diff --git a/DEPS b/DEPS index 1d84e7b..7742ae635 100644 --- a/DEPS +++ b/DEPS
@@ -195,11 +195,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': 'd7b09c4c3acf69a3fea49f5baaa8b5bed954a6fc', + 'skia_revision': '652124c372e528937645533147c7da8ec8ac4e08', # 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': '75a11031417f6373146adf109048a99f67f82956', + 'v8_revision': '9e3426ebd5780d3e984c142cc521f2c33b6e32f2', # 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. @@ -207,15 +207,15 @@ # 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': '5276639d27894f3f35c43af5f038bf84e3aafe9f', + 'angle_revision': 'cc958e0e87034f591ea2a76d2809b13dad186c93', # 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': 'b65408064b1fd0f6d6f7ef1e4da7445c67ae166f', + 'swiftshader_revision': 'cda86eff64617e9b48167f1aa6a31bcdb823c10b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '61ca10cb63d06a31daaba9d453ccc7f837802c24', + 'pdfium_revision': '7369107c781969a1d77ae88e00052062a91f04c5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -258,7 +258,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '9f3ce85bab94e6c5f89c7615e0cc1bdcbe5c95e5', + 'catapult_revision': 'af63c44964adbcb5c46c65bf7272addd06e8478e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -266,7 +266,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': '51d97b104f7998cfec009f4de3376f613a4b1e4b', + 'devtools_frontend_revision': '86c9a7134948a3e2f0c82edbf1cab340ed6e2c20', # 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. @@ -318,11 +318,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. - 'dawn_revision': '1aff02d444786a451f72a9b3bb5d064f0b26e0f4', + 'dawn_revision': '4a486be696b44151bbda5e837a784560b2d9154f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': '07b2e8df6cc8aeda04e989102f4c97a11297ffb2', + 'quiche_revision': '3f2c3d7f4b2a6db93e7c78d9020bcfcb3c7ea72b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -357,7 +357,7 @@ 'ukey2_revision': '0275885d8e6038c39b8a8ca55e75d1d4d1727f47', # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'tint_revision': 'bc80805c4b04d0e8cd9dad12bef32927363b9787', + 'tint_revision': '5e7ef27ca7b1ddedd9a9553bc873e4034cd0c735', # TODO(crbug.com/941824): The values below need to be kept in sync # between //DEPS and //buildtools/DEPS, so if you're updating one, @@ -545,7 +545,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'db5c2d7e4d04d3d2b49d81b3895df36f455a77f5', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'c48cd65ade15bc29ab2329ed9e8032e1f5f01a2c', 'condition': 'checkout_ios', }, @@ -895,7 +895,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0e99b9be0afe1cf0aa824cf7fd919bbef66ba5d8', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '409802afddc89795132b49743c2660f18f91b8df', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -946,7 +946,7 @@ Var('chromium_git') + '/codecs/libgav1.git' + '@' + 'e46493b9148e0d1e63f55b5890bff503822616e5', 'src/third_party/glslang/src': - Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'b60e067b43744ce88adea33ab347ac9997b923d8', + Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + 'd253278f986574cb8e80ec9a4e84094ec1b25349', 'src/third_party/google_toolbox_for_mac/src': { 'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'), @@ -1248,7 +1248,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'dfa133b7b48c5ef14f5040d3a735e5d350de06bd', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'dbee93ac203d9269fe93c1ff1e48eba6148e542c', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1326,7 +1326,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': 'ZEo24H1CQXzgoFSxz3B6HiIwjFXWLShZsaOpIkfVnE4C' + 'version': 'EiEDrfCNj1Zs02bIIJ6EbbubcxNig2cBj_I58ylH0P4C' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1401,7 +1401,7 @@ Var('swiftshader_git') + '/SwiftShader.git' + '@' + Var('swiftshader_revision'), 'src/third_party/text-fragments-polyfill/src': { - 'url': Var('chromium_git') + '/external/github.com/GoogleChromeLabs/text-fragments-polyfill.git' + '@' + 'f12d4cb5c2fe4d106d8310603c8481a732daaa40', + 'url': Var('chromium_git') + '/external/github.com/GoogleChromeLabs/text-fragments-polyfill.git' + '@' + '5593fc403e4d1ee06a68ff710932d59c06a87df9', 'condition': 'checkout_ios', }, @@ -1470,7 +1470,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '67615460bea48f58bdfeea04692bc7c93b8d5cbf', + Var('webrtc_git') + '/src.git' + '@' + '383f2cfca4a1ebd9626134101fe70d5a716b2d92', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1542,7 +1542,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@f7f46a7432a97842a94d75b0f9c2d677161dfc7c', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@00fcb720bc393474247797666b48288df9240b2e', 'condition': 'checkout_src_internal', }, @@ -1550,7 +1550,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'qm8oRNi8gU7naD1qdw0-8dq2k2YWuPswsrYsoz6u_n8C', + 'version': 'yzqZBKPmH-7JzPqoGRyX5xzi_i8ljeOuLly8tsBta8YC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1561,7 +1561,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'UZ0LaGP4pONeWSmuhGzTHaNGXAnBjLFccXtfgum0L4QC', + 'version': 'C4uGPvOKetOg4cH-ijCNNQo9zb0CSgH-DLV-l8618cYC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 9c362d46..ad058a2 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -570,7 +570,7 @@ "//net/android:net_java", "//services/network/public/mojom:mojom_java", "//third_party/android_deps:androidx_annotation_annotation_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/blink/public:blink_headers_java", "//ui/android:ui_java", "//url:gurl_java", @@ -597,7 +597,7 @@ "//base:base_java", "//components/variations/android:variations_java", "//third_party/android_deps:androidx_annotation_annotation_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", ] }
diff --git a/android_webview/browser/aw_print_manager.cc b/android_webview/browser/aw_print_manager.cc index 557f556..d7825691 100644 --- a/android_webview/browser/aw_print_manager.cc +++ b/android_webview/browser/aw_print_manager.cc
@@ -105,12 +105,12 @@ void AwPrintManager::OnDidPrintDocument( content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPrintDocument_Params& params, + const printing::mojom::DidPrintDocumentParams& params, std::unique_ptr<DelayedFrameDispatchHelper> helper) { if (params.document_cookie != cookie_) return; - const printing::mojom::DidPrintContentParams& content = params.content; + const printing::mojom::DidPrintContentParams& content = *params.content; if (!content.metafile_data_region.IsValid()) { NOTREACHED() << "invalid memory handle"; web_contents()->Stop();
diff --git a/android_webview/browser/aw_print_manager.h b/android_webview/browser/aw_print_manager.h index 85e974bf..597affc 100644 --- a/android_webview/browser/aw_print_manager.h +++ b/android_webview/browser/aw_print_manager.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "components/printing/browser/print_manager.h" +#include "components/printing/common/print.mojom-forward.h" #include "components/printing/common/print_messages.h" #include "content/public/browser/web_contents_user_data.h" #include "printing/print_settings.h" @@ -45,7 +46,7 @@ // printing::PrintManager: void OnDidPrintDocument( content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPrintDocument_Params& params, + const printing::mojom::DidPrintDocumentParams& params, std::unique_ptr<DelayedFrameDispatchHelper> helper) override; void OnGetDefaultPrintSettings(content::RenderFrameHost* render_frame_host, IPC::Message* reply_msg) override;
diff --git a/android_webview/nonembedded/BUILD.gn b/android_webview/nonembedded/BUILD.gn index 84574660..ee350a7 100644 --- a/android_webview/nonembedded/BUILD.gn +++ b/android_webview/nonembedded/BUILD.gn
@@ -32,7 +32,7 @@ "//components/embedder_support/android:application_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:com_google_code_findbugs_jsr305_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//ui/android:ui_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] @@ -103,7 +103,7 @@ "//components/version_info/android:version_constants_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:com_google_code_findbugs_jsr305_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", ] }
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn index c5b2b18..53108dd 100644 --- a/android_webview/test/BUILD.gn +++ b/android_webview/test/BUILD.gn
@@ -206,8 +206,8 @@ "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_deps:com_google_code_findbugs_jsr305_java", "//third_party/android_deps:com_google_guava_failureaccess_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/android_deps:espresso_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", "//third_party/blink/public/mojom:web_feature_mojo_bindings_java", @@ -515,7 +515,7 @@ "//base:base_junit_test_support", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:androidx_test_runner_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/android_support_test_runner:runner_java", ]
diff --git a/ash/ambient/model/ambient_backend_model.cc b/ash/ambient/model/ambient_backend_model.cc index ec276aa89..c9f7374 100644 --- a/ash/ambient/model/ambient_backend_model.cc +++ b/ash/ambient/model/ambient_backend_model.cc
@@ -92,7 +92,7 @@ next_image_.Clear(); } -PhotoWithDetails AmbientBackendModel::GetNextImage() const { +const PhotoWithDetails& AmbientBackendModel::GetNextImage() const { if (!next_image_.IsNull()) return next_image_;
diff --git a/ash/ambient/model/ambient_backend_model.h b/ash/ambient/model/ambient_backend_model.h index 32a202999..7d295f8f 100644 --- a/ash/ambient/model/ambient_backend_model.h +++ b/ash/ambient/model/ambient_backend_model.h
@@ -67,7 +67,7 @@ void Clear(); // Get images from local storage. Could be null image. - PhotoWithDetails GetNextImage() const; + const PhotoWithDetails& GetNextImage() const; // Updates the weather information and notifies observers if the icon image is // not null.
diff --git a/ash/ambient/ui/ambient_background_image_view.cc b/ash/ambient/ui/ambient_background_image_view.cc index d954b92..a319e20 100644 --- a/ash/ambient/ui/ambient_background_image_view.cc +++ b/ash/ambient/ui/ambient_background_image_view.cc
@@ -4,18 +4,39 @@ #include "ash/ambient/ui/ambient_background_image_view.h" +#include <memory> + +#include "ash/ambient/util/ambient_util.h" #include "ash/assistant/ui/assistant_view_ids.h" #include "ui/events/event.h" +#include "ui/gfx/geometry/insets.h" #include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/layout/fill_layout.h" #include "ui/views/metadata/metadata_impl_macros.h" namespace ash { +namespace { + +// Appearance. +constexpr int kHorizontalMarginDip = 16; +constexpr int kVerticalMarginDip = 43; + +// Typography. +constexpr SkColor kTextColor = SK_ColorWHITE; +constexpr int kDefaultFontSizeDip = 64; +constexpr int kDetailsFontSizeDip = 13; + +} // namespace + AmbientBackgroundImageView::AmbientBackgroundImageView( AmbientViewDelegate* delegate) : delegate_(delegate) { DCHECK(delegate_); SetID(AssistantViewID::kAmbientBackgroundImageView); + InitLayout(); } AmbientBackgroundImageView::~AmbientBackgroundImageView() = default; @@ -34,6 +55,52 @@ } } +void AmbientBackgroundImageView::UpdateImage(const gfx::ImageSkia& img) { + image_view_->SetImage(img); +} + +void AmbientBackgroundImageView::UpdateImageDetails( + const base::string16& details) { + details_label_->SetText(details); +} + +const gfx::ImageSkia& AmbientBackgroundImageView::GetCurrentImage() { + return image_view_->GetImage(); +} + +gfx::Rect AmbientBackgroundImageView::GetCurrentImageBoundsForTesting() const { + return image_view_->GetImageBounds(); +} + +void AmbientBackgroundImageView::InitLayout() { + SetLayoutManager(std::make_unique<views::FillLayout>()); + + // Inits the image view. This view should have the same size of the screen. + image_view_ = AddChildView(std::make_unique<views::ImageView>()); + + // Inits the attribution view. It also has a full-screen size and is + // responsible for layout the details label at its bottom left corner. + views::View* attribution_view = AddChildView(std::make_unique<views::View>()); + views::BoxLayout* attribution_layout = + attribution_view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); + attribution_layout->set_main_axis_alignment( + views::BoxLayout::MainAxisAlignment::kStart); + attribution_layout->set_inside_border_insets( + gfx::Insets(0, kHorizontalMarginDip, kVerticalMarginDip, 0)); + + // Inits the details label. + details_label_ = + attribution_view->AddChildView(std::make_unique<views::Label>()); + details_label_->SetAutoColorReadabilityEnabled(false); + details_label_->SetEnabledColor(kTextColor); + details_label_->SetFontList( + ambient::util::GetDefaultFontlist().DeriveWithSizeDelta( + kDetailsFontSizeDip - kDefaultFontSizeDip)); + details_label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); + details_label_->SetVerticalAlignment(gfx::VerticalAlignment::ALIGN_BOTTOM); +} + BEGIN_METADATA(AmbientBackgroundImageView) METADATA_PARENT_CLASS(views::ImageView) END_METADATA()
diff --git a/ash/ambient/ui/ambient_background_image_view.h b/ash/ambient/ui/ambient_background_image_view.h index 6b7cfc9..7607694 100644 --- a/ash/ambient/ui/ambient_background_image_view.h +++ b/ash/ambient/ui/ambient_background_image_view.h
@@ -5,18 +5,25 @@ #ifndef ASH_AMBIENT_UI_AMBIENT_BACKGROUND_IMAGE_VIEW_H_ #define ASH_AMBIENT_UI_AMBIENT_BACKGROUND_IMAGE_VIEW_H_ +#include <string> + #include "ash/ambient/ui/ambient_view_delegate.h" #include "ash/ash_export.h" #include "ui/views/controls/image_view.h" #include "ui/views/metadata/metadata_header_macros.h" #include "ui/views/view.h" +namespace views { +class Label; +} // namespace views + namespace ash { // AmbientBackgroundImageView-------------------------------------------------- -// A custom ImageView for ambient mode to handle specific mouse/gesture events -// when the user interacts with the background photos. -class ASH_EXPORT AmbientBackgroundImageView : public views::ImageView { +// A custom ImageView to display photo image and details information on ambient. +// It also handles specific mouse/gesture events to dismiss ambient when user +// interacts with the background photos. +class ASH_EXPORT AmbientBackgroundImageView : public views::View { public: METADATA_HEADER(AmbientBackgroundImageView); @@ -29,9 +36,28 @@ bool OnMousePressed(const ui::MouseEvent& event) override; void OnGestureEvent(ui::GestureEvent* event) override; + // Updates the display image. + void UpdateImage(const gfx::ImageSkia& img); + + // Updates the details for the currently displayed image. + void UpdateImageDetails(const base::string16& details); + + const gfx::ImageSkia& GetCurrentImage(); + + gfx::Rect GetCurrentImageBoundsForTesting() const; + private: + void InitLayout(); + // Owned by |AmbientController| and should always outlive |this|. AmbientViewDelegate* delegate_ = nullptr; + + // View to display the current image on ambient. Owned by the view hierarchy. + views::ImageView* image_view_ = nullptr; + + // Label to show details text, i.e. attribution, to be displayed for the + // current image. Owned by the view hierarchy. + views::Label* details_label_ = nullptr; }; } // namespace ash
diff --git a/ash/ambient/ui/photo_view.cc b/ash/ambient/ui/photo_view.cc index 5fedc931..95e23cae7 100644 --- a/ash/ambient/ui/photo_view.cc +++ b/ash/ambient/ui/photo_view.cc
@@ -5,6 +5,7 @@ #include "ash/ambient/ui/photo_view.h" #include <algorithm> +#include <iterator> #include <memory> #include "ash/ambient/ambient_constants.h" @@ -14,6 +15,7 @@ #include "ash/assistant/ui/assistant_view_ids.h" #include "ash/public/cpp/metrics_util.h" #include "base/metrics/histogram_functions.h" +#include "base/strings/utf_string_conversions.h" #include "ui/aura/window.h" #include "ui/compositor/animation_metrics_reporter.h" #include "ui/compositor/animation_throughput_reporter.h" @@ -82,7 +84,7 @@ for (const int index : {0, 1}) { auto image = images_unscaled_[index]; auto image_resized = ResizeImage(image, size()); - image_views_[index]->SetImage(image_resized); + image_views_[index]->UpdateImage(image_resized); } } @@ -103,14 +105,16 @@ layer()->SetFillsBoundsOpaquely(false); SetLayoutManager(std::make_unique<views::FillLayout>()); - image_views_[0] = - AddChildView(std::make_unique<AmbientBackgroundImageView>(delegate_)); - image_views_[1] = - AddChildView(std::make_unique<AmbientBackgroundImageView>(delegate_)); - image_views_[0]->SetPaintToLayer(); - image_views_[0]->layer()->SetFillsBoundsOpaquely(false); - image_views_[1]->SetPaintToLayer(); - image_views_[1]->layer()->SetFillsBoundsOpaquely(false); + for (auto*& image_view : image_views_) { + // Creates image views. + image_view = + AddChildView(std::make_unique<AmbientBackgroundImageView>(delegate_)); + // Each image view will be animated on its own layer. + image_view->SetPaintToLayer(); + image_view->layer()->SetFillsBoundsOpaquely(false); + } + + // Hides one image view initially for fade in animation. image_views_[1]->layer()->SetOpacity(0.0f); delegate_->GetAmbientBackendModel()->AddObserver(this); @@ -118,12 +122,15 @@ void PhotoView::UpdateImages() { auto* model = delegate_->GetAmbientBackendModel(); - images_unscaled_[image_index_] = model->GetNextImage().photo; + auto& next_image = model->GetNextImage(); + images_unscaled_[image_index_] = next_image.photo; if (images_unscaled_[image_index_].isNull()) return; auto next_resized = ResizeImage(images_unscaled_[image_index_], size()); - image_views_[image_index_]->SetImage(next_resized); + image_views_[image_index_]->UpdateImage(next_resized); + image_views_[image_index_]->UpdateImageDetails( + base::UTF8ToUTF16(next_image.details)); image_index_ = 1 - image_index_; } @@ -175,7 +182,7 @@ } const gfx::ImageSkia& PhotoView::GetCurrentImagesForTesting() { - return image_views_[image_index_]->GetImage(); + return image_views_[image_index_]->GetCurrentImage(); } } // namespace ash
diff --git a/ash/ambient/ui/photo_view_unittest.cc b/ash/ambient/ui/photo_view_unittest.cc index fbd96a8..c1dd844 100644 --- a/ash/ambient/ui/photo_view_unittest.cc +++ b/ash/ambient/ui/photo_view_unittest.cc
@@ -32,7 +32,7 @@ // Image should be full width. Image height should extend above and below the // visible part of the screen. - ASSERT_EQ(image_view->GetImageBounds(), + ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(), gfx::Rect(/*x=*/0, /*y=*/-200, /*width=*/600, /*height=*/1200)); } @@ -52,7 +52,7 @@ // Image should be full width. Image should have equal empty space top and // bottom. - ASSERT_EQ(image_view->GetImageBounds(), + ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(), gfx::Rect(/*x=*/0, /*y=*/200, /*width=*/600, /*height=*/400)); } @@ -72,7 +72,7 @@ // Image should be full height. Image width should have equal empty space on // left and right. - ASSERT_EQ(image_view->GetImageBounds(), + ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(), gfx::Rect(/*x=*/250, /*y=*/0, /*width=*/300, /*height=*/600)); } @@ -93,7 +93,7 @@ // Image should be full height. Image width should extend equally to the left // and right of the visible part of the screen. - ASSERT_EQ(image_view->GetImageBounds(), + ASSERT_EQ(image_view->GetCurrentImageBoundsForTesting(), gfx::Rect(/*x=*/-50, /*y=*/0, /*width=*/900, /*height=*/600)); }
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index a298e09..3c523ddb 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -564,6 +564,9 @@ view_delegate_->LogSearchAbandonHistogram(); + contents_view_->search_results_page_view() + ->result_selection_controller() + ->ClearSelection(); ClearSearch(); SetSearchBoxActive(false, ui::ET_UNKNOWN); }
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc index e79043d..68a975d 100644 --- a/ash/app_list/views/search_box_view_unittest.cc +++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -569,6 +569,59 @@ EXPECT_EQ(base::ASCIIToUTF16("test"), selection->result()->title()); } +// Tests that the default selection is reset after resetting and reactivating +// the search box. +TEST_F(SearchBoxViewTest, ResetSelectionAfterResettingSearchBox) { + SetSearchBoxActive(true, ui::ET_UNKNOWN); + CreateSearchResult(ash::SearchResultDisplayType::kList, 0.7, + base::ASCIIToUTF16("test1"), base::string16()); + CreateSearchResult(ash::SearchResultDisplayType::kList, 0.5, + base::ASCIIToUTF16("test2"), base::string16()); + base::RunLoop().RunUntilIdle(); + + SearchResultPageView* const result_page_view = + view()->contents_view()->search_results_page_view(); + + // Selection should rest on the first result, which is default. + const SearchResultBaseView* selection = + result_page_view->result_selection_controller()->selected_result(); + EXPECT_EQ(result_page_view->first_result_view(), selection); + ASSERT_TRUE(selection->result()); + EXPECT_EQ(base::ASCIIToUTF16("test1"), selection->result()->title()); + EXPECT_TRUE(selection->is_default_result()); + + // Navigate down then up. The first result should no longer be default. + KeyPress(ui::VKEY_DOWN); + KeyPress(ui::VKEY_UP); + + selection = + result_page_view->result_selection_controller()->selected_result(); + ASSERT_TRUE(selection->result()); + EXPECT_EQ(base::ASCIIToUTF16("test1"), selection->result()->title()); + EXPECT_FALSE(selection->is_default_result()); + + // Navigate down to the second result. + KeyPress(ui::VKEY_DOWN); + + selection = + result_page_view->result_selection_controller()->selected_result(); + ASSERT_TRUE(selection->result()); + EXPECT_EQ(base::ASCIIToUTF16("test2"), selection->result()->title()); + + // Reset the search box. + view()->ClearSearchAndDeactivateSearchBox(); + SetSearchBoxActive(true, ui::ET_UNKNOWN); + result_page_view->OnSearchResultContainerResultsChanged(); + + // Selection should again rest on the first result, which is default. + selection = + result_page_view->result_selection_controller()->selected_result(); + EXPECT_EQ(result_page_view->first_result_view(), selection); + ASSERT_TRUE(selection->result()); + EXPECT_EQ(base::ASCIIToUTF16("test1"), selection->result()->title()); + EXPECT_TRUE(selection->is_default_result()); +} + TEST_F(SearchBoxViewTest, NewSearchQueryActionRecordedWhenUserType) { base::UserActionTester user_action_tester; // User starts to type a character in search box. @@ -772,7 +825,7 @@ // titles. TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesTopListResultTitle) { - // Add two SearchResults, one with higher ranking. Initialize their title + // Add two SearchResults, one tile and one list result. Initialize their title // field to a non-empty string. CreateSearchResult(ash::SearchResultDisplayType::kList, 1.0, base::ASCIIToUTF16("hello list"), base::string16()); @@ -785,16 +838,16 @@ KeyPress(ui::VKEY_E); view()->ProcessAutocomplete(); - EXPECT_EQ(view()->search_box()->GetText(), base::ASCIIToUTF16("hello list")); + EXPECT_EQ(view()->search_box()->GetText(), base::ASCIIToUTF16("hello tile")); EXPECT_EQ(view()->search_box()->GetSelectedText(), - base::ASCIIToUTF16("llo list")); + base::ASCIIToUTF16("llo tile")); } // Tests that autocomplete suggestions are consistent with top SearchResult tile // titles. TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesTopTileResultTitle) { - // Add two SearchResults, one with higher ranking. Initialize their title + // Add two SearchResults, one tile and one list result. Initialize their title // field to a non-empty string. CreateSearchResult(ash::SearchResultDisplayType::kTile, 1.0, base::ASCIIToUTF16("hello tile"), base::string16()); @@ -815,8 +868,9 @@ // details. TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesTopListResultDetails) { - // Add two SearchResults, one with higher ranking. Initialize their details - // field to a non-empty string. + // Add two SearchResults, one tile and one list result. The tile should + // display first, despite having a lower score. Initialize their details field + // to a non-empty string. CreateSearchResult(ash::SearchResultDisplayType::kList, 1.0, base::string16(), base::ASCIIToUTF16("hello list")); CreateSearchResult(ash::SearchResultDisplayType::kTile, 0.5, base::string16(), @@ -827,17 +881,17 @@ KeyPress(ui::VKEY_H); KeyPress(ui::VKEY_E); view()->ProcessAutocomplete(); - EXPECT_EQ(view()->search_box()->GetText(), base::ASCIIToUTF16("hello list")); + EXPECT_EQ(view()->search_box()->GetText(), base::ASCIIToUTF16("hello tile")); EXPECT_EQ(view()->search_box()->GetSelectedText(), - base::ASCIIToUTF16("llo list")); + base::ASCIIToUTF16("llo tile")); } // Tests that autocomplete suggestions are consistent with top SearchResult tile // details. TEST_F(SearchBoxViewAutocompleteTest, SearchBoxAutocompletesTopTileResultDetails) { - // Add two SearchResults, one with higher ranking. Initialize their details - // field to a non-empty string. + // Add two SearchResults, one tile and one list result. Initialize their + // details field to a non-empty string. CreateSearchResult(ash::SearchResultDisplayType::kTile, 1.0, base::string16(), base::ASCIIToUTF16("hello tile")); CreateSearchResult(ash::SearchResultDisplayType::kList, 0.5, base::string16(),
diff --git a/ash/app_list/views/search_result_answer_card_view.cc b/ash/app_list/views/search_result_answer_card_view.cc index 9d9f7621..a2750a5 100644 --- a/ash/app_list/views/search_result_answer_card_view.cc +++ b/ash/app_list/views/search_result_answer_card_view.cc
@@ -5,6 +5,7 @@ #include "ash/app_list/views/search_result_answer_card_view.h" #include <memory> +#include <string> #include <utility> #include <vector> @@ -12,6 +13,7 @@ #include "ash/app_list/app_list_view_delegate.h" #include "ash/app_list/views/app_list_view.h" #include "ash/app_list/views/search_result_base_view.h" +#include "ash/public/cpp/app_list/app_list_config.h" #include "base/bind.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" @@ -351,7 +353,9 @@ parent()->SetVisible(has_valid_answer_card); set_container_score( - has_valid_answer_card && top_result ? top_result->display_score() : -1); + has_valid_answer_card && top_result + ? AppListConfig::instance().answer_card_container_score() + : -1.0); if (top_result) top_result->set_is_visible(has_valid_answer_card);
diff --git a/ash/app_list/views/search_result_answer_card_view_unittest.cc b/ash/app_list/views/search_result_answer_card_view_unittest.cc index 1503cc2..8a2dbc8b 100644 --- a/ash/app_list/views/search_result_answer_card_view_unittest.cc +++ b/ash/app_list/views/search_result_answer_card_view_unittest.cc
@@ -22,7 +22,7 @@ namespace { constexpr char kResultTitle[] = "The weather is fine"; -constexpr double kDisplayScore = 13.0; +constexpr double kDisplayScore = 2.0; } // namespace class SearchResultAnswerCardViewTest : public views::ViewsTestBase {
diff --git a/ash/app_list/views/search_result_list_view.cc b/ash/app_list/views/search_result_list_view.cc index f13de29..0d4ce14 100644 --- a/ash/app_list/views/search_result_list_view.cc +++ b/ash/app_list/views/search_result_list_view.cc
@@ -284,7 +284,9 @@ previous_found_drive_quick_access_ = found_drive_quick_access; set_container_score( - display_results.empty() ? -1 : display_results.front()->display_score()); + display_results.empty() + ? -1.0 + : AppListConfig::instance().results_list_container_score()); return display_results.size(); }
diff --git a/ash/app_list/views/search_result_page_view_unittest.cc b/ash/app_list/views/search_result_page_view_unittest.cc index 9cee7e9..525d5ff 100644 --- a/ash/app_list/views/search_result_page_view_unittest.cc +++ b/ash/app_list/views/search_result_page_view_unittest.cc
@@ -153,17 +153,15 @@ EXPECT_EQ(tile_list_view(), view()->result_container_views()[0]); EXPECT_EQ(list_view(), view()->result_container_views()[1]); - // Change the relevance of the tile result and expect the list results to be - // displayed first. - // TODO(warx): fullscreen launcher should always have tile list view to be - // displayed first over list view. + // Change the relevance of the tile result to be lower than list results. The + // tile container should still be displayed first. tile_result->set_display_score(0.4); results->NotifyItemsChanged(0, 1); RunPendingMessages(); - EXPECT_EQ(list_view(), view()->result_container_views()[0]); - EXPECT_EQ(tile_list_view(), view()->result_container_views()[1]); + EXPECT_EQ(tile_list_view(), view()->result_container_views()[0]); + EXPECT_EQ(list_view(), view()->result_container_views()[1]); } TEST_P(SearchResultPageViewTest, TileResultsSortedBeforeEmptyListResults) {
diff --git a/ash/app_list/views/search_result_tile_item_list_view.cc b/ash/app_list/views/search_result_tile_item_list_view.cc index 946381c..c1182d1 100644 --- a/ash/app_list/views/search_result_tile_item_list_view.cc +++ b/ash/app_list/views/search_result_tile_item_list_view.cc
@@ -253,7 +253,9 @@ } set_container_score( - display_results.empty() ? -1 : display_results.front()->display_score()); + display_results.empty() + ? -1.0 + : AppListConfig::instance().app_tiles_container_score()); return display_results.size(); }
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 0422608..2e767f5 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -1456,6 +1456,9 @@ <message name="IDS_ASH_STATUS_TRAY_DISPLAY_REMOVED" desc="The text of the notification to show when a display is disconnected from the device."> Removed display <ph name="DISPLAY_NAME">$1</ph> </message> + <message name="IDS_ASH_STATUS_TRAY_DISPLAY_ADDED" desc="The text of the notification to show that a display is connected to the device."> + <ph name="DISPLAY_NAME">$1</ph> connected + </message> <message name="IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING_NO_INTERNAL" desc="The label used in the tray to show that the current status is mirroring and the device doesn't have the internal display."> Mirroring </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_DISPLAY_ADDED.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_DISPLAY_ADDED.png.sha1 new file mode 100644 index 0000000..21d851357 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_DISPLAY_ADDED.png.sha1
@@ -0,0 +1 @@ +e601523381ac478f8b11e5da2a8e5617ad1b658e \ No newline at end of file
diff --git a/ash/public/cpp/app_list/app_list_config.h b/ash/public/cpp/app_list/app_list_config.h index fe9a8dc..277f2e8 100644 --- a/ash/public/cpp/app_list/app_list_config.h +++ b/ash/public/cpp/app_list/app_list_config.h
@@ -176,6 +176,16 @@ return max_search_result_list_items_; } + double app_tiles_container_score() const { + return app_tiles_container_score_; + } + double results_list_container_score() const { + return results_list_container_score_; + } + double answer_card_container_score() const { + return answer_card_container_score_; + } + gfx::Size grid_icon_size() const { return gfx::Size(grid_icon_dimension_, grid_icon_dimension_); } @@ -462,6 +472,12 @@ // Max number of search result list items in the launcher suggestion window. const size_t max_search_result_list_items_ = 5; + // Scores for the three containers within the search box view. These are + // displayed in high-to-low order. + const double app_tiles_container_score_ = 3.0; + const double answer_card_container_score_ = 2.0; + const double results_list_container_score_ = 1.0; + // Cardified app list background properties const SkColor cardified_background_color_; const SkColor cardified_background_color_active_;
diff --git a/ash/shelf/shelf_app_button.cc b/ash/shelf/shelf_app_button.cc index fc8e84be..dc1039b 100644 --- a/ash/shelf/shelf_app_button.cc +++ b/ash/shelf/shelf_app_button.cc
@@ -48,7 +48,10 @@ constexpr int kStatusIndicatorActiveSize = 8; constexpr int kStatusIndicatorRunningSize = 4; constexpr int kStatusIndicatorThickness = 2; -constexpr int kNotificationIndicatorRadiusDip = 7; + +constexpr int kNotificationIndicatorRadiusDip = 6; +constexpr int kNotificationIndicatorPadding = 1; + constexpr SkColor kDefaultIndicatorColor = SK_ColorWHITE; // Slightly different colors and alpha in the new UI. @@ -743,10 +746,12 @@ // The indicators should be aligned with the icon, not the icon + shadow. gfx::Point indicator_midpoint = icon_view_bounds.CenterPoint(); if (is_notification_indicator_enabled_) { - notification_indicator_->SetBoundsRect( - gfx::Rect(icon_view_bounds.right() - kNotificationIndicatorRadiusDip, - icon_view_bounds.y(), kNotificationIndicatorRadiusDip * 2, - kNotificationIndicatorRadiusDip * 2)); + notification_indicator_->SetBoundsRect(gfx::Rect( + icon_view_bounds.right() - 2 * kNotificationIndicatorRadiusDip - + kNotificationIndicatorPadding, + icon_view_bounds.y() + kNotificationIndicatorPadding, + kNotificationIndicatorRadiusDip * 2, + kNotificationIndicatorRadiusDip * 2)); } switch (shelf->alignment()) {
diff --git a/ash/style/ash_color_provider.cc b/ash/style/ash_color_provider.cc index 6d2bb13..00659488 100644 --- a/ash/style/ash_color_provider.cc +++ b/ash/style/ash_color_provider.cc
@@ -321,16 +321,15 @@ return cros_colors::ResolveColor(ColorName::kTextColorSecondary, color_mode); case ContentLayerType::kTextColorAlert: - light_color = gfx::kGoogleRed600; - dark_color = gfx::kGoogleRed300; + return cros_colors::ResolveColor(ColorName::kTextColorAlert, color_mode); break; case ContentLayerType::kTextColorWarning: - light_color = gfx::kGoogleYellow600; - dark_color = gfx::kGoogleYellow300; + return cros_colors::ResolveColor(ColorName::kTextColorWarning, + color_mode); break; case ContentLayerType::kTextColorPositive: - light_color = gfx::kGoogleGreen600; - dark_color = gfx::kGoogleGreen300; + return cros_colors::ResolveColor(ColorName::kTextColorPositive, + color_mode); break; case ContentLayerType::kIconColorPrimary: return cros_colors::ResolveColor(ColorName::kIconColorPrimary, @@ -339,16 +338,15 @@ light_color = dark_color = gfx::kGoogleGrey500; break; case ContentLayerType::kIconColorAlert: - light_color = gfx::kGoogleRed600; - dark_color = gfx::kGoogleRed300; + return cros_colors::ResolveColor(ColorName::kIconColorAlert, color_mode); break; case ContentLayerType::kIconColorWarning: - light_color = gfx::kGoogleYellow600; - dark_color = gfx::kGoogleYellow300; + return cros_colors::ResolveColor(ColorName::kIconColorWarning, + color_mode); break; case ContentLayerType::kIconColorPositive: - light_color = gfx::kGoogleGreen600; - dark_color = gfx::kGoogleGreen300; + return cros_colors::ResolveColor(ColorName::kIconColorPositive, + color_mode); break; case ContentLayerType::kIconColorProminent: case ContentLayerType::kSliderThumbColorEnabled:
diff --git a/ash/system/screen_layout_observer.cc b/ash/system/screen_layout_observer.cc index c6e3c1b..5ad02ed 100644 --- a/ash/system/screen_layout_observer.cc +++ b/ash/system/screen_layout_observer.cc
@@ -85,7 +85,7 @@ UMA_STATUS_AREA_DISPLAY_NOTIFICATION_SHOW_SETTINGS); } message_center::MessageCenter::Get()->RemoveNotification( - ScreenLayoutObserver::kNotificationId, true /* by_user */); + ScreenLayoutObserver::kNotificationId, /*by_user=*/true); } // Returns the name of the currently connected external display whose ID is @@ -180,6 +180,12 @@ base::string16 GetDisplayAddedMessage(int64_t added_display_id, base::string16* additional_message_out) { + if (features::IsReduceDisplayNotificationsEnabled()) { + DCHECK(!display::Display::IsInternalDisplayId(added_display_id)); + return l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_ADDED, + GetExternalDisplayName(added_display_id)); + } + if (!display::Display::HasInternalDisplay()) { return l10n_util::GetStringUTF16( IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL); @@ -195,12 +201,12 @@ "chrome://settings/display"; ScreenLayoutObserver::ScreenLayoutObserver() { - Shell::Get()->display_manager()->AddObserver(this); + Shell::Get()->window_tree_host_manager()->AddObserver(this); UpdateDisplayInfo(nullptr); } ScreenLayoutObserver::~ScreenLayoutObserver() { - Shell::Get()->display_manager()->RemoveObserver(this); + Shell::Get()->window_tree_host_manager()->RemoveObserver(this); } void ScreenLayoutObserver::SetDisplayChangedFromSettingsUI(int64_t display_id) { @@ -283,6 +289,12 @@ if (old_info.count(iter.first)) continue; + // No notification if the internal display is connected. + if (features::IsReduceDisplayNotificationsEnabled() && + display::Display::IsInternalDisplayId(iter.first)) { + return false; + } + *out_message = GetDisplayAddedMessage(iter.first, out_additional_message); return true; } @@ -374,7 +386,7 @@ // Always remove the notification to make sure the notification appears // as a popup in any situation. message_center::MessageCenter::Get()->RemoveNotification(kNotificationId, - false /* by_user */); + /*by_user=*/false); if (message.empty() && additional_message.empty()) return; @@ -413,22 +425,7 @@ std::move(notification)); } -void ScreenLayoutObserver::OnDisplayAdded(const display::Display& new_display) { - if (!show_notifications_for_testing_) - return; - - // The older way handles showing display added notifications as well. We will - // use that if display notifications are not suppressed. - if (!features::IsReduceDisplayNotificationsEnabled()) - return; - - base::string16 additional_message; - base::string16 message = - GetDisplayAddedMessage(new_display.id(), &additional_message); - CreateOrUpdateNotification(message, additional_message); -} - -void ScreenLayoutObserver::OnDidProcessDisplayChanges() { +void ScreenLayoutObserver::OnDisplayConfigurationChanged() { DisplayInfoMap old_info; UpdateDisplayInfo(&old_info); @@ -467,13 +464,21 @@ base::string16 additional_message; if (!GetDisplayMessageForNotification(old_info, should_notify_has_unassociated_display, - &message, &additional_message)) + &message, &additional_message)) { return; + } + + // Alerting user of display added and unassociated display are allowed even + // when suppressed. + const bool exited_mirror = old_display_mode_ == DisplayMode::MIRRORING && + current_display_mode_ != DisplayMode::MIRRORING; + const bool display_added = + !exited_mirror && old_info.size() < display_info_.size(); + const bool allowed_notifications = + display_added || should_notify_has_unassociated_display; if (features::IsReduceDisplayNotificationsEnabled() && - !should_notify_has_unassociated_display) { - // If display notifications should be suppressed and the notification is not - // to alert the user of an unassociated display, do not show a notification. + !allowed_notifications) { return; }
diff --git a/ash/system/screen_layout_observer.h b/ash/system/screen_layout_observer.h index ecf92de..ec33f7e 100644 --- a/ash/system/screen_layout_observer.h +++ b/ash/system/screen_layout_observer.h
@@ -11,25 +11,24 @@ #include <set> #include "ash/ash_export.h" +#include "ash/display/window_tree_host_manager.h" #include "base/macros.h" #include "base/strings/string16.h" -#include "ui/display/display_observer.h" #include "ui/display/manager/managed_display_info.h" namespace ash { // ScreenLayoutObserver is responsible to send notification to users when screen // resolution changes or screen rotation changes. -class ASH_EXPORT ScreenLayoutObserver : public display::DisplayObserver { +class ASH_EXPORT ScreenLayoutObserver : public WindowTreeHostManager::Observer { public: ScreenLayoutObserver(); ~ScreenLayoutObserver() override; static const char kNotificationId[]; - // display::DisplayObserver: - void OnDisplayAdded(const display::Display& new_display) override; - void OnDidProcessDisplayChanges() override; + // WindowTreeHostManager::Observer: + void OnDisplayConfigurationChanged() override; // No notification will be shown only for the next ui scale change for the // display with |display_id|. This state will be consumed and subsequent
diff --git a/ash/system/screen_layout_observer_unittest.cc b/ash/system/screen_layout_observer_unittest.cc index 1e9ea6c..861a851 100644 --- a/ash/system/screen_layout_observer_unittest.cc +++ b/ash/system/screen_layout_observer_unittest.cc
@@ -353,11 +353,8 @@ base::RunLoop().RunUntilIdle(); // Exit mirror mode manually. Now display mode should be extending mode. - // Exiting mirror mode counts as adding a display, which will show a - // notification. display_manager()->SetMirrorMode(display::MirrorMode::kOff, base::nullopt); - EXPECT_TRUE(IsNotificationShown()); - CloseNotification(); + EXPECT_FALSE(IsNotificationShown()); // Simulate that device can support at most two displays and user connects // it with three displays. Because device is in tablet mode, display mode @@ -425,10 +422,10 @@ IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL), GetDisplayNotificationText()); - // OnDidProcessDisplayChanges() may be called more than once for a single + // OnDisplayConfigurationChanged() may be called more than once for a single // update display in case of primary is swapped or recovered from dock mode. // Should not remove the notification in such case. - GetScreenLayoutObserver()->OnDidProcessDisplayChanges(); + GetScreenLayoutObserver()->OnDisplayConfigurationChanged(); EXPECT_EQ(l10n_util::GetStringUTF16( IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL), GetDisplayNotificationText());
diff --git a/ash/system/unified/unified_system_tray_bubble.cc b/ash/system/unified/unified_system_tray_bubble.cc index df61129..ff8d4c9e 100644 --- a/ash/system/unified/unified_system_tray_bubble.cc +++ b/ash/system/unified/unified_system_tray_bubble.cc
@@ -111,7 +111,6 @@ tray->tray_event_filter()->AddBubble(this); tray->shelf()->AddObserver(this); - Shell::Get()->display_manager()->AddObserver(this); Shell::Get()->tablet_mode_controller()->AddObserver(this); Shell::Get()->activation_client()->AddObserver(this); } @@ -120,14 +119,13 @@ Shell::Get()->activation_client()->RemoveObserver(this); if (Shell::Get()->tablet_mode_controller()) Shell::Get()->tablet_mode_controller()->RemoveObserver(this); - Shell::Get()->display_manager()->RemoveObserver(this); tray_->tray_event_filter()->RemoveBubble(this); tray_->shelf()->RemoveObserver(this); if (bubble_widget_) { bubble_widget_->RemoveObserver(this); bubble_widget_->Close(); } - CHECK(!views::WidgetObserver::IsInObserverList()); + CHECK(!IsInObserverList()); } gfx::Rect UnifiedSystemTrayBubble::GetBoundsInScreen() const { @@ -263,7 +261,7 @@ bubble_view_->StopReroutingEvents(); } -void UnifiedSystemTrayBubble::OnDidProcessDisplayChanges() { +void UnifiedSystemTrayBubble::OnDisplayConfigurationChanged() { UpdateBubbleBounds(); }
diff --git a/ash/system/unified/unified_system_tray_bubble.h b/ash/system/unified/unified_system_tray_bubble.h index 7c129ef..00235c959 100644 --- a/ash/system/unified/unified_system_tray_bubble.h +++ b/ash/system/unified/unified_system_tray_bubble.h
@@ -9,12 +9,12 @@ #include "ash/public/cpp/tablet_mode_observer.h" #include "ash/shelf/shelf_observer.h" +#include "ash/system/screen_layout_observer.h" #include "ash/system/tray/time_to_click_recorder.h" #include "ash/system/tray/tray_bubble_base.h" #include "base/macros.h" #include "base/optional.h" #include "base/time/time.h" -#include "ui/display/display_observer.h" #include "ui/gfx/geometry/insets.h" #include "ui/views/widget/widget_observer.h" #include "ui/wm/public/activation_change_observer.h" @@ -35,7 +35,7 @@ // case, this class calls UnifiedSystemTray::CloseBubble() to delete itself. class ASH_EXPORT UnifiedSystemTrayBubble : public TrayBubbleBase, - public display::DisplayObserver, + public ScreenLayoutObserver, public views::WidgetObserver, public ShelfObserver, public ::wm::ActivationChangeObserver, @@ -104,8 +104,8 @@ TrayBubbleView* GetBubbleView() const override; views::Widget* GetBubbleWidget() const override; - // display::DisplayObserver: - void OnDidProcessDisplayChanges() override; + // ScreenLayoutObserver: + void OnDisplayConfigurationChanged() override; // views::WidgetObserver: void OnWidgetDestroying(views::Widget* widget) override;
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h index 72c66a3..a48bd3f6 100644 --- a/base/mac/sdk_forward_declarations.h +++ b/base/mac/sdk_forward_declarations.h
@@ -67,6 +67,11 @@ #if !defined(MAC_OS_VERSION_11_0) #include <CoreMedia/CoreMedia.h> enum : CMVideoCodecType { kCMVideoCodecType_VP9 = 'vp09' }; + +extern "C" { +void VTRegisterSupplementalVideoDecoderIfAvailable(CMVideoCodecType codecType); +} + #endif // MAC_OS_VERSION_11_0 #endif // BASE_MAC_SDK_FORWARD_DECLARATIONS_H_
diff --git a/base/process/kill.h b/base/process/kill.h index b955870f..9d33283b 100644 --- a/base/process/kill.h +++ b/base/process/kill.h
@@ -84,6 +84,12 @@ int exit_code, const ProcessFilter* filter); +#if defined(OS_POSIX) +// Attempts to kill the process group identified by |process_group_id|. Returns +// true on success. +BASE_EXPORT bool KillProcessGroup(ProcessHandle process_group_id); +#endif // defined(OS_POSIX) + // Get the termination status of the process by interpreting the // circumstances of the child process' death. |exit_code| is set to // the status returned by waitpid() on POSIX, and from GetExitCodeProcess() on
diff --git a/base/process/kill_fuchsia.cc b/base/process/kill_fuchsia.cc index 456033e5..1b7bbd6a 100644 --- a/base/process/kill_fuchsia.cc +++ b/base/process/kill_fuchsia.cc
@@ -13,6 +13,14 @@ namespace base { +bool KillProcessGroup(ProcessHandle process_group_id) { + // |process_group_id| is really a job on Fuchsia. + zx_status_t status = zx_task_kill(process_group_id); + DLOG_IF(ERROR, status != ZX_OK) + << "unable to terminate job " << process_group_id; + return status == ZX_OK; +} + TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) { DCHECK(exit_code);
diff --git a/base/process/kill_posix.cc b/base/process/kill_posix.cc index 0750d9a..86d5096 100644 --- a/base/process/kill_posix.cc +++ b/base/process/kill_posix.cc
@@ -78,6 +78,15 @@ } // namespace +#if !defined(OS_NACL_NONSFI) +bool KillProcessGroup(ProcessHandle process_group_id) { + bool result = kill(-1 * process_group_id, SIGKILL) == 0; + if (!result) + DPLOG(ERROR) << "Unable to terminate process group " << process_group_id; + return result; +} +#endif // !defined(OS_NACL_NONSFI) + TerminationStatus GetTerminationStatus(ProcessHandle handle, int* exit_code) { return GetTerminationStatusImpl(handle, false /* can_block */, exit_code); }
diff --git a/base/process/process_metrics.cc b/base/process/process_metrics.cc index 83185c02..6943a197 100644 --- a/base/process/process_metrics.cc +++ b/base/process/process_metrics.cc
@@ -26,8 +26,8 @@ } int64_t events_delta = event_count - *last_event_count; - double time_delta = (time - *last_calculated).InSecondsF(); - if (time_delta == 0) { + base::TimeDelta time_delta = time - *last_calculated; + if (time_delta == base::TimeDelta()) { NOTREACHED(); return 0; } @@ -35,7 +35,7 @@ *last_calculated = time; *last_event_count = event_count; - return base::ClampRound(events_delta / time_delta); + return base::ClampRound(events_delta / time_delta.InSecondsF()); } } // namespace
diff --git a/base/rand_util_posix.cc b/base/rand_util_posix.cc index 41ac6a09..64132cb 100644 --- a/base/rand_util_posix.cc +++ b/base/rand_util_posix.cc
@@ -14,6 +14,14 @@ #include "base/files/file_util.h" #include "base/no_destructor.h" #include "base/posix/eintr_wrapper.h" +#include "build/build_config.h" + +#if defined(OS_MAC) +// TODO(crbug.com/995996): Waiting for this header to appear in the iOS SDK. +// (See below.) We'll also use this on other POSIX platforms in the future (and +// change the #if condition then). +#include <sys/random.h> +#endif namespace { @@ -48,6 +56,17 @@ namespace base { void RandBytes(void* output, size_t output_length) { +#if defined(OS_MAC) + // TODO(crbug.com/995996): Enable this on iOS too, when sys/random.h arrives + // in its SDK. + if (__builtin_available(macOS 10.12, *)) { + if (getentropy(output, output_length) == 0) { + return; + } + } + // Fall through to reading from urandom on < 10.12: +#endif + const int urandom_fd = GetUrandomFD(); const bool success = ReadFromFD(urandom_fd, static_cast<char*>(output), output_length);
diff --git a/base/task/job_perftest.cc b/base/task/job_perftest.cc index 2e6782a..fb4dc53 100644 --- a/base/task/job_perftest.cc +++ b/base/task/job_perftest.cc
@@ -109,7 +109,7 @@ return num_incomplete_items_.fetch_sub(1, std::memory_order_relaxed) > 1; } - size_t NumIncompleteWorkItems() const { + size_t NumIncompleteWorkItems(size_t /*worker_count*/) const { // memory_order_relaxed is sufficient since this is not synchronized with // other state. return num_incomplete_items_.load(std::memory_order_relaxed); @@ -160,31 +160,31 @@ const TimeTicks job_run_start = TimeTicks::Now(); WaitableEvent complete; - auto handle = PostJob(FROM_HERE, {TaskPriority::USER_VISIBLE}, - BindRepeating( - [](WorkList* work_list, WaitableEvent* complete, - JobDelegate* delegate) { - for (size_t i = 0; - i < work_list->NumWorkItems() && - work_list->NumIncompleteWorkItems() != 0 && - !delegate->ShouldYield(); - ++i) { - if (!work_list->TryAcquire(i)) - continue; - if (!work_list->ProcessWorkItem(i)) { - complete->Signal(); - return; - } - } - }, - Unretained(&work_list), Unretained(&complete)), - BindRepeating(&WorkList::NumIncompleteWorkItems, - Unretained(&work_list))); + auto handle = PostJob( + FROM_HERE, {TaskPriority::USER_VISIBLE}, + BindRepeating( + [](WorkList* work_list, WaitableEvent* complete, + JobDelegate* delegate) { + for (size_t i = 0; i < work_list->NumWorkItems() && + work_list->NumIncompleteWorkItems(0) != 0 && + !delegate->ShouldYield(); + ++i) { + if (!work_list->TryAcquire(i)) + continue; + if (!work_list->ProcessWorkItem(i)) { + complete->Signal(); + return; + } + } + }, + Unretained(&work_list), Unretained(&complete)), + BindRepeating(&WorkList::NumIncompleteWorkItems, + Unretained(&work_list))); complete.Wait(); handle.Join(); const TimeDelta job_duration = TimeTicks::Now() - job_run_start; - EXPECT_EQ(0U, work_list.NumIncompleteWorkItems()); + EXPECT_EQ(0U, work_list.NumIncompleteWorkItems(0)); perf_test::PrintResult( "Work throughput", "", trace, size_t(num_work_items / job_duration.InMilliseconds()), "tasks/ms", @@ -214,7 +214,7 @@ BindRepeating( [](IndexGenerator* generator, WorkList* work_list, WaitableEvent* complete, JobDelegate* delegate) { - while (work_list->NumIncompleteWorkItems() != 0 && + while (work_list->NumIncompleteWorkItems(0) != 0 && !delegate->ShouldYield()) { Optional<size_t> index = generator->GetNext(); if (!index) @@ -243,7 +243,7 @@ complete.Wait(); handle.Join(); const TimeDelta job_duration = TimeTicks::Now() - job_run_start; - EXPECT_EQ(0U, work_list.NumIncompleteWorkItems()); + EXPECT_EQ(0U, work_list.NumIncompleteWorkItems(0)); perf_test::PrintResult( "Work throughput", "", trace, size_t(num_work_items / job_duration.InMilliseconds()), "tasks/ms", @@ -305,7 +305,7 @@ complete.Wait(); handle.Join(); const TimeDelta job_duration = TimeTicks::Now() - job_run_start; - EXPECT_EQ(0U, work_list.NumIncompleteWorkItems()); + EXPECT_EQ(0U, work_list.NumIncompleteWorkItems(0)); perf_test::PrintResult( "Work throughput", "", trace, size_t(num_work_items / job_duration.InMilliseconds()), "tasks/ms",
diff --git a/base/task/post_job.cc b/base/task/post_job.cc index bc74e242..c45db301 100644 --- a/base/task/post_job.cc +++ b/base/task/post_job.cc
@@ -133,6 +133,10 @@ return *this; } +bool JobHandle::IsCompleted() const { + return task_source_->IsCompleted(); +} + void JobHandle::UpdatePriority(TaskPriority new_priority) { task_source_->delegate()->UpdatePriority(task_source_, new_priority); } @@ -174,7 +178,7 @@ JobHandle PostJob(const Location& from_here, const TaskTraits& traits, RepeatingCallback<void(JobDelegate*)> worker_task, - RepeatingCallback<size_t()> max_concurrency_callback) { + RepeatingCallback<size_t(size_t)> max_concurrency_callback) { DCHECK(ThreadPoolInstance::Get()) << "Ref. Prerequisite section of post_task.h.\n\n" "Hint: if this is in a unit test, you're likely merely missing a "
diff --git a/base/task/post_job.h b/base/task/post_job.h index 75aebb3..b0f4ae5 100644 --- a/base/task/post_job.h +++ b/base/task/post_job.h
@@ -98,6 +98,9 @@ // Returns true if associated with a Job. explicit operator bool() const { return task_source_ != nullptr; } + // Returns true if there's no work pending and no worker running. + bool IsCompleted() const; + // Update this Job's priority. void UpdatePriority(TaskPriority new_priority); @@ -161,8 +164,9 @@ // } // // |max_concurrency_callback| controls the maximum number of threads calling -// |worker_task| concurrently. |worker_task| is only invoked if the number of -// threads previously running |worker_task| was less than the value returned by +// |worker_task| concurrently, given the number of threads currently assigned to +// this job. |worker_task| is only invoked if the number of threads previously +// running |worker_task| was less than the value returned by // |max_concurrency_callback|. In general, |max_concurrency_callback| should // return the latest number of incomplete work items (smallest unit of work) // left to processed. JobHandle/JobDelegate::NotifyConcurrencyIncrease() *must* @@ -181,7 +185,7 @@ PostJob(const Location& from_here, const TaskTraits& traits, RepeatingCallback<void(JobDelegate*)> worker_task, - RepeatingCallback<size_t()> max_concurrency_callback); + RepeatingCallback<size_t(size_t)> max_concurrency_callback); } // namespace base
diff --git a/base/task/post_job_unittest.cc b/base/task/post_job_unittest.cc index f2ee7d5..3471db8e 100644 --- a/base/task/post_job_unittest.cc +++ b/base/task/post_job_unittest.cc
@@ -21,7 +21,8 @@ auto handle = PostJob( FROM_HERE, {}, BindLambdaForTesting([&](JobDelegate* delegate) { --num_tasks_to_run; }), - BindLambdaForTesting([&]() -> size_t { return num_tasks_to_run; })); + BindLambdaForTesting( + [&](size_t /*worker_count*/) -> size_t { return num_tasks_to_run; })); handle.Join(); DCHECK_EQ(num_tasks_to_run, 0U); } @@ -29,9 +30,10 @@ TEST(PostJobTest, PostJobExtension) { testing::FLAGS_gtest_death_test_style = "threadsafe"; EXPECT_DCHECK_DEATH({ - auto handle = PostJob(FROM_HERE, TestExtensionBoolTrait(), - BindRepeating([](JobDelegate* delegate) {}), - BindRepeating([]() -> size_t { return 0; })); + auto handle = PostJob( + FROM_HERE, TestExtensionBoolTrait(), + BindRepeating([](JobDelegate* delegate) {}), + BindRepeating([](size_t /*worker_count*/) -> size_t { return 0; })); }); }
diff --git a/base/task/thread_pool/job_task_source.cc b/base/task/thread_pool/job_task_source.cc index 9fd1d3f..1d8ede7 100644 --- a/base/task/thread_pool/job_task_source.cc +++ b/base/task/thread_pool/job_task_source.cc
@@ -82,7 +82,7 @@ const Location& from_here, const TaskTraits& traits, RepeatingCallback<void(JobDelegate*)> worker_task, - RepeatingCallback<size_t()> max_concurrency_callback, + RepeatingCallback<size_t(size_t)> max_concurrency_callback, PooledTaskRunnerDelegate* delegate) : TaskSource(traits, nullptr, TaskSourceExecutionMode::kJob), from_here_(from_here), @@ -127,7 +127,7 @@ const auto state_before_add = state_.IncrementWorkerCount(); if (!state_before_add.is_canceled() && - state_before_add.worker_count() < GetMaxConcurrency()) { + state_before_add.worker_count() < GetMaxConcurrency(state_before_add)) { return true; } return WaitForParticipationOpportunity(); @@ -142,7 +142,7 @@ // Stale values will only cause WaitForParticipationOpportunity() to be // called. const auto state = TS_UNCHECKED_READ(state_).Load(); - if (!state.is_canceled() && state.worker_count() <= GetMaxConcurrency()) + if (!state.is_canceled() && state.worker_count() <= GetMaxConcurrency(state)) return true; TRACE_EVENT0("base", "Job.WaitForParticipationOpportunity"); @@ -170,7 +170,7 @@ // std::memory_order_relaxed is sufficient because no other state is // synchronized with |state_| outside of |lock_|. auto state = state_.Load(); - size_t max_concurrency = GetMaxConcurrency(); + size_t max_concurrency = GetMaxConcurrency(state); // Wait until either: // A) |worker_count| is below or equal to max concurrency and state is not @@ -188,7 +188,7 @@ // 2- In NotifyConcurrencyIncrease(), following a max_concurrency increase. worker_released_condition_->Wait(); state = state_.Load(); - max_concurrency = GetMaxConcurrency(); + max_concurrency = GetMaxConcurrency(state); } // Case A: if (state.worker_count() <= max_concurrency && !state.is_canceled()) @@ -204,8 +204,8 @@ TaskSource::RunStatus JobTaskSource::WillRunTask() { CheckedAutoLock auto_lock(worker_lock_); - const size_t max_concurrency = GetMaxConcurrency(); auto state_before_add = state_.Load(); + const size_t max_concurrency = GetMaxConcurrency(state_before_add); if (!state_before_add.is_canceled() && state_before_add.worker_count() < max_concurrency) { state_before_add = state_.IncrementWorkerCount(); @@ -233,13 +233,23 @@ // It is safe to read |state_| without a lock since this variable is atomic, // and no other state is synchronized with GetRemainingConcurrency(). const auto state = TS_UNCHECKED_READ(state_).Load(); - const size_t max_concurrency = GetMaxConcurrency(); + const size_t max_concurrency = GetMaxConcurrency(state); // Avoid underflows. if (state.is_canceled() || state.worker_count() > max_concurrency) return 0; return max_concurrency - state.worker_count(); } +bool JobTaskSource::IsCompleted() const { + CheckedAutoLock auto_lock(worker_lock_); + auto state = state_.Load(); + return GetMaxConcurrency(state) == 0 && state.worker_count() == 0; +} + +size_t JobTaskSource::GetWorkerCount() const { + return TS_UNCHECKED_READ(state_).Load().worker_count(); +} + void JobTaskSource::NotifyConcurrencyIncrease() { #if DCHECK_IS_ON() { @@ -272,7 +282,12 @@ } size_t JobTaskSource::GetMaxConcurrency() const { - return std::min(max_concurrency_callback_.Run(), kMaxWorkersPerJob); + return GetMaxConcurrency(TS_UNCHECKED_READ(state_).Load()); +} + +size_t JobTaskSource::GetMaxConcurrency(State::Value value) const { + return std::min(max_concurrency_callback_.Run(value.worker_count()), + kMaxWorkersPerJob); } uint8_t JobTaskSource::AcquireTaskId() { @@ -357,7 +372,7 @@ // Re-enqueue the TaskSource if the task ran and the worker count is below the // max concurrency. - return state_before_sub.worker_count() <= GetMaxConcurrency(); + return state_before_sub.worker_count() <= GetMaxConcurrency(state_.Load()); } SequenceSortKey JobTaskSource::GetSortKey() const {
diff --git a/base/task/thread_pool/job_task_source.h b/base/task/thread_pool/job_task_source.h index 43b6a7ed..70551ae 100644 --- a/base/task/thread_pool/job_task_source.h +++ b/base/task/thread_pool/job_task_source.h
@@ -35,7 +35,7 @@ JobTaskSource(const Location& from_here, const TaskTraits& traits, RepeatingCallback<void(JobDelegate*)> worker_task, - RepeatingCallback<size_t()> max_concurrency_callback, + RepeatingCallback<size_t(size_t)> max_concurrency_callback, PooledTaskRunnerDelegate* delegate); static JobHandle CreateJobHandle( @@ -69,6 +69,9 @@ ExecutionEnvironment GetExecutionEnvironment() override; size_t GetRemainingConcurrency() const override; + bool IsCompleted() const; + size_t GetWorkerCount() const; + // Returns the maximum number of tasks from this TaskSource that can run // concurrently. size_t GetMaxConcurrency() const; @@ -179,6 +182,8 @@ // either there's no work remaining or Job was cancelled. bool WaitForParticipationOpportunity() EXCLUSIVE_LOCKS_REQUIRED(worker_lock_); + size_t GetMaxConcurrency(State::Value value) const; + // TaskSource: RunStatus WillRunTask() override; Task TakeTask(TaskSource::Transaction* transaction) override; @@ -202,7 +207,7 @@ std::atomic<uint32_t> assigned_task_ids_{0}; const Location from_here_; - RepeatingCallback<size_t()> max_concurrency_callback_; + RepeatingCallback<size_t(size_t)> max_concurrency_callback_; // Worker task set by the job owner. RepeatingCallback<void(JobDelegate*)> worker_task_;
diff --git a/base/task/thread_pool/job_task_source_unittest.cc b/base/task/thread_pool/job_task_source_unittest.cc index 50e0715..9ba4af5 100644 --- a/base/task/thread_pool/job_task_source_unittest.cc +++ b/base/task/thread_pool/job_task_source_unittest.cc
@@ -57,14 +57,17 @@ { EXPECT_EQ(registered_task_source.WillRunTask(), TaskSource::RunStatus::kAllowedNotSaturated); + EXPECT_EQ(1U, task_source->GetWorkerCount()); auto task = registered_task_source.TakeTask(); std::move(task.task).Run(); EXPECT_TRUE(registered_task_source.DidProcessTask()); + EXPECT_EQ(0U, task_source->GetWorkerCount()); } { EXPECT_EQ(registered_task_source.WillRunTask(), TaskSource::RunStatus::kAllowedSaturated); + EXPECT_EQ(1U, task_source->GetWorkerCount()); // An attempt to run an additional task is not allowed. EXPECT_EQ(RegisteredTaskSource::CreateForTesting(task_source).WillRunTask(), @@ -76,8 +79,11 @@ std::move(task.task).Run(); EXPECT_EQ(0U, task_source->GetRemainingConcurrency()); + EXPECT_FALSE(task_source->IsCompleted()); // Returns false because the task source is out of tasks. EXPECT_FALSE(registered_task_source.DidProcessTask()); + EXPECT_EQ(0U, task_source->GetWorkerCount()); + EXPECT_TRUE(task_source->IsCompleted()); } } @@ -196,12 +202,14 @@ RegisteredTaskSource::CreateForTesting(task_source); EXPECT_EQ(registered_task_source_a.WillRunTask(), TaskSource::RunStatus::kAllowedNotSaturated); + EXPECT_EQ(1U, task_source->GetWorkerCount()); auto task_a = registered_task_source_a.TakeTask(); auto registered_task_source_b = RegisteredTaskSource::CreateForTesting(task_source); EXPECT_EQ(registered_task_source_b.WillRunTask(), TaskSource::RunStatus::kAllowedSaturated); + EXPECT_EQ(2U, task_source->GetWorkerCount()); auto task_b = registered_task_source_b.TakeTask(); // WillRunTask() should return a null RunStatus once the max concurrency is @@ -218,6 +226,8 @@ std::move(task_b.task).Run(); EXPECT_TRUE(registered_task_source_b.DidProcessTask()); + EXPECT_EQ(0U, task_source->GetWorkerCount()); + auto registered_task_source_c = RegisteredTaskSource::CreateForTesting(task_source); EXPECT_EQ(registered_task_source_c.WillRunTask(), @@ -283,11 +293,13 @@ auto worker_task = registered_task_source.TakeTask(); EXPECT_TRUE(task_source->WillJoin()); + EXPECT_FALSE(task_source->IsCompleted()); std::move(worker_task.task).Run(); EXPECT_FALSE(registered_task_source.DidProcessTask()); EXPECT_FALSE(task_source->RunJoinTask()); + EXPECT_TRUE(task_source->IsCompleted()); } // Verifies that a call to NotifyConcurrencyIncrease() calls the delegate @@ -365,7 +377,7 @@ // As set up below, the mock will return true once. ASSERT_TRUE(delegate->ShouldYield()); }), - BindRepeating([]() -> size_t { + BindRepeating([](size_t /*worker_count*/) -> size_t { return 1; // max concurrency is always 1. }), &pooled_task_runner_delegate_); @@ -422,7 +434,7 @@ auto task_source = MakeRefCounted<JobTaskSource>( FROM_HERE, TaskTraits{}, BindRepeating([](JobDelegate*) {}), - BindRepeating([]() -> size_t { return 1; }), + BindRepeating([](size_t /*worker_count*/) -> size_t { return 1; }), &pooled_task_runner_delegate_); auto registered_task_source = @@ -505,7 +517,7 @@ // Allow running the task again. delegate->NotifyConcurrencyIncrease(); }), - BindRepeating([]() -> size_t { return 1; }), + BindRepeating([](size_t /*worker_count*/) -> size_t { return 1; }), &pooled_task_runner_delegate_); auto registered_task_source =
diff --git a/base/task/thread_pool/test_utils.cc b/base/task/thread_pool/test_utils.cc index 837b61d..8d70f53 100644 --- a/base/task/thread_pool/test_utils.cc +++ b/base/task/thread_pool/test_utils.cc
@@ -258,7 +258,7 @@ base::Passed(std::move(worker_task)))), remaining_num_tasks_to_run_(1) {} -size_t MockJobTask::GetMaxConcurrency() const { +size_t MockJobTask::GetMaxConcurrency(size_t /* worker_count */) const { return remaining_num_tasks_to_run_.load(); }
diff --git a/base/task/thread_pool/test_utils.h b/base/task/thread_pool/test_utils.h index 1908cbd1..3d13b4a 100644 --- a/base/task/thread_pool/test_utils.h +++ b/base/task/thread_pool/test_utils.h
@@ -94,7 +94,7 @@ remaining_num_tasks_to_run_ = num_tasks_to_run; } - size_t GetMaxConcurrency() const; + size_t GetMaxConcurrency(size_t worker_count) const; void Run(JobDelegate* delegate); scoped_refptr<JobTaskSource> GetJobTaskSource(
diff --git a/base/task/thread_pool/thread_group_unittest.cc b/base/task/thread_pool/thread_group_unittest.cc index 35058f2..a8c79ca 100644 --- a/base/task/thread_pool/thread_group_unittest.cc +++ b/base/task/thread_pool/thread_group_unittest.cc
@@ -797,7 +797,7 @@ JobHandle job_handle = internal::JobTaskSource::CreateJobHandle(task_source); job_handle.Join(); // All worker tasks should complete before Join() returns. - EXPECT_EQ(0U, job_task->GetMaxConcurrency()); + EXPECT_EQ(0U, job_task->GetMaxConcurrency(0)); thread_group_->JoinForTesting(); EXPECT_EQ(1U, task_source->HasOneRef()); // Prevent TearDown() from calling JoinForTesting() again. @@ -814,7 +814,8 @@ auto task_source = MakeRefCounted<JobTaskSource>( FROM_HERE, TaskTraits{}, BindLambdaForTesting([&](JobDelegate*) { thread_running.Signal(); }), - BindLambdaForTesting([&]() -> size_t { return max_concurrency; }), + BindLambdaForTesting( + [&](size_t /*worker_count*/) -> size_t { return max_concurrency; }), &mock_pooled_task_runner_delegate_); mock_pooled_task_runner_delegate_.EnqueueJobTaskSource(task_source); @@ -838,7 +839,7 @@ auto task_source = MakeRefCounted<JobTaskSource>( FROM_HERE, TaskTraits{}, BindLambdaForTesting([&](JobDelegate*) { thread_running.Signal(); }), - BindRepeating([]() -> size_t { return 1; }), + BindRepeating([](size_t /*worker_count*/) -> size_t { return 1; }), &mock_pooled_task_runner_delegate_); mock_pooled_task_runner_delegate_.EnqueueJobTaskSource(task_source);
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index 1abc32d..66c4c89c 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -438,21 +438,38 @@ // Cleanup the data directory. CHECK(DeletePathRecursively(nested_data_path)); #elif defined(OS_POSIX) - // It is not possible to waitpid() on any leaked sub-processes of the test - // batch process, since those are not direct children of this process. - // kill()ing the process-group will return a result indicating whether the - // group was found (i.e. processes were still running in it) or not (i.e. - // sub-processes had exited already). Unfortunately many tests (e.g. browser - // tests) have processes exit asynchronously, so checking the kill() result - // will report false failures. - // Unconditionally kill the process group, regardless of the batch exit-code - // until a better solution is available. - int kill_result = kill(-1 * process.Handle(), SIGKILL); - if (kill_result < 0 && errno != ESRCH) { - PLOG(ERROR) << "kill(-" << process.Handle() << ") failed"; - exit_code = -1; + +#if BUILDFLAG(CLANG_PROFILING) + // TODO(crbug.com/1094369): Remove this condition once the child process + // leaking bug is fixed. + // + // TODO(crbug.com/1095075): Make test launcher treat lingering child + // processes hard failures so that they can be detected and surfaced + // gracefully. + // + // When profiling is enabled, browser child processes take extra time to + // dump profiles, which means that lingering processes are much more likely + // to happen than non-profiling build. Therefore, on POSIX, in order to + // avoid polluting the machine state, ensure any child processes that the + // test might have created are cleaned up to avoid potential leaking even + // when tests have passed. On Windows, child processes are automatically + // cleaned up using JobObjects. + // + // On non-profiling build, when tests have passed, we don't clean up the + // lingering processes even when there are any, and the reason is that they + // usually indicate prod issues, letting them slip to the following test + // tasks and cause failures increses the chance of them being surfaced. + kill(-1 * process.Handle(), SIGKILL); +#else + if (exit_code != 0) { + // On POSIX, in case the test does not exit cleanly, either due to a crash + // or due to it timing out, we need to clean up any child processes that + // it might have created. On Windows, child processes are automatically + // cleaned up using JobObjects. + KillProcessGroup(process.Handle()); } -#endif // defined(OS_POSIX) +#endif +#endif GetLiveProcesses()->erase(process.Handle()); }
diff --git a/base/test/launcher/test_launcher_unittest.cc b/base/test/launcher/test_launcher_unittest.cc index dfa69e4..bcf7df0 100644 --- a/base/test/launcher/test_launcher_unittest.cc +++ b/base/test/launcher/test_launcher_unittest.cc
@@ -15,14 +15,12 @@ #include "base/test/launcher/test_launcher.h" #include "base/test/launcher/test_launcher_test_utils.h" #include "base/test/launcher/unit_test_launcher.h" -#include "base/test/multiprocess_test.h" #include "base/test/task_environment.h" #include "base/test/test_timeouts.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/multiprocess_func_list.h" #if defined(OS_WIN) #include "base/win/windows_version.h" @@ -710,12 +708,12 @@ TEST(MockUnitTests, DISABLED_CrashTest) { IMMEDIATE_CRASH(); } -// Basic test will not be reached, due to the preceding crash in the same batch. +// Basic test will not be reached with default batch size. TEST(MockUnitTests, DISABLED_NoRunTest) { ASSERT_TRUE(true); } -// Using TestLauncher to launch 3 basic unitests +// Using TestLauncher to launch 3 simple unitests // and validate the resulting json file. TEST_F(UnitTestLauncherDelegateTester, RunMockTests) { CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram());
diff --git a/build/config/android/config.gni b/build/config/android/config.gni index 9be0dc1..0b942fa4c 100644 --- a/build/config/android/config.gni +++ b/build/config/android/config.gni
@@ -129,6 +129,12 @@ "//third_party/android_deps:com_google_android_material_material_java" } + if (!defined(android_protoc_bin)) { + android_protoc_bin = "//third_party/android_protoc/protoc" + android_proto_runtime = + "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java" + } + webview_public_framework_dep = "//third_party/android_sdk:public_framework_system_java" if (!defined(webview_framework_dep)) {
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index dd74568..66614c6 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -4009,10 +4009,6 @@ # proto_path (required) # Root directory of .proto files. # - # generate_nano (optional, default false) - # Whether to generate nano protos. If false, this will use the lite proto generator. - # Nano protos are deprecated, so please use lite new proto libraries. - # # deps (optional) # Additional dependencies. Passed through to both the action and the # android_library targets. @@ -4032,22 +4028,7 @@ template("proto_java_library") { set_sources_assignment_filter([]) forward_variables_from(invoker, [ "testonly" ]) - _generate_nano = - defined(invoker.generate_nano) && invoker.generate_nano == true - if (_generate_nano) { - # Use the legacy Android nano proto generator. - _protoc_dep = - "//third_party/android_protobuf:android_protoc($host_toolchain)" - _protoc_out_dir = get_label_info(_protoc_dep, "root_out_dir") - _protoc_bin = "$_protoc_out_dir/android_protoc" - _proto_runtime = "//third_party/android_protobuf:protobuf_nano_javalib" - } else { - # Use the regular proto library to generate lite protos. - _protoc_bin = "//third_party/android_protoc/protoc" - _proto_runtime = "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java" - } - _proto_path = invoker.proto_path _template_name = target_name action_with_pydeps("${_template_name}__protoc_java") { @@ -4057,9 +4038,6 @@ script = "//build/protoc_java.py" deps = [] - if (defined(_protoc_dep)) { - deps += [ _protoc_dep ] - } if (defined(invoker.deps)) { deps += invoker.deps } @@ -4071,9 +4049,9 @@ "--depfile", rebase_path(depfile, root_build_dir), "--protoc", - rebase_path(_protoc_bin, root_build_dir), + rebase_path(android_protoc_bin, root_build_dir), "--proto-path", - rebase_path(_proto_path, root_build_dir), + rebase_path(invoker.proto_path, root_build_dir), "--srcjar", rebase_path(_srcjar_path, root_build_dir), ] + rebase_path(sources, root_build_dir) @@ -4086,17 +4064,13 @@ ] } } - - if (_generate_nano) { - args += [ "--nano" ] - } } android_library(target_name) { chromium_code = false sources = [] srcjar_deps = [ ":${_template_name}__protoc_java" ] - deps = [ _proto_runtime ] + deps = [ android_proto_runtime ] if (defined(invoker.deps)) { deps += invoker.deps } @@ -4127,6 +4101,9 @@ # ignore_proguard_configs: Whether to ignore proguard configs. # strip_resources: Whether to ignore android resources found in the .aar. # custom_package: Java package for generated R.java files. + # extract_assets: Whether to extract and include assets found in the .aar. + # If the file contains assets, either extract_assets or ignore_assets + # must be set. # extract_native_libraries: Whether to extract .so files found in the .aar. # If the file contains .so, either extract_native_libraries or # ignore_native_libraries must be set. @@ -4154,6 +4131,7 @@ _unpack_target_name = "${_target_name_without_java_or_junit}__unpack_aar" _ignore_aidl = defined(invoker.ignore_aidl) && invoker.ignore_aidl _ignore_assets = defined(invoker.ignore_assets) && invoker.ignore_assets + _extract_assets = defined(invoker.extract_assets) && invoker.extract_assets _ignore_manifest = defined(invoker.ignore_manifest) && invoker.ignore_manifest _ignore_native_libraries = defined(invoker.ignore_native_libraries) && @@ -4184,14 +4162,12 @@ # rm -r out/tmp _scanned_files = read_file(_info_path, "scope") + _contains_scanned_assets = _scanned_files.assets != [] + assert(_ignore_aidl || _scanned_files.aidl == [], "android_aar_prebuilt() aidl not yet supported." + " Implement or use ignore_aidl = true." + " http://crbug.com/644439") - assert(_ignore_assets || _scanned_files.assets == [], - "android_aar_prebuilt() assets not yet supported." + - " Implement or use ignore_assets = true." + - " http://crbug.com/643966") assert( !_scanned_files.has_native_libraries || (_ignore_native_libraries || _extract_native_libraries), @@ -4200,6 +4176,11 @@ assert( !(_ignore_native_libraries && _extract_native_libraries), "ignore_native_libraries and extract_native_libraries cannot both be set.") + assert(!_contains_scanned_assets || (_ignore_assets || _extract_assets), + "android_aar_prebuilt() contains asset files." + + " Please set ignore_assets or extract_assets.") + assert(!(_ignore_assets && _extract_assets), + "ignore_assets and extract_assets cannot both be set.") assert(!_scanned_files.has_native_libraries || _scanned_files.native_libraries != []) assert(_scanned_files.has_classes_jar || _scanned_files.subjars == []) @@ -4257,6 +4238,11 @@ rebase_path(_scanned_files.native_libraries, "", _output_path), "abspath") } + if (_extract_assets && _contains_scanned_assets) { + outputs += + get_path_info(rebase_path(_scanned_files.assets, "", _output_path), + "abspath") + } } _has_unignored_resources = @@ -4310,6 +4296,26 @@ not_needed(invoker, [ "strip_drawables" ]) } + _should_extract_assets = _extract_assets && _contains_scanned_assets + + # Create the android_assets target for assets + if (_should_extract_assets) { + _assets_target_name = "${target_name}__assets" + android_assets(_assets_target_name) { + forward_variables_from(invoker, [ "testonly" ]) + renaming_sources = [] + renaming_destinations = [] + foreach(_asset_file, _scanned_files.assets) { + _original_path = + get_path_info(rebase_path(_asset_file, "", _output_path), + "abspath") + _updated_path = string_replace(_asset_file, "assets/", "", 1) + renaming_sources += [ _original_path ] + renaming_destinations += [ _updated_path ] + } + } + } + # Create android_java_prebuilt target for classes.jar. if (_scanned_files.has_classes_jar) { _java_library_vars = [ @@ -4399,6 +4405,9 @@ if (defined(_res_target_name)) { deps += [ ":$_res_target_name" ] } + if (defined(_assets_target_name)) { + deps += [ ":$_assets_target_name" ] + } } }
diff --git a/build/config/linux/BUILD.gn b/build/config/linux/BUILD.gn index 2a5f886..d939fc2 100644 --- a/build/config/linux/BUILD.gn +++ b/build/config/linux/BUILD.gn
@@ -45,9 +45,7 @@ "Xdamage", "Xext", "Xfixes", - "Xi", "Xrender", - "Xtst", ] } @@ -67,14 +65,6 @@ libs = [ "cap" ] } -config("xi") { - libs = [ "Xi" ] -} - -config("xtst") { - libs = [ "Xtst" ] -} - config("libresolv") { libs = [ "resolv" ] }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 01bee43c..b0fc14ff 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -0.20200812.1.1 +0.20200812.4.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 01bee43c..b0fc14ff 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -0.20200812.1.1 +0.20200812.4.1
diff --git a/cc/debug/debug_colors.cc b/cc/debug/debug_colors.cc index 2d1f0804..0faf114 100644 --- a/cc/debug/debug_colors.cc +++ b/cc/debug/debug_colors.cc
@@ -339,7 +339,7 @@ return SkColorSetARGB(96, 255, 0, 128); case LCDTextDisallowedReason::kWillChangeTransform: return SkColorSetARGB(96, 128, 0, 255); - case LCDTextDisallowedReason::kLayerHasFilterEffect: + case LCDTextDisallowedReason::kPixelOrColorEffect: return SkColorSetARGB(96, 0, 128, 0); } NOTREACHED();
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index d3010511..44541af 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -864,9 +864,9 @@ return LCDTextDisallowedReason::kWillChangeTransform; EffectNode* effect_node = GetEffectTree().Node(effect_tree_index()); - // TODO(crbug.com/1074521): Should also consider ancestor filters. + // TODO(crbug.com/1114504): Should also consider ancestor filters. if (!effect_node->filters.IsEmpty()) - return LCDTextDisallowedReason::kLayerHasFilterEffect; + return LCDTextDisallowedReason::kPixelOrColorEffect; return LCDTextDisallowedReason::kNone; }
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 4e1d2392..fdf2787 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -6174,7 +6174,7 @@ FilterOperations blur_filter; blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); SetFilter(child_, blur_filter); - CheckCanUseLCDText(LCDTextDisallowedReason::kLayerHasFilterEffect, child_); + CheckCanUseLCDText(LCDTextDisallowedReason::kPixelOrColorEffect, child_); // TODO(crbug.com/1114504): will-change:transform should apply to descendants. CheckCanUseLCDText(LCDTextDisallowedReason::kNone, grand_child_);
diff --git a/cc/metrics/video_playback_roughness_reporter.cc b/cc/metrics/video_playback_roughness_reporter.cc index 8b670b4..50f3d2a0 100644 --- a/cc/metrics/video_playback_roughness_reporter.cc +++ b/cc/metrics/video_playback_roughness_reporter.cc
@@ -73,8 +73,8 @@ } // Adjust frame window size to fit about 1 second of playback - int win_size = base::ClampRound( - kDesiredWindowDuration / info.intended_duration.value().InSecondsF()); + int win_size = base::ClampRound(kDesiredWindowDuration * + info.intended_duration.value().ToHz()); frames_window_size_ = std::max(kMinWindowSize, win_size); frames_window_size_ = std::min(frames_window_size_, kMaxWindowSize); }
diff --git a/cc/raster/lcd_text_disallowed_reason.cc b/cc/raster/lcd_text_disallowed_reason.cc index c4e6604..c2e59ed 100644 --- a/cc/raster/lcd_text_disallowed_reason.cc +++ b/cc/raster/lcd_text_disallowed_reason.cc
@@ -27,8 +27,8 @@ return "non-integral-y-offset"; case LCDTextDisallowedReason::kWillChangeTransform: return "will-change-transform"; - case LCDTextDisallowedReason::kLayerHasFilterEffect: - return "layer-has-filter-effect"; + case LCDTextDisallowedReason::kPixelOrColorEffect: + return "pixel-or-color-effect"; } NOTREACHED(); return "";
diff --git a/cc/raster/lcd_text_disallowed_reason.h b/cc/raster/lcd_text_disallowed_reason.h index c897300..9296f5c 100644 --- a/cc/raster/lcd_text_disallowed_reason.h +++ b/cc/raster/lcd_text_disallowed_reason.h
@@ -24,8 +24,8 @@ kNonIntegralXOffset = 5, kNonIntegralYOffset = 6, kWillChangeTransform = 7, - kLayerHasFilterEffect = 8, - kMaxValue = kLayerHasFilterEffect, + kPixelOrColorEffect = 8, + kMaxValue = kPixelOrColorEffect, }; constexpr size_t kLCDTextDisallowedReasonCount = static_cast<size_t>(LCDTextDisallowedReason::kMaxValue) + 1;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 146cfb8..21b8216 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -17619,11 +17619,15 @@ occluding_frame_layer->SetBounds(gfx::Size(50, 50)); occluding_frame_layer->SetHitTestable(true); CopyProperties(root_layer(), occluding_frame_layer); - CreateTransformNode(occluding_frame_layer).frame_element_id = ElementId(0x20); + CreateTransformNode(occluding_frame_layer, + frame_layer->transform_tree_index()) + .frame_element_id = ElementId(0x20); occluding_frame_layer->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); UpdateDrawProperties(host_impl_->active_tree()); + EXPECT_EQ(host_impl_->FindFrameElementIdAtPoint(gfx::PointF(15, 15)), + ElementId(0x10)); EXPECT_EQ(host_impl_->FindFrameElementIdAtPoint(gfx::PointF(30, 30)), ElementId(0x20)); } @@ -17668,7 +17672,8 @@ rounded_frame_layer->SetBounds(gfx::Size(50, 50)); rounded_frame_layer->SetHitTestable(true); CopyProperties(root_layer(), rounded_frame_layer); - CreateTransformNode(rounded_frame_layer).frame_element_id = ElementId(0x20); + CreateTransformNode(rounded_frame_layer, frame_layer->transform_tree_index()) + .frame_element_id = ElementId(0x20); rounded_frame_layer->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); // Add rounded corners to the layer, which are unable to be hit tested by the @@ -17683,5 +17688,35 @@ EXPECT_FALSE(host_impl_->FindFrameElementIdAtPoint(gfx::PointF(30, 30))); } +TEST_F(LayerTreeHostImplTest, FrameElementIdHitTestOverlapSibling) { + SetupDefaultRootLayer(gfx::Size(100, 100)); + + LayerImpl* frame_layer = AddLayer(); + frame_layer->SetBounds(gfx::Size(50, 50)); + frame_layer->SetHitTestable(true); + CopyProperties(root_layer(), frame_layer); + CreateTransformNode(frame_layer, root_layer()->transform_tree_index()) + .frame_element_id = ElementId(0x20); + + LayerImpl* sibling_frame_layer = AddLayer(); + sibling_frame_layer->SetBounds(gfx::Size(50, 50)); + sibling_frame_layer->SetHitTestable(true); + CopyProperties(root_layer(), sibling_frame_layer); + CreateTransformNode(sibling_frame_layer, root_layer()->transform_tree_index()) + .frame_element_id = ElementId(0x30); + sibling_frame_layer->SetOffsetToTransformParent(gfx::Vector2dF(25, 25)); + + UpdateDrawProperties(host_impl_->active_tree()); + + EXPECT_EQ(host_impl_->FindFrameElementIdAtPoint(gfx::PointF(15, 15)), + ElementId(0x20)); + EXPECT_EQ(host_impl_->FindFrameElementIdAtPoint(gfx::PointF(60, 60)), + ElementId(0x30)); + + // If we have a layer occluded by a layer from another document, attributions + // should be discarded outside of the simple frame -> subframe case. + EXPECT_FALSE(host_impl_->FindFrameElementIdAtPoint(gfx::PointF(30, 30))); +} + } // namespace } // namespace cc
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 123377b..c01d7d7e 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -12,6 +12,7 @@ #include <limits> #include <memory> #include <set> +#include <unordered_set> #include <utility> #include "base/containers/adapters.h" @@ -2388,6 +2389,81 @@ layer.non_fast_scrollable_region(), &layer); } +static ElementId GetFrameElementIdForLayer(const LayerImpl* layer) { + ElementId frame_element_id; + auto& transform_tree = + layer->layer_tree_impl()->property_trees()->transform_tree; + auto* node = transform_tree.Node(layer->transform_tree_index()); + while (node && !frame_element_id) { + frame_element_id = node->frame_element_id; + node = transform_tree.parent(node); + } + return frame_element_id; +} + +static void FindClosestMatchingLayerForAttribution( + const gfx::PointF& screen_space_point, + const LayerImpl* root_layer, + FindClosestMatchingLayerState* state) { + std::unordered_set<ElementId, ElementIdHash> hit_frame_element_ids; + // We want to iterate from front to back when hit testing. + for (auto* layer : base::Reversed(*root_layer->layer_tree_impl())) { + if (!layer->HitTestable()) + continue; + + float distance_to_intersection = 0.f; + bool hit = false; + if (layer->Is3dSorted()) { + hit = + PointHitsLayer(layer, screen_space_point, &distance_to_intersection); + } else { + hit = PointHitsLayer(layer, screen_space_point, nullptr); + } + + if (!hit) + continue; + + bool in_front_of_previous_candidate = + state->closest_match && + layer->GetSortingContextId() == + state->closest_match->GetSortingContextId() && + distance_to_intersection > + state->closest_distance + std::numeric_limits<float>::epsilon(); + + if (!state->closest_match || in_front_of_previous_candidate) { + state->closest_distance = distance_to_intersection; + state->closest_match = layer; + } + + ElementId frame_element_id = GetFrameElementIdForLayer(layer); + hit_frame_element_ids.insert(frame_element_id); + } + + // Iterate through the transform tree of the hit layer in order to derive the + // frame path (which is a subset of the transform path). If we hit any frame + // layer in our hit testing that belonged to a frame outside of this + // hierarchy, bail out. + // + // We explicitly allow occluding layers whose frames are parents of the + // targeted frame so that we can properly attribute the (common) parent -> + // child frame relationship. This is made possible since we can accurately + // hit test within layerized subframes, but not for all occluders. + if (auto* layer = state->closest_match) { + auto& transform_tree = + layer->layer_tree_impl()->property_trees()->transform_tree; + for (auto* node = transform_tree.Node(layer->transform_tree_index()); node; + node = transform_tree.parent(node)) { + hit_frame_element_ids.erase(node->frame_element_id); + if (hit_frame_element_ids.size() == 0) + break; + } + + if (hit_frame_element_ids.size() > 0) { + state->closest_distance = 0.f; + state->closest_match = nullptr; + } + } +} ElementId LayerTreeImpl::FindFrameElementIdAtPoint( const gfx::PointF& screen_space_point) { @@ -2396,19 +2472,10 @@ if (!UpdateDrawProperties()) return {}; FindClosestMatchingLayerState state; - FindClosestMatchingLayer(screen_space_point, layer_list_[0].get(), - HitTestVisibleScrollableOrTouchableFunctor(), - &state); + FindClosestMatchingLayerForAttribution(screen_space_point, + layer_list_[0].get(), &state); - if (auto* layer = state.closest_match) { - ElementId frame_element_id; - auto* node = - property_trees()->transform_tree.Node(layer->transform_tree_index()); - while (node && !frame_element_id) { - frame_element_id = node->frame_element_id; - node = property_trees()->transform_tree.parent(node); - } - + if (const auto* layer = state.closest_match) { // TODO(https://crbug.com/1058870): Permit hit testing only if the framed // element hit has a simple mask/clip. We don't have enough information // about complex masks/clips on the impl-side to do accurate hit testing. @@ -2417,8 +2484,9 @@ layer->effect_tree_index()); if (!layer_hit_test_region_is_masked) - return frame_element_id; + return GetFrameElementIdForLayer(layer); } + return {}; }
diff --git a/chrome/VERSION b/chrome/VERSION index 7730da6..45e6b56 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=86 MINOR=0 -BUILD=4232 +BUILD=4233 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index e06b5ca..e01e91a 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -484,9 +484,9 @@ "//third_party/android_deps:com_google_code_findbugs_jsr305_java", "//third_party/android_deps:com_google_dagger_dagger_java", "//third_party/android_deps:com_google_guava_listenablefuture_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/android_deps:javax_inject_javax_inject_java", "//third_party/android_deps:material_design_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/android_media:android_media_java", "//third_party/android_sdk:android_gcm_java", "//third_party/android_sdk/androidx_browser:androidx_browser_java", @@ -871,8 +871,8 @@ "//third_party/android_deps:androidx_test_core_java", "//third_party/android_deps:androidx_test_runner_java", "//third_party/android_deps:com_google_dagger_dagger_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/android_deps:com_googlecode_java_diff_utils_diffutils_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/android_sdk/androidx_browser:androidx_browser_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", @@ -1131,9 +1131,9 @@ # to androidx. "//third_party/android_deps:com_android_support_recyclerview_v7_java", "//third_party/android_deps:com_google_code_findbugs_jsr305_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/android_deps:espresso_java", "//third_party/android_deps:material_design_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/android_sdk:android_test_base_java", "//third_party/android_sdk:android_test_mock_java", "//third_party/android_sdk:android_test_runner_java", @@ -1148,6 +1148,7 @@ "//third_party/junit", "//third_party/mockito:mockito_java", "//third_party/ub-uiautomator:ub_uiautomator_java", + "//ui/android:clipboard_java_test_support", "//ui/android:ui_java", "//ui/android:ui_java_test_support", "//ui/android:ui_javatests", @@ -1888,7 +1889,7 @@ "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:androidx_annotation_annotation_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/junit", ] } @@ -3259,11 +3260,7 @@ "//url/mojom:url_mojom_gurl_java", ] - sources = [ - "native_java_unittests/src/org/chromium/chrome/browser/UnitTestUtils.java", - ] - - sources += native_java_unittests_tests + sources = native_java_unittests_tests annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] }
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index acad3418..1a29f87 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -460,6 +460,7 @@ "java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionService.java", "java/src/org/chromium/chrome/browser/customtabs/FirstMeaningfulPaintObserver.java", "java/src/org/chromium/chrome/browser/customtabs/HiddenTabHolder.java", + "java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java", "java/src/org/chromium/chrome/browser/customtabs/NavigationInfoCaptureTrigger.java", "java/src/org/chromium/chrome/browser/customtabs/PageLoadMetricsObserver.java", "java/src/org/chromium/chrome/browser/customtabs/PaymentHandlerActivity.java",
diff --git a/chrome/android/expectations/lint-baseline.xml b/chrome/android/expectations/lint-baseline.xml index 945e044..2abf8c7 100644 --- a/chrome/android/expectations/lint-baseline.xml +++ b/chrome/android/expectations/lint-baseline.xml
@@ -260,72 +260,6 @@ <issue id="WrongConstant" - message="Must be one of: SelectionType.UNDETERMINED, SelectionType.TAP, SelectionType.LONG_PRESS" - errorLine1=" || mSelectionController.getSelectionType() == SelectionType.RESOLVING_LONG_PRESS;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java" - line="460" - column="63"/> - </issue> - - <issue - id="WrongConstant" - message="Must be one of: SelectionType.UNDETERMINED, SelectionType.TAP, SelectionType.LONG_PRESS" - errorLine1=" == SelectionType.RESOLVING_LONG_PRESS)) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java" - line="784" - column="36"/> - </issue> - - <issue - id="WrongConstant" - message="Must be one of: SelectionType.UNDETERMINED, SelectionType.TAP, SelectionType.LONG_PRESS" - errorLine1=" if (mSelectionController.getSelectionType() == SelectionType.RESOLVING_LONG_PRESS) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java" - line="1375" - column="56"/> - </issue> - - <issue - id="WrongConstant" - message="Must be one of: SelectionType.UNDETERMINED, SelectionType.TAP, SelectionType.LONG_PRESS" - errorLine1=" == SelectionType.RESOLVING_LONG_PRESS;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java" - line="1598" - column="36"/> - </issue> - - <issue - id="WrongConstant" - message="Must be one of: SelectionType.UNDETERMINED, SelectionType.TAP, SelectionType.LONG_PRESS" - errorLine1=" == SelectionType.RESOLVING_LONG_PRESS) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java" - line="1633" - column="36"/> - </issue> - - <issue - id="WrongConstant" - message="Must be one of: SelectionType.UNDETERMINED, SelectionType.TAP, SelectionType.LONG_PRESS" - errorLine1=" || mSelectionController.getSelectionType() == SelectionType.RESOLVING_LONG_PRESS" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java" - line="138" - column="63"/> - </issue> - - <issue - id="WrongConstant" message="Must be one of: TabLaunchType.FROM_LINK, TabLaunchType.FROM_EXTERNAL_APP, TabLaunchType.FROM_CHROME_UI, TabLaunchType.FROM_RESTORE, TabLaunchType.FROM_LONGPRESS_FOREGROUND, TabLaunchType.FROM_LONGPRESS_BACKGROUND, TabLaunchType.FROM_REPARENTING, TabLaunchType.FROM_LAUNCHER_SHORTCUT, TabLaunchType.FROM_SPECULATIVE_BACKGROUND_CREATION, TabLaunchType.FROM_BROWSER_ACTIONS, TabLaunchType.FROM_LAUNCH_NEW_INCOGNITO_TAB, TabLaunchType.FROM_STARTUP, TabLaunchType.FROM_START_SURFACE, TabLaunchType.SIZE" errorLine1=" return -1;" errorLine2=" ~~">
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn index 2c9d53c..bb3df2c 100644 --- a/chrome/android/features/autofill_assistant/BUILD.gn +++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -235,7 +235,7 @@ "//components/autofill_assistant/browser:proto_java", "//content/public/test/android:content_java_test_support", "//third_party/android_deps:androidx_annotation_annotation_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/hamcrest:hamcrest_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] @@ -301,9 +301,9 @@ "//third_party/android_deps:androidx_coordinatorlayout_coordinatorlayout_java", "//third_party/android_deps:androidx_recyclerview_recyclerview_java", "//third_party/android_deps:androidx_test_runner_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//third_party/android_deps:espresso_java", "//third_party/android_deps:material_design_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//third_party/android_support_test_runner:runner_java", "//third_party/gif_player:gif_player_java", "//third_party/hamcrest:hamcrest_java",
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_header.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_header.xml index 9689c17..9185a74 100644 --- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_header.xml +++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_header.xml
@@ -8,6 +8,7 @@ android:layout_height="wrap_content"> <LinearLayout + android:id="@+id/header_top_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="56dp"
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java index b246ed73..12a9c82 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AssistantBottomBarCoordinator.java
@@ -151,6 +151,8 @@ // We don't want to animate the carousels children views as they are already animated by the // recyclers ItemAnimator, so we exclude them to avoid a clash between the animations. mLayoutTransition.excludeChildren(mActionsCoordinator.getView(), /* exclude= */ true); + mLayoutTransition.excludeChildren( + mHeaderCoordinator.getCarouselView(), /* exclude= */ true); // do not animate the contents of the payment method section inside the section choice list, // since the animation is not required and causes a rendering crash. @@ -190,7 +192,11 @@ controller.addObserver(new EmptyBottomSheetObserver() { @Override public void onSheetStateChanged(int newState) { - maybeShowHeaderChip(); + // Note: recycler view updates while the bottom sheet is SCROLLING result in a + // BottomSheet assertion. + if (newState != BottomSheetController.SheetState.SCROLLING) { + maybeShowHeaderChips(); + } } @Override @@ -256,10 +262,9 @@ } private void setupAnimations(AssistantModel model, ViewGroup rootView) { - // Animate when the chip in the header changes. model.getHeaderModel().addObserver((source, propertyKey) -> { - if (propertyKey == AssistantHeaderModel.CHIP - || propertyKey == AssistantHeaderModel.CHIP_VISIBLE) { + if (propertyKey == AssistantHeaderModel.CHIPS_VISIBLE + || propertyKey == AssistantHeaderModel.CHIPS) { animateChildren(rootView); } }); @@ -295,12 +300,12 @@ TransitionManager.beginDelayedTransition(rootView, mLayoutTransition); } - private void maybeShowHeaderChip() { - boolean showChip = + private void maybeShowHeaderChips() { + boolean showChips = mBottomSheetController.getSheetState() == BottomSheetController.SheetState.PEEK && mPeekHeightCoordinator.getPeekMode() == AssistantPeekHeightCoordinator.PeekMode.HANDLE_HEADER; - mModel.getHeaderModel().set(AssistantHeaderModel.CHIP_VISIBLE, showChip); + mModel.getHeaderModel().set(AssistantHeaderModel.CHIPS_VISIBLE, showChips); } /** @@ -350,7 +355,7 @@ /** Set the peek mode. */ void setPeekMode(@AssistantPeekHeightCoordinator.PeekMode int peekMode) { mPeekHeightCoordinator.setPeekMode(peekMode); - maybeShowHeaderChip(); + maybeShowHeaderChips(); } /** Expand the bottom sheet. */
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java index 674fef83..dfc3750 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -18,7 +18,6 @@ import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantCarouselModel; import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChip; import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChip.Type; -import org.chromium.chrome.browser.autofill_assistant.header.AssistantHeaderModel; import org.chromium.chrome.browser.autofill_assistant.metrics.DropOutReason; import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.profiles.Profile; @@ -283,55 +282,56 @@ } /** - * Adds an action button to the chip list, which executes the action {@code actionIndex}. + * Creates an action button which executes the action {@code actionIndex}. */ @CalledByNative - private void addActionButton(List<AssistantChip> chips, int icon, String text, int actionIndex, + private AssistantChip createActionButton(int icon, String text, int actionIndex, boolean disabled, boolean sticky, String identifier) { - chips.add(new AssistantChip(AssistantChip.Type.BUTTON_HAIRLINE, icon, text, disabled, - sticky, identifier, () -> safeNativeOnUserActionSelected(actionIndex))); + return new AssistantChip(AssistantChip.Type.BUTTON_HAIRLINE, icon, text, disabled, sticky, + identifier, () -> safeNativeOnUserActionSelected(actionIndex)); } /** - * Adds a highlighted action button to the chip list, which executes the action {@code - * actionIndex}. + * Creates a highlighted action button which executes the action {@code actionIndex}. */ @CalledByNative - private void addHighlightedActionButton(List<AssistantChip> chips, int icon, String text, - int actionIndex, boolean disabled, boolean sticky, String identifier) { - chips.add(new AssistantChip(Type.BUTTON_FILLED_BLUE, icon, text, disabled, sticky, - identifier, () -> safeNativeOnUserActionSelected(actionIndex))); + private AssistantChip createHighlightedActionButton(int icon, String text, int actionIndex, + boolean disabled, boolean sticky, String identifier) { + return new AssistantChip(Type.BUTTON_FILLED_BLUE, icon, text, disabled, sticky, identifier, + () -> safeNativeOnUserActionSelected(actionIndex)); } /** - * Adds a cancel action button to the chip list. If the keyboard is currently shown, it - * dismisses the keyboard. Otherwise, it shows the snackbar and then executes - * {@code actionIndex}, or shuts down Autofill Assistant if {@code actionIndex} is {@code -1}. + * Creates a cancel action button. If the keyboard is currently shown, it dismisses the + * keyboard. Otherwise, it shows the snackbar and then executes {@code actionIndex}, or shuts + * down Autofill Assistant if {@code actionIndex} is {@code -1}. */ @CalledByNative - private void addCancelButton(List<AssistantChip> chips, int icon, String text, int actionIndex, + private AssistantChip createCancelButton(int icon, String text, int actionIndex, boolean disabled, boolean sticky, String identifier) { - chips.add(new AssistantChip(AssistantChip.Type.BUTTON_HAIRLINE, icon, text, disabled, - sticky, identifier, () -> safeNativeOnCancelButtonClicked(actionIndex))); + return new AssistantChip(AssistantChip.Type.BUTTON_HAIRLINE, icon, text, disabled, sticky, + identifier, () -> safeNativeOnCancelButtonClicked(actionIndex)); } /** * Adds a close action button to the chip list, which shuts down Autofill Assistant. */ @CalledByNative - private void addCloseButton(List<AssistantChip> chips, int icon, String text, boolean disabled, - boolean sticky, String identifier) { - chips.add(new AssistantChip(AssistantChip.Type.BUTTON_HAIRLINE, icon, text, disabled, - sticky, identifier, this::safeNativeOnCloseButtonClicked)); + private AssistantChip createCloseButton( + int icon, String text, boolean disabled, boolean sticky, String identifier) { + return new AssistantChip(AssistantChip.Type.BUTTON_HAIRLINE, icon, text, disabled, sticky, + identifier, this::safeNativeOnCloseButtonClicked); + } + + @CalledByNative + private static void appendChipToList(List<AssistantChip> chips, AssistantChip chip) { + chips.add(chip); } @CalledByNative private void setActions(List<AssistantChip> chips) { - // TODO(b/144075373): Move this to AssistantCarouselModel and AssistantHeaderModel. Move - // header chip logic to native. - AssistantCarouselModel model = getModel().getActionsModel(); - model.setChips(chips); - setHeaderChip(chips); + // TODO(b/144075373): Move this to AssistantCarouselModel. + getModel().getActionsModel().setChips(chips); } @CalledByNative @@ -358,19 +358,6 @@ model.setChips(newChips); } - private void setHeaderChip(List<AssistantChip> chips) { - // The header chip is the first sticky chip found in the actions. - AssistantChip headerChip = null; - for (AssistantChip chip : chips) { - if (chip.isSticky()) { - headerChip = chip; - break; - } - } - - getModel().getHeaderModel().set(AssistantHeaderModel.CHIP, headerChip); - } - @CalledByNative private void setViewportMode(@AssistantViewportMode int mode) { mCoordinator.getBottomBarCoordinator().setViewportMode(mode);
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantChipAdapter.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantChipAdapter.java index 4ce5656..f449346 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantChipAdapter.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/carousel/AssistantChipAdapter.java
@@ -22,7 +22,7 @@ public class AssistantChipAdapter extends RecyclerView.Adapter<AssistantChipViewHolder> { private final List<AssistantChip> mChips = new ArrayList<>(); - void setChips(List<AssistantChip> chips) { + public void setChips(List<AssistantChip> chips) { DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtil.Callback() { @Override public int getOldListSize() {
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderCoordinator.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderCoordinator.java index 7653718e..7f97029f 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderCoordinator.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderCoordinator.java
@@ -5,13 +5,19 @@ package org.chromium.chrome.browser.autofill_assistant.header; import android.content.Context; +import android.graphics.Rect; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiController; +import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChipAdapter; import org.chromium.chrome.browser.autofill_assistant.header.AssistantHeaderViewBinder.ViewHolder; import org.chromium.chrome.browser.signin.DisplayableProfileData; import org.chromium.chrome.browser.signin.IdentityServicesProvider; @@ -32,6 +38,7 @@ private final ImageView mProfileView; private final String mSignedInAccountName; private final ViewHolder mViewHolder; + private final RecyclerView mChipsContainer; public AssistantHeaderCoordinator(Context context, AssistantHeaderModel model) { // Create the poodle and insert it before the status message. We have to create a view @@ -56,8 +63,52 @@ identityManager.getPrimaryAccountInfo(ConsentLevel.SYNC)); setupProfileImage(); + mChipsContainer = new RecyclerView(context); + final int innerChipSpacing = context.getResources().getDimensionPixelSize( + R.dimen.autofill_assistant_actions_spacing); + mChipsContainer.addItemDecoration(new RecyclerView.ItemDecoration() { + @Override + public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, + @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { + outRect.top = 0; + outRect.bottom = 0; + + if (state.getItemCount() <= 1) { + return; + } + + // If old position != NO_POSITION, it means the carousel is being animated and we + // should use that position in our logic. + int position = parent.getChildAdapterPosition(view); + RecyclerView.ViewHolder viewHolder = parent.getChildViewHolder(view); + if (viewHolder != null && viewHolder.getOldPosition() != RecyclerView.NO_POSITION) { + position = viewHolder.getOldPosition(); + } + + if (position == RecyclerView.NO_POSITION) { + return; + } + + outRect.left = position == 0 ? 0 : innerChipSpacing; + outRect.right = 0; + } + }); + + AssistantChipAdapter chipAdapter = new AssistantChipAdapter(); + mChipsContainer.setAdapter(chipAdapter); + LinearLayoutManager layoutManager = new LinearLayoutManager(context); + layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); + mChipsContainer.setLayoutManager(layoutManager); + mView.setPadding(mChipsContainer.getPaddingLeft(), mChipsContainer.getPaddingTop(), + context.getResources().getDimensionPixelSize( + R.dimen.autofill_assistant_profile_icon_padding), + mChipsContainer.getPaddingBottom()); + ViewGroup topContainer = mView.findViewById(R.id.header_top_container); + topContainer.addView(mChipsContainer); + // Bind view and mediator through the model. - mViewHolder = new AssistantHeaderViewBinder.ViewHolder(context, mView, poodle); + mViewHolder = + new AssistantHeaderViewBinder.ViewHolder(context, mView, poodle, mChipsContainer); AssistantHeaderViewBinder viewBinder = new AssistantHeaderViewBinder(); PropertyModelChangeProcessor.create(model, mViewHolder, viewBinder); @@ -77,6 +128,11 @@ return mView; } + /** Returns the view containing the chips. */ + public View getCarouselView() { + return mChipsContainer; + } + /** * Cleanup resources when this goes out of scope. */
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderModel.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderModel.java index 1fc9fc8..7c86cc3 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderModel.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderModel.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.autofill_assistant.header; +import android.support.annotation.VisibleForTesting; + import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChip; @@ -18,6 +20,9 @@ */ @JNINamespace("autofill_assistant") public class AssistantHeaderModel extends PropertyModel { + public static final WritableObjectPropertyKey<List<AssistantChip>> CHIPS = + new WritableObjectPropertyKey<>(); + public static final WritableObjectPropertyKey<String> STATUS_MESSAGE = new WritableObjectPropertyKey<>(); @@ -45,10 +50,7 @@ public static final WritableObjectPropertyKey<Runnable> FEEDBACK_BUTTON_CALLBACK = new WritableObjectPropertyKey<>(); - public static final WritableObjectPropertyKey<AssistantChip> CHIP = - new WritableObjectPropertyKey<>(); - - public static final WritableBooleanPropertyKey CHIP_VISIBLE = new WritableBooleanPropertyKey(); + public static final WritableBooleanPropertyKey CHIPS_VISIBLE = new WritableBooleanPropertyKey(); public static final WritableBooleanPropertyKey DISABLE_ANIMATIONS_FOR_TESTING = new WritableBooleanPropertyKey(); @@ -56,7 +58,8 @@ public AssistantHeaderModel() { super(STATUS_MESSAGE, BUBBLE_MESSAGE, PROGRESS, PROGRESS_ACTIVE_STEP, PROGRESS_BAR_ERROR, PROGRESS_VISIBLE, USE_STEP_PROGRESS_BAR, STEP_PROGRESS_BAR_ICONS, SPIN_POODLE, - FEEDBACK_BUTTON_CALLBACK, CHIP, CHIP_VISIBLE, DISABLE_ANIMATIONS_FOR_TESTING); + FEEDBACK_BUTTON_CALLBACK, CHIPS, CHIPS_VISIBLE, DISABLE_ANIMATIONS_FOR_TESTING); + set(CHIPS, new ArrayList<>()); } @CalledByNative @@ -127,4 +130,16 @@ private void setDisableAnimations(boolean disableAnimations) { set(DISABLE_ANIMATIONS_FOR_TESTING, disableAnimations); } + + @CalledByNative + @VisibleForTesting + public void setChips(List<AssistantChip> chips) { + // Move last chip (cancel) to first position. For legacy reasons, native builds this list + // such that the cancel chip is last, but the regular carousel will show it in the left-most + // position and the header should mirror this. + if (chips.size() > 1) { + chips.add(0, chips.remove(chips.size() - 1)); + } + set(CHIPS, chips); + } }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java index 62ea30e80..7afb8db 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/header/AssistantHeaderViewBinder.java
@@ -11,11 +11,12 @@ import android.widget.TextView; import androidx.annotation.Nullable; +import androidx.recyclerview.widget.DefaultItemAnimator; +import androidx.recyclerview.widget.RecyclerView; import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.browser.autofill_assistant.AssistantTextUtils; -import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChip; -import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChipViewHolder; +import org.chromium.chrome.browser.autofill_assistant.carousel.AssistantChipAdapter; import org.chromium.chrome.browser.settings.SettingsLauncher; import org.chromium.chrome.browser.settings.SettingsLauncherImpl; import org.chromium.chrome.browser.sync.settings.SyncAndServicesSettings; @@ -48,12 +49,12 @@ final AssistantStepProgressBar mStepProgressBar; final View mProfileIconView; final PopupMenu mProfileIconMenu; - @Nullable - AssistantChipViewHolder mChip; + final RecyclerView mChipsContainer; @Nullable TextBubble mTextBubble; - ViewHolder(Context context, ViewGroup headerView, AnimatedPoodle poodle) { + ViewHolder(Context context, ViewGroup headerView, AnimatedPoodle poodle, + RecyclerView chipsContainer) { mContext = context; mPoodle = poodle; mHeader = headerView; @@ -65,6 +66,7 @@ mProfileIconMenu = new PopupMenu(context, mProfileIconView); mProfileIconMenu.inflate(R.menu.profile_icon_menu); mProfileIconView.setOnClickListener(unusedView -> mProfileIconMenu.show()); + mChipsContainer = chipsContainer; } void disableAnimations(boolean disable) { @@ -73,6 +75,8 @@ // Hiding the animated poodle seems to be the easiest way to disable its animation since // {@link LogoView#setAnimationEnabled(boolean)} is private. mPoodle.getView().setVisibility(View.INVISIBLE); + ((DefaultItemAnimator) mChipsContainer.getItemAnimator()) + .setSupportsChangeAnimations(!disable); } void updateProgressBarVisibility(boolean visible, boolean useStepProgressBar) { @@ -113,11 +117,13 @@ view.mPoodle.setSpinEnabled(model.get(AssistantHeaderModel.SPIN_POODLE)); } else if (AssistantHeaderModel.FEEDBACK_BUTTON_CALLBACK == propertyKey) { setProfileMenuListener(view, model.get(AssistantHeaderModel.FEEDBACK_BUTTON_CALLBACK)); - } else if (AssistantHeaderModel.CHIP == propertyKey) { - bindChip(view, model.get(AssistantHeaderModel.CHIP)); - maybeShowChip(model, view); - } else if (AssistantHeaderModel.CHIP_VISIBLE == propertyKey) { - maybeShowChip(model, view); + } else if (AssistantHeaderModel.CHIPS == propertyKey) { + view.mChipsContainer.invalidateItemDecorations(); + ((AssistantChipAdapter) view.mChipsContainer.getAdapter()) + .setChips(model.get(AssistantHeaderModel.CHIPS)); + maybeShowChips(model, view); + } else if (AssistantHeaderModel.CHIPS_VISIBLE == propertyKey) { + maybeShowChips(model, view); } else if (AssistantHeaderModel.BUBBLE_MESSAGE == propertyKey) { showOrDismissBubble(model, view); } else if (AssistantHeaderModel.DISABLE_ANIMATIONS_FOR_TESTING == propertyKey) { @@ -127,45 +133,18 @@ } } - private void maybeShowChip(AssistantHeaderModel model, ViewHolder view) { - if (model.get(AssistantHeaderModel.CHIP_VISIBLE) - && model.get(AssistantHeaderModel.CHIP) != null) { - view.mChip.getView().setVisibility(View.VISIBLE); + private void maybeShowChips(AssistantHeaderModel model, ViewHolder view) { + if (model.get(AssistantHeaderModel.CHIPS_VISIBLE) + && !model.get(AssistantHeaderModel.CHIPS).isEmpty()) { + view.mChipsContainer.setVisibility(View.VISIBLE); view.mProfileIconView.setVisibility(View.GONE); } else { - if (view.mChip != null) { - view.mChip.getView().setVisibility(View.GONE); - } + view.mChipsContainer.setVisibility(View.GONE); view.mProfileIconView.setVisibility(View.VISIBLE); } } - private void bindChip(ViewHolder view, @Nullable AssistantChip chip) { - if (chip == null) { - return; - } - - int viewType = AssistantChipViewHolder.getViewType(chip); - - // If there is already a chip in the header but with incompatible type, remove it. - ViewGroup parent = (ViewGroup) view.mStatusMessage.getParent(); - if (view.mChip != null && view.mChip.getType() != viewType) { - parent.removeView(view.mChip.getView()); - view.mChip = null; - } - - // If there is no chip already in the header, create one and add it at the end of the - // header. - if (view.mChip == null) { - view.mChip = AssistantChipViewHolder.create(view.mHeader, viewType); - parent.addView(view.mChip.getView()); - } - - // Bind the chip to the view. - view.mChip.bind(chip); - } - private void setProfileMenuListener(ViewHolder view, @Nullable Runnable feedbackCallback) { view.mProfileIconMenu.setOnMenuItemClickListener(item -> { int itemId = item.getItemId();
diff --git a/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_my.xtb b/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_my.xtb index bf47ce4..ab9452c 100644 --- a/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_my.xtb +++ b/chrome/android/features/autofill_assistant/java/strings/translations/android_chrome_autofill_assistant_strings_my.xtb
@@ -19,7 +19,7 @@ <translation id="6785872064505734160">Chrome ရှိ Google Assistant က ဝဘ်ဆိုက်များတွင် သင့်အတွက် အလိုအလျောက် ဖြည့်ပေးနိုင်သည်</translation> <translation id="6973932557599545801">ကျွန်ုပ် ကူညီ၍မရပါ၊ ကိုယ်တိုင် ဆက်လုပ်ပါ။</translation> <translation id="7135664311366978968">အကြိမ်အနည်းငယ် တို့ရုံဖြင့်\nရုပ်ရှင်လက်မှတ်များ ဝယ်နိုင်သည်</translation> -<translation id="7455021968451468078">Google Assistant အား သင့်စကားဝှက်ကို \nကူးပြောင်းခွင့်ပေးပါ</translation> +<translation id="7455021968451468078">Google Assistant အား သင့်စကားဝှက်ကို \nပြောင်းခွင့်ပေးပါ</translation> <translation id="7658239707568436148">မလုပ်တော့</translation> <translation id="7953600313732929223">ဝဘ်ဆိုက်များတွင်\nအသံဖြင့်ခိုင်းစေချက်များ စမ်းကြည့်ပါ</translation> <translation id="8253702004019660079">Chrome ရှိ Google Assistant။</translation>
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBackButtonIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBackButtonIntegrationTest.java index 2c0363c..44580c9 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBackButtonIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBackButtonIntegrationTest.java
@@ -167,14 +167,18 @@ Espresso.pressBack(); waitUntilViewMatchesCondition(withText(R.string.undo), isCompletelyDisplayed()); onView(withId(R.id.autofill_assistant)).check(doesNotExist()); - assertThat(mTestRule.getActivity().getActivityTab().getUrl().getSpec(), + + assertThat( + ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()).getSpec(), is(getURL(TEST_PAGE_B))); // Third press on back button navigates back. Espresso.pressBack(); - waitUntil(() - -> mTestRule.getActivity().getActivityTab().getUrl().getSpec().equals( - getURL(TEST_PAGE_A))); + waitUntil( + () + -> ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()) + .getSpec() + .equals(getURL(TEST_PAGE_A))); } @Test @@ -242,7 +246,8 @@ Espresso.pressBack(); waitUntilViewMatchesCondition(withText("Back button pressed"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Undo"), isDisplayed()); - assertThat(mTestRule.getActivity().getActivityTab().getUrl().getSpec(), + assertThat( + ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()).getSpec(), is(getURL(TEST_PAGE_B))); // Undo should get back to the prompt state. @@ -253,15 +258,18 @@ Espresso.pressBack(); waitUntilViewMatchesCondition(withText("Back button pressed"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Undo"), isDisplayed()); - assertThat(mTestRule.getActivity().getActivityTab().getUrl().getSpec(), + assertThat( + ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()).getSpec(), is(getURL(TEST_PAGE_B))); // Third press on back button destroys Autofill UI and navigates back. Espresso.pressBack(); waitUntilViewAssertionTrue(withId(R.id.autofill_assistant), doesNotExist(), 3000L); - waitUntil(() - -> mTestRule.getActivity().getActivityTab().getUrl().getSpec().equals( - getURL(TEST_PAGE_A))); + waitUntil( + () + -> ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()) + .getSpec() + .equals(getURL(TEST_PAGE_A))); } @Test @@ -295,9 +303,11 @@ withId(R.id.autofill_assistant), doesNotExist(), DEFAULT_MAX_TIME_TO_POLL); onView(withText("Shutdown")).check(doesNotExist()); onView(withText(R.string.undo)).check(doesNotExist()); - waitUntil(() - -> mTestRule.getActivity().getActivityTab().getUrl().getSpec().equals( - getURL(TEST_PAGE_A))); + waitUntil( + () + -> ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()) + .getSpec() + .equals(getURL(TEST_PAGE_A))); } @Test @@ -355,7 +365,8 @@ Espresso.pressBack(); waitUntilViewMatchesCondition(withText("Back button pressed"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Undo"), isDisplayed()); - assertThat(mTestRule.getActivity().getActivityTab().getUrl().getSpec(), + assertThat( + ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()).getSpec(), is(getURL(TEST_PAGE_B))); // Navigation destroys the Autofill Assistant UI. @@ -402,9 +413,11 @@ // Second press on back button navigates back, without removing the Autofill Assistannt UI. Espresso.pressBack(); - waitUntil(() - -> mTestRule.getActivity().getActivityTab().getUrl().getSpec().equals( - getURL(TEST_PAGE_A))); + waitUntil( + () + -> ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()) + .getSpec() + .equals(getURL(TEST_PAGE_A))); onView(withId(R.id.autofill_assistant)).check(matches(isDisplayed())); onView(withId(R.id.status_message)).check(matches(withText("Prompt"))); }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java index 9a19708..cad8a5de 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java
@@ -7,6 +7,7 @@ import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.assertion.PositionAssertions.isRightOf; +import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; @@ -52,6 +53,9 @@ import org.chromium.components.browser_ui.widget.MaterialProgressBar; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import java.util.ArrayList; +import java.util.List; + /** * Tests for the Autofill Assistant header. */ @@ -206,15 +210,17 @@ chipText, /* disabled= */ false, /* sticky= */ false, "", () -> {}); // Set the header chip without displaying it. - TestThreadUtils.runOnUiThreadBlocking(() -> model.set(AssistantHeaderModel.CHIP, chip)); + List<AssistantChip> chips = new ArrayList<>(); + chips.add(chip); + TestThreadUtils.runOnUiThreadBlocking(() -> model.setChips(chips)); Matcher<View> chipMatcher = allOf(isDescendantOfA(is(coordinator.getView())), withText(chipText)); - onView(chipMatcher).check(matches(not(isDisplayed()))); + onView(chipMatcher).check(doesNotExist()); // Show the chip TestThreadUtils.runOnUiThreadBlocking( - () -> model.set(AssistantHeaderModel.CHIP_VISIBLE, true)); + () -> model.set(AssistantHeaderModel.CHIPS_VISIBLE, true)); onView(chipMatcher) .check(matches(isDisplayed())) .check(isRightOf(withId(R.id.status_message)));
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantNavigationIntegrationTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantNavigationIntegrationTest.java index c58469e..f8c6689 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantNavigationIntegrationTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantNavigationIntegrationTest.java
@@ -123,9 +123,11 @@ onView(withId(org.chromium.chrome.R.id.url_bar)) .perform(click(), typeText(getURL(TEST_PAGE_B)), pressImeActionButton()); waitUntilViewMatchesCondition(withText(containsString("Sorry")), isCompletelyDisplayed()); - waitUntil(() - -> mTestRule.getActivity().getActivityTab().getUrl().getSpec().equals( - getURL(TEST_PAGE_B))); + waitUntil( + () + -> ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()) + .getSpec() + .equals(getURL(TEST_PAGE_B))); } @Test @@ -157,9 +159,11 @@ startAutofillAssistantOnTab(TEST_PAGE_A); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); - waitUntil(() - -> mTestRule.getActivity().getActivityTab().getUrl().getSpec().equals( - getURL(TEST_PAGE_B))); + waitUntil( + () + -> ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()) + .getSpec() + .equals(getURL(TEST_PAGE_B))); } @Test @@ -192,9 +196,11 @@ startAutofillAssistantOnTab(TEST_PAGE_A); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); - waitUntil(() - -> mTestRule.getActivity().getActivityTab().getUrl().getSpec().equals( - getURL(TEST_PAGE_B))); + waitUntil( + () + -> ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()) + .getSpec() + .equals(getURL(TEST_PAGE_B))); } @Test @@ -257,21 +263,28 @@ onView(withText("Navigate")).perform(click()); waitUntilViewMatchesCondition(withText("Page A"), isCompletelyDisplayed()); - waitUntil(() - -> mTestRule.getActivity().getActivityTab().getUrl().getSpec().equals( - getURL(TEST_PAGE_A))); + + waitUntil( + () + -> ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()) + .getSpec() + .equals(getURL(TEST_PAGE_A))); onView(withText("Go back")).perform(click()); waitUntilViewMatchesCondition(withText("Page B"), isCompletelyDisplayed()); - waitUntil(() - -> mTestRule.getActivity().getActivityTab().getUrl().getSpec().equals( - getURL(TEST_PAGE_B))); + waitUntil( + () + -> ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()) + .getSpec() + .equals(getURL(TEST_PAGE_B))); onView(withText("Go forward")).perform(click()); waitUntilViewMatchesCondition(withText("Page A"), isCompletelyDisplayed()); - waitUntil(() - -> mTestRule.getActivity().getActivityTab().getUrl().getSpec().equals( - getURL(TEST_PAGE_A))); + waitUntil( + () + -> ChromeTabUtils.getUrlOnUiThread(mTestRule.getActivity().getActivityTab()) + .getSpec() + .equals(getURL(TEST_PAGE_A))); } @Test
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java index 65cb0ee..278391e 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -1572,7 +1572,7 @@ .check(waitForView(allOf(withText(expectedTerm), isDisplayed()))); // Click the chip and check the tab navigates back to the search result page. - assertEquals(mUrl, currentTab.getUrlString()); + assertEquals(mUrl, ChromeTabUtils.getUrlStringOnUiThread(currentTab)); OverviewModeBehaviorWatcher hideWatcher = TabUiTestHelper.createOverviewHideWatcher(cta); onView(withId(R.id.search_button)) .check(waitForView(allOf(withText(expectedTerm), isDisplayed())));
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTab.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTab.java index dafb35f..701f2fc 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTab.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTab.java
@@ -174,7 +174,7 @@ * @return The URL */ public String getUrl() { - if (mTab != null && mTab.get() != null) { + if (mTab != null && mTab.get() != null && mTab.get().isInitialized()) { return mTab.get().getUrlString(); } assert mTabId != null;
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java index 8fb296c9..f08fa39b 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
@@ -460,7 +460,7 @@ private static void verifyAllTabsHaveUrl(TabModel tabModel, String url) { for (int i = 0; i < tabModel.getCount(); i++) { - assertEquals(url, tabModel.getTabAt(i).getUrlString()); + assertEquals(url, ChromeTabUtils.getUrlStringOnUiThread(tabModel.getTabAt(i))); } }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTabUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTabUnitTest.java index 17428bf..97ad1af 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTabUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/pseudotab/PseudoTabUnitTest.java
@@ -447,4 +447,15 @@ // UnsupportedOperationException Assert.assertEquals("", pseudoTab.getTitle()); } + + @Test + public void testTabDestroyedUrl() { + Tab tab = new MockTab(TAB4_ID, false); + PseudoTab pseudoTab = PseudoTab.fromTab(tab); + tab.destroy(); + // Url was not set. Without the isInitialized() check, + // pseudoTab.getUrl() would crash here with + // UnsupportedOperationException + Assert.assertEquals("", pseudoTab.getUrl()); + } }
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java index 6671abd5..16f289f 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
@@ -230,12 +230,9 @@ mActionOptions = actionOptions; Resources resources = mActivity.getResources(); - mDefaultMargin = resources.getDimensionPixelSize(mV2Enabled - ? R.dimen.content_suggestions_card_modern_margin_v2 - : R.dimen.content_suggestions_card_modern_margin); - mWideMargin = resources.getDimensionPixelSize(mV2Enabled - ? R.dimen.ntp_wide_card_lateral_margins_v2 - : R.dimen.ntp_wide_card_lateral_margins); + mDefaultMargin = + resources.getDimensionPixelSize(R.dimen.content_suggestions_card_modern_margin); + mWideMargin = resources.getDimensionPixelSize(R.dimen.ntp_wide_card_lateral_margins); mRootView = new RootView(mActivity); mRootView.setPadding(0, resources.getDimensionPixelOffset(R.dimen.tab_strip_height), 0, 0);
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java index 17d9eb1..ac1370a 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java
@@ -42,8 +42,8 @@ import org.chromium.chrome.browser.xsurface.FeedActionsHandler; import org.chromium.chrome.browser.xsurface.HybridListRenderer; import org.chromium.chrome.browser.xsurface.ProcessScope; +import org.chromium.chrome.browser.xsurface.ProcessScopeDependencyProvider; import org.chromium.chrome.browser.xsurface.SurfaceActionsHandler; -import org.chromium.chrome.browser.xsurface.SurfaceDependencyProvider; import org.chromium.chrome.browser.xsurface.SurfaceScope; import org.chromium.chrome.browser.xsurface.SurfaceScopeDependencyProvider; import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent; @@ -116,7 +116,7 @@ public static ProcessScope xSurfaceProcessScope() { if (sXSurfaceProcessScope == null) { sXSurfaceProcessScope = AppHooks.get().getExternalSurfaceProcessScope( - new FeedSurfaceDependencyProvider()); + new FeedProcessScopeDependencyProvider()); } return sXSurfaceProcessScope; } @@ -201,8 +201,9 @@ * * TODO(rogerm): Find a more global home for this. */ - private static class FeedSurfaceDependencyProvider implements SurfaceDependencyProvider { - FeedSurfaceDependencyProvider() {} + private static class FeedProcessScopeDependencyProvider + implements ProcessScopeDependencyProvider { + FeedProcessScopeDependencyProvider() {} @Override public Context getContext() { @@ -342,12 +343,14 @@ * Performs all necessary cleanups. */ public void destroy() { + if (mOpened) { + surfaceClosed(); + } if (mSliceViewTracker != null) { mSliceViewTracker.destroy(); mSliceViewTracker = null; } mHybridListRenderer.unbind(); - surfaceClosed(); } /** @@ -787,6 +790,7 @@ if (sStartupCalled) { FeedStreamSurfaceJni.get().surfaceOpened( mNativeFeedStreamSurface, FeedStreamSurface.this); + mHybridListRenderer.onSurfaceOpened(); } } @@ -794,6 +798,13 @@ * Informs that the surface is closed. */ public void surfaceClosed() { + // Let the hybrid list renderer know that the surface has closed, so it doesn't + // interpret the removal of contents as related to actions otherwise initiated by + // the user. + if (sStartupCalled) { + mHybridListRenderer.onSurfaceClosed(); + } + int feedCount = mContentManager.getItemCount() - mHeaderCount; if (feedCount > 0) { mContentManager.removeContents(mHeaderCount, feedCount);
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java index 0dce68d5..79722b6 100644 --- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java +++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java
@@ -291,7 +291,7 @@ mIsCachePopulatedInAccountManagerFacade = true; TestThreadUtils.runOnUiThreadBlocking(mTab::reload); - ChromeTabUtils.waitForTabPageLoaded(mTab, mTab.getUrlString()); + ChromeTabUtils.waitForTabPageLoaded(mTab, ChromeTabUtils.getUrlStringOnUiThread(mTab)); // Check that the sign-in promo is displayed this time. onView(instanceOf(RecyclerView.class))
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/DebugLoggerTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/DebugLoggerTest.java index 0399c59..8af68ec 100644 --- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/DebugLoggerTest.java +++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/DebugLoggerTest.java
@@ -17,7 +17,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; import org.robolectric.Robolectric; import org.robolectric.annotation.Config; @@ -35,9 +34,6 @@ private static final String ERROR_TEXT_2 = "Exotic particle containment breach."; private static final String WARNING_TEXT = "Noncompliant meson entanglement."; - @Mock - private FrameContext mFrameContext; - private Context mContext; private DebugLogger mDebugLogger;
diff --git a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/TextElementAdapterTest.java b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/TextElementAdapterTest.java index 0863c60..8fd5bd5f 100644 --- a/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/TextElementAdapterTest.java +++ b/chrome/android/feed/core/javatests/src/org/chromium/chrome/browser/feed/library/piet/TextElementAdapterTest.java
@@ -45,7 +45,6 @@ import org.chromium.chrome.browser.feed.library.piet.DebugLogger.MessageType; import org.chromium.chrome.browser.feed.library.piet.TextElementAdapter.TextElementKey; import org.chromium.chrome.browser.feed.library.piet.host.AssetProvider; -import org.chromium.chrome.browser.feed.library.piet.host.TypefaceProvider; import org.chromium.chrome.browser.feed.library.piet.host.TypefaceProvider.GoogleSansTypeface; import org.chromium.components.feed.core.proto.ui.piet.BindingRefsProto.StyleBindingRef; import org.chromium.components.feed.core.proto.ui.piet.ElementsProto.CustomElement; @@ -75,8 +74,6 @@ private HostProviders mMockHostProviders; @Mock private AssetProvider mMockAssetProvider; - @Mock - private TypefaceProvider mMockTypefaceProvider; private AdapterParameters mAdapterParameters;
diff --git a/chrome/android/feed/merging.md b/chrome/android/feed/merging.md index 006f657f..d13d689 100644 --- a/chrome/android/feed/merging.md +++ b/chrome/android/feed/merging.md
@@ -8,4 +8,4 @@ The hash below represents the last commit from that repo that was reviewed for the potential need to merge here. -Last checked commit ID: 5c177dff913851f5adaf4c536c67154c4c1041a7 +Last checked commit ID: c80d3c49fa92f00c05130106b29d5b49a735ac97
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 8d885ae..b3669e0 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -354,11 +354,9 @@ (matches toolbar_height_no_shadow). --> <dimen name="ntp_search_box_bounds_vertical_inset_modern">-4dp</dimen> <dimen name="ntp_wide_card_lateral_margins">48dp</dimen> - <dimen name="ntp_wide_card_lateral_margins_v2">36dp</dimen> <dimen name="snippets_article_header_height">40dp</dimen> - <dimen name="content_suggestions_card_modern_margin">12dp</dimen> - <dimen name="content_suggestions_card_modern_margin_v2">0dp</dimen> <!-- This is in sp because we want the icon to scale with the TextView it sits alongside. --> + <dimen name="content_suggestions_card_modern_margin">12dp</dimen> <dimen name="md_incognito_ntp_line_spacing">6sp</dimen> <dimen name="md_incognito_ntp_padding_left">16dp</dimen> <dimen name="cryptid_height_in_logo_wrapper">60dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java index 2b1d838..955b3f3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
@@ -42,7 +42,6 @@ import org.chromium.chrome.browser.webapps.GooglePlayWebApkInstallDelegate; import org.chromium.chrome.browser.xsurface.ProcessScope; import org.chromium.chrome.browser.xsurface.ProcessScopeDependencyProvider; -import org.chromium.chrome.browser.xsurface.SurfaceDependencyProvider; import org.chromium.components.browser_ui.widget.FeatureHighlightProvider; import org.chromium.components.external_intents.AuthenticatorNavigationInterceptor; import org.chromium.components.signin.AccountManagerDelegate; @@ -350,19 +349,6 @@ } /** - * Returns a new {@link SurfaceRenderer} if the xsurface implementation is included in the - * apk. Otherwise null is returned. - * - * This API is deprecated, and will be removed after safely renaming SurfaceDependencyProvider - * to ProcessScopeDependencyProvider. - */ - @Deprecated - public @Nullable ProcessScope getExternalSurfaceProcessScope( - SurfaceDependencyProvider dependencies) { - return getExternalSurfaceProcessScope((ProcessScopeDependencyProvider) dependencies); - } - - /** * Returns the URL to the WebAPK creation/update server. */ public String getWebApkServerUrl() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java index 863f3d1a..2de2624 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
@@ -910,26 +910,14 @@ // Ignore all intents that specify a Chrome internal scheme if they did not come from // a trustworthy source. String scheme = getSanitizedUrlScheme(url); - if (!isInternal && scheme != null - && (intent.hasCategory(Intent.CATEGORY_BROWSABLE) - || intent.hasCategory(Intent.CATEGORY_DEFAULT) - || intent.getCategories() == null)) { - String lowerCaseScheme = scheme.toLowerCase(Locale.US); - if (UrlConstants.CHROME_SCHEME.equals(lowerCaseScheme) - || UrlConstants.CHROME_NATIVE_SCHEME.equals(lowerCaseScheme) - || ContentUrlConstants.ABOUT_SCHEME.equals(lowerCaseScheme)) { - // Allow certain "safe" internal URLs to be launched by external - // applications. - String lowerCaseUrl = url.toLowerCase(Locale.US); - if (ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL.equals(lowerCaseUrl) - || ContentUrlConstants.ABOUT_BLANK_URL.equals(lowerCaseUrl) - || UrlConstants.CHROME_DINO_URL.equals(lowerCaseUrl)) { - return false; - } - + recordFirstPartyToInternalScheme(scheme, url, intent, isInternal, isFromChrome); + if (!isInternal) { + if (intentHasUnsafeInternalScheme(scheme, url, intent)) { Log.w(TAG, "Ignoring internal Chrome URL from untrustworthy source."); return true; } + + return false; } // We must check for screen state at this point. @@ -945,6 +933,30 @@ } } + private static boolean intentHasUnsafeInternalScheme(String scheme, String url, Intent intent) { + if (scheme != null + && (intent.hasCategory(Intent.CATEGORY_BROWSABLE) + || intent.hasCategory(Intent.CATEGORY_DEFAULT) + || intent.getCategories() == null)) { + String lowerCaseScheme = scheme.toLowerCase(Locale.US); + if (UrlConstants.CHROME_SCHEME.equals(lowerCaseScheme) + || UrlConstants.CHROME_NATIVE_SCHEME.equals(lowerCaseScheme) + || ContentUrlConstants.ABOUT_SCHEME.equals(lowerCaseScheme)) { + // Allow certain "safe" internal URLs to be launched by external + // applications. + String lowerCaseUrl = url.toLowerCase(Locale.US); + if (ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL.equals(lowerCaseUrl) + || ContentUrlConstants.ABOUT_BLANK_URL.equals(lowerCaseUrl) + || UrlConstants.CHROME_DINO_URL.equals(lowerCaseUrl)) { + return false; + } + + return true; + } + } + return false; + } + @VisibleForTesting static boolean intentHasValidUrl(Intent intent) { String url = extractUrlFromIntent(intent); @@ -1381,6 +1393,18 @@ return newIntent; } + /** + * Records whether the intent comes from a non-Chrome first party and contains a Chrome internal + * scheme. This is so we can determine whether we can cut the feature. + */ + private static void recordFirstPartyToInternalScheme( + String scheme, String url, Intent intent, boolean isInternal, boolean isChrome) { + if (!isInternal || isChrome) return; + + RecordHistogram.recordBooleanHistogram("MobileIntent.FirstPartyToInternalScheme", + intentHasUnsafeInternalScheme(scheme, url, intent)); + } + @NativeMethods interface Natives { boolean isCorsSafelistedHeader(String name, String value);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelListItem.java b/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelListItem.java index aee5895..abc29f7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelListItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/accessibility_tab_switcher/AccessibilityTabModelListItem.java
@@ -304,7 +304,7 @@ private void updateTabText() { String title = null; String url = null; - if (mTab != null) { + if (mTab != null && mTab.isInitialized()) { title = mTab.getTitle(); url = mTab.getUrlString(); if (TextUtils.isEmpty(title)) title = url;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java index ff26cc9..a5caeaa9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
@@ -295,7 +295,11 @@ // Only display the Enter VR button if VR Shell Dev environment is enabled. menu.findItem(R.id.enter_vr_id).setVisible(shouldShowEnterVr()); - menu.findItem(R.id.managed_by_menu_id).setVisible(shouldShowManagedByMenuItem(currentTab)); + MenuItem managedByMenuItem = menu.findItem(R.id.managed_by_menu_id); + managedByMenuItem.setVisible(shouldShowManagedByMenuItem(currentTab)); + // TODO(https://crbug.com/1092175): Enable "managed by" menu item after chrome://management + // page is added. + managedByMenuItem.setEnabled(false); } private void prepareCommonMenuItems(Menu menu, @MenuGroup int menuGroup, boolean isIncognito) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/ManagedByMenuItemViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/ManagedByMenuItemViewBinder.java index 8bc81bec..0165266 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/ManagedByMenuItemViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/ManagedByMenuItemViewBinder.java
@@ -37,8 +37,6 @@ if (convertView == null) { convertView = inflater.inflate(R.layout.managed_by_menu_item, parent, false); } - - convertView.setEnabled(false); convertView.setFocusable(false); return convertView;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java index 3378bc8..e1545c8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java
@@ -34,7 +34,8 @@ /** * The type of selection made by the user. */ - @IntDef({SelectionType.UNDETERMINED, SelectionType.TAP, SelectionType.LONG_PRESS}) + @IntDef({SelectionType.UNDETERMINED, SelectionType.TAP, SelectionType.LONG_PRESS, + SelectionType.RESOLVING_LONG_PRESS}) @Retention(RetentionPolicy.SOURCE) public @interface SelectionType { int UNDETERMINED = 0;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 8232731..53d67edd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -198,6 +198,9 @@ @Override protected BrowserServicesIntentDataProvider buildIntentDataProvider( Intent intent, @CustomTabsIntent.ColorScheme int colorScheme) { + if (IncognitoCustomTabIntentDataProvider.isValidIncognitoIntent(intent)) { + return new IncognitoCustomTabIntentDataProvider(intent, this, colorScheme); + } return new CustomTabIntentDataProvider(intent, this, colorScheme); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java index 544494d5..a25c14d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
@@ -174,6 +174,8 @@ if (mIsIncognito) { addToHomeScreenVisible = false; + downloadItemVisible = false; + openInChromeItemVisible = false; } boolean isChromeScheme = url.startsWith(UrlConstants.CHROME_URL_PREFIX)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index b38cf9e..10855648 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -79,12 +79,12 @@ */ public static final String EXTRA_KEEP_ALIVE = "android.support.customtabs.extra.KEEP_ALIVE"; - private static final String ANIMATION_BUNDLE_PREFIX = + public static final String ANIMATION_BUNDLE_PREFIX = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? "android:activity." : "android:"; - private static final String BUNDLE_PACKAGE_NAME = ANIMATION_BUNDLE_PREFIX + "packageName"; - private static final String BUNDLE_ENTER_ANIMATION_RESOURCE = + public static final String BUNDLE_PACKAGE_NAME = ANIMATION_BUNDLE_PREFIX + "packageName"; + public static final String BUNDLE_ENTER_ANIMATION_RESOURCE = ANIMATION_BUNDLE_PREFIX + "animEnterRes"; - private static final String BUNDLE_EXIT_ANIMATION_RESOURCE = + public static final String BUNDLE_EXIT_ANIMATION_RESOURCE = ANIMATION_BUNDLE_PREFIX + "animExitRes"; /** @@ -179,7 +179,6 @@ private final Integer mNavigationBarColor; @Nullable private final Integer mNavigationBarDividerColor; - private final boolean mIsIncognito; @Nullable private final List<String> mTrustedWebActivityAdditionalOrigins; @Nullable @@ -276,15 +275,10 @@ IntentUtils.safeGetIntExtra(intent, EXTRA_UI_TYPE, CustomTabsUiType.DEFAULT); mUiType = verifiedUiType(requestedUiType); - // TODO(https://crbug.com/1023759): WARNING: Current implementation uses - // a common off-the-record profile with browser's incognito mode and is - // not privacy-safe. - mIsIncognito = isValidIncognitoIntent(intent); - CustomTabColorSchemeParams params = getColorSchemeParams(intent, colorScheme); retrieveCustomButtons(intent, context); - retrieveToolbarColor(params, context); - retrieveBottomBarColor(params); + mToolbarColor = retrieveToolbarColor(params, context); + mBottomBarColor = retrieveBottomBarColor(params); mNavigationBarColor = params.navigationBarColor == null ? null : ColorUtils.getOpaqueColor(params.navigationBarColor); @@ -310,17 +304,8 @@ List<Bundle> menuItems = IntentUtils.getParcelableArrayListExtra(intent, CustomTabsIntent.EXTRA_MENU_ITEMS); - if (menuItems != null) { - for (int i = 0; i < Math.min(MAX_CUSTOM_MENU_ITEMS, menuItems.size()); i++) { - Bundle bundle = menuItems.get(i); - String title = - IntentUtils.safeGetString(bundle, CustomTabsIntent.KEY_MENU_ITEM_TITLE); - PendingIntent pendingIntent = - IntentUtils.safeGetParcelable(bundle, CustomTabsIntent.KEY_PENDING_INTENT); - if (TextUtils.isEmpty(title) || pendingIntent == null) continue; - mMenuEntries.add(new Pair<String, PendingIntent>(title, pendingIntent)); - } - } + + updateExtraMenuItems(menuItems); mActivityType = IntentUtils.safeGetBooleanExtra( intent, TrustedWebUtils.EXTRA_LAUNCH_AS_TRUSTED_WEB_ACTIVITY, false) @@ -364,6 +349,18 @@ mGsaExperimentIds = IntentUtils.safeGetIntArrayExtra(intent, EXPERIMENT_IDS); } + private void updateExtraMenuItems(List<Bundle> menuItems) { + if (menuItems == null) return; + for (int i = 0; i < Math.min(MAX_CUSTOM_MENU_ITEMS, menuItems.size()); i++) { + Bundle bundle = menuItems.get(i); + String title = IntentUtils.safeGetString(bundle, CustomTabsIntent.KEY_MENU_ITEM_TITLE); + PendingIntent pendingIntent = + IntentUtils.safeGetParcelable(bundle, CustomTabsIntent.KEY_PENDING_INTENT); + if (TextUtils.isEmpty(title) || pendingIntent == null) continue; + mMenuEntries.add(new Pair<String, PendingIntent>(title, pendingIntent)); + } + } + /** * Triggers the client-defined action when the user clicks a custom menu item. * @param activity The {@link ChromeActivity} to use for sending the {@link PendingIntent}. @@ -416,28 +413,6 @@ } } - // TODO(https://crbug.com/1023759): Remove this function and enable - // incognito CCT request for all apps. - private boolean isValidIncognitoIntent(Intent intent) { - if (!isIncognitoRequested(intent)) return false; - // Incognito requests for payments flow are supported without - // INCOGNITO_CCT flag as an exceptional case that can use Chrome - // incognito profile. - if (isForPaymentsFlow(intent)) return true; - assert ChromeFeatureList.isInitialized(); - return ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_INCOGNITO); - } - - private boolean isForPaymentsFlow(Intent intent) { - return isIncognitoRequested(intent) && isTrustedIntent() && isOpenedByChrome() - && isForPaymentRequest(); - } - - private static boolean isIncognitoRequested(Intent intent) { - return IntentUtils.safeGetBooleanExtra( - intent, IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, false); - } - /** * Get the verified UI type, according to the intent extras, and whether the intent is trusted. * @param requestedUiType requested UI type in the intent, unqualified @@ -481,31 +456,24 @@ } /** - * Processes the color passed from the client app and updates {@link #mToolbarColor}. + * Returns the color passed from the client app. */ - private void retrieveToolbarColor(CustomTabColorSchemeParams schemeParams, Context context) { - int defaultColor = ChromeColors.getDefaultThemeColor(context.getResources(), isIncognito()); - if (isIncognito()) { - mToolbarColor = defaultColor; - return; // Don't allow toolbar color customization for incognito tabs. - } + private int retrieveToolbarColor(CustomTabColorSchemeParams schemeParams, Context context) { + int defaultColor = ChromeColors.getDefaultThemeColor( + context.getResources(), /*forceDarkBgColor*/ false); mHasCustomToolbarColor = (schemeParams.toolbarColor != null); int color = mHasCustomToolbarColor ? schemeParams.toolbarColor : defaultColor; - mToolbarColor = ColorUtils.getOpaqueColor(color); + return ColorUtils.getOpaqueColor(color); } /** * Must be called after calling {@link #retrieveToolbarColor}. */ - private void retrieveBottomBarColor(CustomTabColorSchemeParams schemeParams) { - if (isIncognito()) { - mBottomBarColor = mToolbarColor; - return; - } + private int retrieveBottomBarColor(CustomTabColorSchemeParams schemeParams) { int defaultColor = mToolbarColor; int color = schemeParams.secondaryToolbarColor != null ? schemeParams.secondaryToolbarColor : defaultColor; - mBottomBarColor = ColorUtils.getOpaqueColor(color); + return ColorUtils.getOpaqueColor(color); } /** @@ -796,7 +764,7 @@ @Override public boolean isIncognito() { - return mIsIncognito; + return false; } @Nullable
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java new file mode 100644 index 0000000..9a179fd --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java
@@ -0,0 +1,207 @@ +// 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.customtabs; + +import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.BUNDLE_ENTER_ANIMATION_RESOURCE; +import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.BUNDLE_EXIT_ANIMATION_RESOURCE; +import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.BUNDLE_PACKAGE_NAME; +import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.EXTRA_IS_OPENED_BY_CHROME; +import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.EXTRA_UI_TYPE; +import static org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider.isTrustedCustomTab; + +import android.content.Context; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.browser.customtabs.CustomTabsIntent; +import androidx.browser.customtabs.CustomTabsSessionToken; + +import org.chromium.base.IntentUtils; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.IntentHandler; +import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; +import org.chromium.chrome.browser.flags.ActivityType; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.components.browser_ui.styles.ChromeColors; +import org.chromium.components.browser_ui.widget.TintedDrawable; + +/** + * A model class that parses the incoming intent for incognito Custom Tabs specific customization + * data. + * + * Lifecycle: is activity-scoped, i.e. one instance per CustomTabActivity instance. Must be + * re-created when color scheme changes, which happens automatically since color scheme change leads + * to activity re-creation. + */ +public class IncognitoCustomTabIntentDataProvider extends BrowserServicesIntentDataProvider { + private final Intent mIntent; + private final CustomTabsSessionToken mSession; + private final boolean mIsTrustedIntent; + private final Bundle mAnimationBundle; + @Nullable + private final String mUrlToLoad; + + private final int mToolbarColor; + private final int mBottomBarColor; + private final Drawable mCloseButtonIcon; + private final boolean mShowShareItem; + + /** Whether this CustomTabActivity was explicitly started by another Chrome Activity. */ + private final boolean mIsOpenedByChrome; + + /** + * Constructs a {@link IncognitoCustomTabIntentDataProvider}. + * Incognito CCT would have a fix color scheme. + */ + public IncognitoCustomTabIntentDataProvider(Intent intent, Context context, int colorScheme) { + assert intent != null; + mIntent = intent; + mUrlToLoad = resolveUrlToLoad(intent); + mSession = CustomTabsSessionToken.getSessionTokenFromIntent(intent); + mIsTrustedIntent = isTrustedCustomTab(intent, mSession); + mAnimationBundle = IntentUtils.safeGetBundleExtra( + intent, CustomTabsIntent.EXTRA_EXIT_ANIMATION_BUNDLE); + mIsOpenedByChrome = + IntentUtils.safeGetBooleanExtra(intent, EXTRA_IS_OPENED_BY_CHROME, false); + mToolbarColor = ChromeColors.getDefaultThemeColor( + context.getResources(), /*forceDarkBgColor*/ true); + mBottomBarColor = ChromeColors.getDefaultThemeColor( + context.getResources(), /*forceDarkBgColor*/ true); + mCloseButtonIcon = TintedDrawable.constructTintedDrawable(context, R.drawable.btn_close); + mShowShareItem = IntentUtils.safeGetBooleanExtra( + intent, CustomTabsIntent.EXTRA_DEFAULT_SHARE_MENU_ITEM, false); + } + + private static boolean isIncognitoRequested(Intent intent) { + return IntentUtils.safeGetBooleanExtra( + intent, IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, false); + } + + private static boolean isForPaymentsFlow(Intent intent) { + CustomTabsSessionToken session = CustomTabsSessionToken.getSessionTokenFromIntent(intent); + boolean isOpenedByChrome = + IntentUtils.safeGetBooleanExtra(intent, EXTRA_IS_OPENED_BY_CHROME, false); + final int requestedUiType = + IntentUtils.safeGetIntExtra(intent, EXTRA_UI_TYPE, CustomTabsUiType.DEFAULT); + return (isTrustedCustomTab(intent, session) && isOpenedByChrome + && (requestedUiType == CustomTabsUiType.PAYMENT_REQUEST)); + } + + // TODO(https://crbug.com/1023759): Remove this function and enable + // incognito CCT request for all apps. + public static boolean isValidIncognitoIntent(Intent intent) { + if (!isIncognitoRequested(intent)) return false; + // Incognito requests for payments flow are supported without + // INCOGNITO_CCT flag as an exceptional case that can use Chrome + // incognito profile. + if (isForPaymentsFlow(intent)) return true; + assert ChromeFeatureList.isInitialized(); + return ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_INCOGNITO); + } + + private String resolveUrlToLoad(Intent intent) { + return IntentHandler.getUrlFromIntent(intent); + } + + @Override + public @ActivityType int getActivityType() { + return ActivityType.CUSTOM_TAB; + } + + @Override + @Nullable + public Intent getIntent() { + return mIntent; + } + + @Override + @Nullable + public CustomTabsSessionToken getSession() { + return mSession; + } + + @Override + public boolean shouldAnimateOnFinish() { + return mAnimationBundle != null && getClientPackageName() != null; + } + + @Override + public String getClientPackageName() { + if (mAnimationBundle == null) return null; + return mAnimationBundle.getString(BUNDLE_PACKAGE_NAME); + } + + @Override + public int getAnimationEnterRes() { + return shouldAnimateOnFinish() ? mAnimationBundle.getInt(BUNDLE_ENTER_ANIMATION_RESOURCE) + : 0; + } + + @Override + public int getAnimationExitRes() { + return shouldAnimateOnFinish() ? mAnimationBundle.getInt(BUNDLE_EXIT_ANIMATION_RESOURCE) + : 0; + } + + @Deprecated + @Override + public boolean isTrustedIntent() { + return mIsTrustedIntent; + } + + @Override + @Nullable + public String getUrlToLoad() { + return mUrlToLoad; + } + + @Override + public boolean shouldEnableUrlBarHiding() { + return false; + } + + @Override + public int getToolbarColor() { + return mToolbarColor; + } + + @Override + @Nullable + public Drawable getCloseButtonDrawable() { + return mCloseButtonIcon; + } + + @Override + public boolean shouldShowShareMenuItem() { + return mShowShareItem; + } + + @Override + public int getBottomBarColor() { + return mBottomBarColor; + } + + @Override + public boolean isOpenedByChrome() { + return mIsOpenedByChrome; + } + + @Override + public boolean shouldShowStarButton() { + return true; + } + + @Override + public boolean shouldShowDownloadButton() { + return false; + } + + @Override + public boolean isIncognito() { + return true; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java index 96d6380..8d113af 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -129,13 +129,6 @@ */ private final @Nullable @TabLaunchType Integer mLaunchType; - /** - * Saves how this tab was initially launched so that we can record metrics on how the - * tab was created. This is different than {@code mLaunchType}, since {@code mLaunchType} will - * be overridden to "FROM_RESTORE" during tab restoration. - */ - private @Nullable @TabLaunchType Integer mLaunchTypeAtCreation; - private @Nullable @TabCreationState Integer mCreationState; /** @@ -144,11 +137,6 @@ private LoadUrlParams mPendingLoadParams; /** - * URL of the page currently loading. Used as a fall-back in case tab restore fails. - */ - private GURL mUrl; - - /** * True while a page load is in progress. */ private boolean mIsLoading; @@ -339,6 +327,7 @@ return mId; } + // TODO(crbug.com/1113249) move getUrl() and getUrlString() to CriticalPersistedTabData @Override public String getUrlString() { return getUrl().getSpec(); @@ -352,10 +341,12 @@ // If we have a ContentView, or a NativePage, or the url is not empty, we have a WebContents // so cache the WebContent's url. If not use the cached version. if (getWebContents() != null || isNativePage() || !url.getSpec().isEmpty()) { - mUrl = url; + CriticalPersistedTabData.from(this).setUrl(url); } - return mUrl != null ? mUrl : GURL.emptyGURL(); + return CriticalPersistedTabData.from(this).getUrl() != null + ? CriticalPersistedTabData.from(this).getUrl() + : GURL.emptyGURL(); } @Override @@ -407,11 +398,6 @@ } @Override - public @Nullable @TabLaunchType Integer getLaunchTypeAtInitialTabCreation() { - return mLaunchTypeAtCreation; - } - - @Override public boolean isIncognito() { return mIncognito; } @@ -769,10 +755,12 @@ try { TraceEvent.begin("Tab.initialize"); - mLaunchTypeAtCreation = mLaunchType; + CriticalPersistedTabData.from(this).setLaunchTypeAtCreation(mLaunchType); mCreationState = creationState; mPendingLoadParams = loadUrlParams; - if (loadUrlParams != null) mUrl = new GURL(loadUrlParams.getUrl()); + if (loadUrlParams != null) { + CriticalPersistedTabData.from(this).setUrl(new GURL(loadUrlParams.getUrl())); + } TabHelpers.initTabHelpers(this, parent); @@ -834,10 +822,11 @@ assert state != null; CriticalPersistedTabData.from(this).setWebContentsState(state.contentsState); CriticalPersistedTabData.from(this).setTimestampMillis(state.timestampMillis); - mUrl = new GURL(state.contentsState.getVirtualUrlFromState()); + CriticalPersistedTabData.from(this).setUrl( + new GURL(state.contentsState.getVirtualUrlFromState())); CriticalPersistedTabData.from(this).setTitle( state.contentsState.getDisplayTitleFromState()); - mLaunchTypeAtCreation = state.tabLaunchTypeAtCreation; + CriticalPersistedTabData.from(this).setLaunchTypeAtCreation(state.tabLaunchTypeAtCreation); CriticalPersistedTabData.from(this).setRootId( state.rootId == Tab.INVALID_TAB_ID ? mId : state.rootId); } @@ -1405,7 +1394,9 @@ initWebContents(webContents); if (!restored) { - String url = mUrl.getSpec().isEmpty() ? UrlConstants.NTP_URL : mUrl.getSpec(); + String url = CriticalPersistedTabData.from(this).getUrl().getSpec().isEmpty() + ? UrlConstants.NTP_URL + : CriticalPersistedTabData.from(this).getUrl().getSpec(); loadUrl(new LoadUrlParams(url, PageTransition.GENERATED)); } } finally {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateExtractor.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateExtractor.java index 9a813d0c..82363a2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateExtractor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateExtractor.java
@@ -26,7 +26,8 @@ tabState.openerAppId = TabAssociatedApp.getAppId(tab); tabState.parentId = CriticalPersistedTabData.from(tab).getParentId(); tabState.timestampMillis = CriticalPersistedTabData.from(tab).getTimestampMillis(); - tabState.tabLaunchTypeAtCreation = tab.getLaunchTypeAtInitialTabCreation(); + tabState.tabLaunchTypeAtCreation = + CriticalPersistedTabData.from(tab).getTabLaunchTypeAtCreation(); // Don't save the actual default theme color because it could change on night mode state // changed. tabState.themeColor = TabThemeColorHelper.isUsingColorFromTabContents(tab)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java index 8ba6590..c3c59f5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java
@@ -73,6 +73,7 @@ private final ObserverList<Callback<WebContents>> mInitObservers = new ObserverList<>(); private final Handler mHandler = new Handler(); private WebContentsObserver mObserver; + private String mLastUrl; public static TabWebContentsObserver from(Tab tab) { TabWebContentsObserver observer = get(tab); @@ -294,6 +295,7 @@ recordErrorInPolicyAuditor( navigation.getUrl(), navigation.errorDescription(), navigation.errorCode()); } + mLastUrl = navigation.getUrl(); if (!navigation.hasCommitted()) return; @@ -353,7 +355,7 @@ @Override public void destroy() { MediaCaptureNotificationService.updateMediaNotificationForTab( - ContextUtils.getApplicationContext(), mTab.getId(), null, mTab.getUrlString()); + ContextUtils.getApplicationContext(), mTab.getId(), null, mLastUrl); super.destroy(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java index 23d522b..1a89f9c1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/TasksUma.java
@@ -65,7 +65,8 @@ if (totalTabCount == 0) return; for (int i = 0; i < totalTabCount; i++) { - Integer tabLaunchType = model.getTabAt(i).getLaunchTypeAtInitialTabCreation(); + Integer tabLaunchType = + CriticalPersistedTabData.from(model.getTabAt(i)).getTabLaunchTypeAtCreation(); if (tabLaunchType == null) { // This should not happen. Because @{link Tab#TabLaunchType} is never null, except // for testing purpose or in the document-mode which it's deprecated.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java index a64c72d..35d47bf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/MainActivityWithURLTest.java
@@ -63,7 +63,8 @@ public void testLaunchActivity() { // Launch chrome mActivityTestRule.startMainActivityFromLauncher(); - String currentUrl = mActivityTestRule.getActivity().getActivityTab().getUrlString(); + String currentUrl = ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab()); Assert.assertNotNull(currentUrl); Assert.assertEquals(false, currentUrl.isEmpty()); } @@ -78,14 +79,17 @@ public void testNewTabPageLaunch() { // Launch chrome with NTP. mActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL); - String currentUrl = mActivityTestRule.getActivity().getActivityTab().getUrlString(); + String currentUrl = ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab()); Assert.assertNotNull(currentUrl); Assert.assertEquals(false, currentUrl.isEmpty()); // Open NTP. ChromeTabUtils.newTabFromMenu( InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity()); - currentUrl = mActivityTestRule.getActivity().getActivityTab().getUrlString(); + + currentUrl = ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab()); Assert.assertNotNull(currentUrl); Assert.assertEquals(false, currentUrl.isEmpty()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java index 343de79..ce7886447 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java
@@ -99,8 +99,10 @@ Criteria.checkThat("urlBar is null", urlBar, Matchers.notNullValue()); Criteria.checkThat("UrlBar text wrong", urlBar.getText().toString(), Matchers.is(expectedLocation(endUrl))); + Criteria.checkThat("Tab url wrong", - mActivityTestRule.getActivity().getActivityTab().getUrlString(), + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab()), Matchers.is(endUrl)); }); } @@ -234,7 +236,8 @@ DOMUtils.clickNode(tab.getWebContents(), "aboutLink"); ChromeTabUtils.waitForTabPageLoaded(tab, url2); Assert.assertEquals("Desired Link not open", url2, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); } /** @@ -320,7 +323,7 @@ @Override public void onPageLoadStarted(Tab tab, String newUrl) { tab.removeObserver(this); - Assert.assertEquals(url1, tab.getUrlString()); + Assert.assertEquals(url1, ChromeTabUtils.getUrlStringOnUiThread(tab)); Assert.assertEquals(url2, newUrl); } }; @@ -329,7 +332,8 @@ DOMUtils.clickNode(tab.getWebContents(), "aboutLink"); ChromeTabUtils.waitForTabPageLoaded(tab, url2); Assert.assertEquals("Desired Link not open", url2, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); } /** @@ -347,7 +351,8 @@ typeInOmniboxAndNavigate(initialUrl, null); CriteriaHelper.pollInstrumentationThread(() -> { - Criteria.checkThat(mActivityTestRule.getActivity().getActivityTab().getUrlString(), + Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab()), Matchers.is(redirectedUrl)); }); } @@ -361,8 +366,9 @@ @Feature({"Navigation"}) public void testIntentFallbackRedirection() throws Exception { InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - Assert.assertEquals( - NEW_TAB_PAGE, mActivityTestRule.getActivity().getActivityTab().getUrlString()); + Assert.assertEquals(NEW_TAB_PAGE, + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); final String fallbackUrl = mTestServer.getURL("/chrome/test/data/android/redirect/about.html"); @@ -382,7 +388,8 @@ // Now intent fallback should be triggered assuming 'non_existent' scheme cannot be handled. CriteriaHelper.pollInstrumentationThread(() -> { - Criteria.checkThat(mActivityTestRule.getActivity().getActivityTab().getUrlString(), + Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab()), Matchers.is(targetUrl)); }); @@ -434,7 +441,9 @@ "URL mismatch after pressing back button for the 1st time in repetition" + "%d.", i), - urls[1], mActivityTestRule.getActivity().getActivityTab().getUrlString()); + urls[1], + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); TouchCommon.singleClickView( mActivityTestRule.getActivity().findViewById(R.id.back_button)); @@ -444,7 +453,9 @@ "URL mismatch after pressing back button for the 2nd time in repetition" + "%d.", i), - urls[0], mActivityTestRule.getActivity().getActivityTab().getUrlString()); + urls[0], + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); TouchCommon.singleClickView( mActivityTestRule.getActivity().findViewById(R.id.forward_button)); @@ -454,7 +465,9 @@ "URL mismatch after pressing fwd button for the 1st time in repetition" + "%d.", i), - urls[1], mActivityTestRule.getActivity().getActivityTab().getUrlString()); + urls[1], + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); TouchCommon.singleClickView( mActivityTestRule.getActivity().findViewById(R.id.forward_button)); @@ -464,7 +477,9 @@ "URL mismatch after pressing fwd button for the 2nd time in repetition" + "%d.", i), - urls[2], mActivityTestRule.getActivity().getActivityTab().getUrlString()); + urls[2], + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); } } @@ -603,7 +618,8 @@ private String getTabUrlOnUIThread(final Tab tab) { try { - return TestThreadUtils.runOnUiThreadBlocking(() -> tab.getUrlString()); + return TestThreadUtils.runOnUiThreadBlocking( + () -> ChromeTabUtils.getUrlStringOnUiThread(tab)); } catch (ExecutionException ex) { assert false : "Unexpected ExecutionException"; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java index 82701ea..f6b0eff1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsOpenedFromExternalAppTest.java
@@ -402,7 +402,8 @@ int newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount + 1, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url1, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); // Launch a new URL from the same app, it should open in the same tab. originalTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); @@ -410,7 +411,8 @@ newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url2, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); // And pressing back should close Clank. Assert.assertTrue("Window does not have focus before pressing back.", @@ -438,7 +440,8 @@ launchUrlFromExternalApp(url1, EXTERNAL_APP_1_ID, false); Assert.assertEquals("Selected tab is not on the right URL.", url1, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); // Launch the same URL without app ID. It should open a new tab. int originalTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); @@ -446,7 +449,8 @@ int newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount + 1, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url1, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); // Launch another URL without app ID. It should open a new tab. originalTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); @@ -454,7 +458,8 @@ newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount + 1, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url2, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); // And pressing back should close Clank. Assert.assertTrue("Window does not have focus before pressing back.", @@ -485,7 +490,8 @@ int newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount + 1, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url1, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); // Launch a new URL from the same app with the right extra to open in a new tab. originalTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); @@ -493,7 +499,8 @@ newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount + 1, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url2, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); // And pressing back should close Clank. Assert.assertTrue("Window does not have focus before pressing back.", @@ -517,7 +524,8 @@ // Launch Clank from the external app. mActivityTestRule.startMainActivityFromExternalApp(url1, EXTERNAL_APP_1_ID); Assert.assertEquals("Selected tab is not on the right URL.", url1, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); // Launch a new URL from the same app, it should open in the same tab. int originalTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); @@ -525,7 +533,8 @@ int newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url2, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); // And pressing back should close Clank. Assert.assertTrue("Window does not have focus before pressing back.", @@ -560,7 +569,8 @@ int newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount + 1, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url2, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); // Also try with no app id, it should also open in a new tab. originalTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); @@ -568,7 +578,8 @@ newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount + 1, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url3, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); } /** @@ -597,7 +608,8 @@ int newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount + 1, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url2, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); } /** @@ -645,7 +657,8 @@ int newTabCount = ChromeTabUtils.getNumOpenTabs(mActivityTestRule.getActivity()); Assert.assertEquals("Incorrect number of tabs open", originalTabCount + 1, newTabCount); Assert.assertEquals("Selected tab is not on the right URL.", url2, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); } private static class TestTabObserver extends EmptyTabObserver {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java index d202b9a..c0ef9b4e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java
@@ -63,8 +63,8 @@ BookmarkModel bookmarkModel = new BookmarkModel(Profile.fromWebContents( mSyncTestRule.getActivity().getActivityTab().getWebContents())); bookmarkModel.loadFakePartnerBookmarkShimForTesting(); - BookmarkTestUtil.waitForBookmarkModelLoaded(); }); + BookmarkTestUtil.waitForBookmarkModelLoaded(); } @After
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityLocationDelegationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityLocationDelegationTest.java index ca2a7964c..19c48c21 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityLocationDelegationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityLocationDelegationTest.java
@@ -25,6 +25,7 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisableIf; +import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.browser.browserservices.TrustedWebActivityTestUtil; import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -86,6 +87,7 @@ @Test @MediumTest + @DisabledTest(message = "crbug.com/1113325") public void getLocationFromTestTwaService() throws TimeoutException, Exception { assertTrue(ChromeFeatureList.isEnabled( ChromeFeatureList.TRUSTED_WEB_ACTIVITY_LOCATION_DELEGATION));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java index 95a647a..062902a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -686,12 +686,9 @@ CriteriaHelper.pollUiThread( mActivityTestRule.getActivity().getTabModelSelector()::isTabStateInitialized); - TestThreadUtils.runOnUiThreadBlocking(() -> { - LayoutManagerChrome layoutManager = mActivityTestRule.getActivity().getLayoutManager(); - layoutManager.showOverview(false); - - CriteriaHelper.pollUiThread(layoutManager::overviewVisible); - }); + LayoutManagerChrome layoutManager = mActivityTestRule.getActivity().getLayoutManager(); + TestThreadUtils.runOnUiThreadBlocking(() -> layoutManager.showOverview(false)); + CriteriaHelper.pollUiThread(layoutManager::overviewVisible); } private Layout getActiveLayout() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java index 9af5fab..92818af0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -46,6 +46,7 @@ import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils; @@ -398,7 +399,9 @@ // Only check for the URL matching as the tab will not be fully created in svelte mode. final String expectedUrl = mTestServer.getURL(expectedPath); CriteriaHelper.pollUiThread( - () -> Criteria.checkThat(newTab.get().getUrlString(), Matchers.is(expectedUrl))); + () + -> Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(newTab.get()), + Matchers.is(expectedUrl))); } @Test @@ -534,17 +537,21 @@ "Number of open tabs does not match", numOpenedTabs, tabModel.getCount()); // Verify the Url is still the same of Parent page. - Assert.assertEquals( - mTestUrl, mDownloadTestRule.getActivity().getActivityTab().getUrlString()); + Assert.assertEquals(mTestUrl, + ChromeTabUtils.getUrlStringOnUiThread( + mDownloadTestRule.getActivity().getActivityTab())); // Verify that the background tabs were opened in the expected order. String newTabUrl = mTestServer.getURL( "/chrome/test/data/android/contextmenu/test_link.html"); - Assert.assertEquals(newTabUrl, tabModel.getTabAt(indexOfLinkPage).getUrlString()); + + Assert.assertEquals(newTabUrl, + ChromeTabUtils.getUrlStringOnUiThread(tabModel.getTabAt(indexOfLinkPage))); String imageUrl = mTestServer.getURL( "/chrome/test/data/android/contextmenu/test_link2.html"); - Assert.assertEquals(imageUrl, tabModel.getTabAt(indexOfLinkPage2).getUrlString()); + Assert.assertEquals(imageUrl, + ChromeTabUtils.getUrlStringOnUiThread(tabModel.getTabAt(indexOfLinkPage2))); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java index 325812d..5bf0a93 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/RevampedContextMenuTest.java
@@ -36,6 +36,7 @@ import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.contextmenu.RevampedContextMenuUtils; import org.chromium.content_public.browser.test.util.Criteria; @@ -151,7 +152,9 @@ final String expectedUrl = mTestServer.getURL("/chrome/test/data/android/contextmenu/test_image.png"); CriteriaHelper.pollUiThread( - () -> Criteria.checkThat(newTab.get().getUrlString(), Matchers.is(expectedUrl))); + () + -> Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(newTab.get()), + Matchers.is(expectedUrl))); } @Test @@ -279,17 +282,20 @@ "Number of open tabs does not match", numOpenedTabs, tabModel.getCount()); // Verify the Url is still the same of Parent page. - Assert.assertEquals( - mTestUrl, mDownloadTestRule.getActivity().getActivityTab().getUrlString()); + Assert.assertEquals(mTestUrl, + ChromeTabUtils.getUrlStringOnUiThread( + mDownloadTestRule.getActivity().getActivityTab())); // Verify that the background tabs were opened in the expected order. String newTabUrl = mTestServer.getURL("/chrome/test/data/android/contextmenu/test_link.html"); - Assert.assertEquals(newTabUrl, tabModel.getTabAt(indexOfLinkPage).getUrlString()); + Assert.assertEquals(newTabUrl, + ChromeTabUtils.getUrlStringOnUiThread(tabModel.getTabAt(indexOfLinkPage))); String imageUrl = mTestServer.getURL("/chrome/test/data/android/contextmenu/test_link2.html"); - Assert.assertEquals(imageUrl, tabModel.getTabAt(indexOfLinkPage2).getUrlString()); + Assert.assertEquals(imageUrl, + ChromeTabUtils.getUrlStringOnUiThread(tabModel.getTabAt(indexOfLinkPage2))); } private void saveMediaFromContextMenu(String mediaDOMElement, int saveMenuID,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java index 3588bf7..5a1aedb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java
@@ -8,27 +8,42 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.addActionButtonToIntent; +import static org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.createTestBitmap; + +import android.app.PendingIntent; +import android.content.Context; import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.drawable.Drawable; import android.support.test.InstrumentationRegistry; +import android.view.Menu; import android.view.MenuItem; +import android.view.View; +import android.widget.ImageButton; +import android.widget.RemoteViews; +import androidx.annotation.DrawableRes; +import androidx.appcompat.content.res.AppCompatResources; import androidx.browser.customtabs.CustomTabsIntent; -import androidx.test.filters.SmallTest; +import androidx.test.filters.MediumTest; +import org.junit.Assert; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.RunWith; -import org.chromium.base.Callback; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisabledTest; -import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; -import org.chromium.chrome.browser.IntentHandler; +import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.OnFinishedForTest; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.incognito.IncognitoDataTestUtils; import org.chromium.chrome.browser.incognito.IncognitoNotificationService; import org.chromium.chrome.browser.toolbar.top.CustomTabToolbar; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -36,96 +51,60 @@ import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.net.test.EmbeddedTestServerRule; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; /** * Instrumentation tests for {@link CustomTabActivity} launched in incognito mode. + * TODO(crbug.com/2338935): Add the screenshot rule again once there's a reliable way to take them + * in the first place. Screenshot of the Custom tab menu item is broken. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.FORCE_FIRST_RUN_FLOW_COMPLETE_FOR_TESTING}) public class CustomTabActivityIncognitoTest { + private String mTestPage; + private static final String TEST_PAGE = "/chrome/test/data/android/google.html"; + private static final String TEST_MENU_TITLE = "testMenuTitle"; + private static int sIdToIncrement = 1; + @Rule public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule(); @Rule - public TestRule mJUnitProcessor = new Features.JUnitProcessor(); + public TestRule mProcessor = new Features.InstrumentationProcessor(); - @Test - @SmallTest - @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) - public void launchesIncognitoWhenEnabled() throws Exception { - CustomTabActivity activity = launchIncognitoCustomTab(); - assertTrue(activity.getActivityTab().isIncognito()); + @Rule + public EmbeddedTestServerRule mEmbeddedTestServerRule = new EmbeddedTestServerRule(); + + @Before + public void setUp() throws TimeoutException { + mTestPage = mEmbeddedTestServerRule.getServer().getURL(TEST_PAGE); + + // Ensuring native is initialized before we access the CCT_INCOGNITO feature flag. + IncognitoDataTestUtils.fireAndWaitForCctWarmup(); } - @Test - @SmallTest - @Features.DisableFeatures({ChromeFeatureList.CCT_INCOGNITO}) - public void doesntLaunchIncognitoWhenDisabled() throws Exception { - CustomTabActivity activity = launchIncognitoCustomTab(); - assertFalse(activity.getActivityTab().isIncognito()); + private Bitmap createVectorDrawableBitmap(@DrawableRes int resId, int widthDp, int heightDp) { + Context context = InstrumentationRegistry.getTargetContext(); + Drawable vectorDrawable = AppCompatResources.getDrawable(context, resId); + Bitmap bitmap = createTestBitmap(widthDp, heightDp); + Canvas canvas = new Canvas(bitmap); + float density = context.getResources().getDisplayMetrics().density; + int widthPx = (int) (density * widthDp); + int heightPx = (int) (density * heightDp); + vectorDrawable.setBounds(0, 0, widthPx, heightPx); + vectorDrawable.draw(canvas); + return bitmap; } - @Test - @SmallTest - @Feature({"UiCatalogue"}) - @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) - public void toolbarHasIncognitoThemeColor() throws Exception { - CustomTabActivity activity = launchIncognitoCustomTab(); - assertEquals(getIncognitoThemeColor(activity), getToolbarColor(activity)); + private Intent createMinimalIncognitoCustomTabIntent() { + return CustomTabsTestUtils.createMinimalIncognitoCustomTabIntent( + InstrumentationRegistry.getContext(), mTestPage); } - @Test - @SmallTest - @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) - public void ignoresCustomizedToolbarColor() throws Exception { - CustomTabActivity activity = launchIncognitoCustomTab( - intent -> intent.putExtra(CustomTabsIntent.EXTRA_TOOLBAR_COLOR, Color.RED)); - assertEquals(getIncognitoThemeColor(activity), getToolbarColor(activity)); - } - - @Test - @SmallTest - @Feature({"UiCatalogue"}) - @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) - public void openInBrowserMenuItemHasCorrectTitle() throws Exception { - CustomTabActivity activity = launchIncognitoCustomTab(); - CustomTabsTestUtils.openAppMenuAndAssertMenuShown(activity); - String menuTitle = mCustomTabActivityTestRule.getMenu() - .findItem(R.id.open_in_browser_id) - .getTitle() - .toString(); - assertEquals(activity.getString(R.string.menu_open_in_incognito_chrome), menuTitle); - } - - @Test - @SmallTest - @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) - @DisabledTest - // TODO(crbug.com/1023759) : The test is flaky on marshmallow. - // Need to investigate. - public void incognitoNotificationClosesIncognitoCustomTab() throws Exception { - CustomTabActivity activity = launchIncognitoCustomTab(); - IncognitoNotificationService.getRemoveAllIncognitoTabsIntent(activity) - .getPendingIntent() - .send(); - CriteriaHelper.pollUiThread(activity::isFinishing); - } - - @Test - @SmallTest - @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) - public void doesNotHaveAddToHomeScreenMenuItem() throws Exception { - CustomTabActivity activity = launchIncognitoCustomTab(); - CustomTabsTestUtils.openAppMenuAndAssertMenuShown(activity); - - MenuItem item = mCustomTabActivityTestRule.getMenu().findItem(R.id.add_to_homescreen_id); - assertTrue(item == null || !item.isVisible()); - } - - private static int getIncognitoThemeColor(CustomTabActivity activity) - throws ExecutionException { + private static int getIncognitoThemeColor(CustomTabActivity activity) throws Exception { return TestThreadUtils.runOnUiThreadBlocking( () -> ChromeColors.getDefaultThemeColor(activity.getResources(), true)); } @@ -137,22 +116,226 @@ }); } - private CustomTabActivity launchIncognitoCustomTab() throws InterruptedException { - return launchIncognitoCustomTab(null); + private void launchMenuItem() throws Exception { + Intent intent = createMinimalIncognitoCustomTabIntent(); + CustomTabActivity activity = launchIncognitoCustomTab(intent); + CustomTabsTestUtils.openAppMenuAndAssertMenuShown(activity); } - private CustomTabActivity launchIncognitoCustomTab( - Callback<Intent> additionalIntentModifications) throws InterruptedException { - Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( - InstrumentationRegistry.getTargetContext(), "http://www.google.com"); + private void launchAndTestMenuItemIsVisible(int itemId, String screenshotName) + throws Exception { + launchMenuItem(); + Menu menu = mCustomTabActivityTestRule.getMenu(); + MenuItem item = menu.findItem(itemId); + assertTrue(item.isVisible()); + } - intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true); - if (additionalIntentModifications != null) { - additionalIntentModifications.onResult(intent); - } + private void launchAndTestMenuItemIsNotVisible(int itemId, String screenshotName) + throws Exception { + launchMenuItem(); + Menu menu = mCustomTabActivityTestRule.getMenu(); + MenuItem item = menu.findItem(itemId); + assertTrue(item == null || !item.isVisible()); + } + private void testTopActionIconsIsVisible(String screenshotName) throws Exception { + Menu menu = mCustomTabActivityTestRule.getMenu(); + MenuItem iconRow = menu.findItem(R.id.icon_row_menu_id); + + assertEquals(4, CustomTabsTestUtils.getVisibleMenuSize(iconRow.getSubMenu())); + assertTrue(iconRow.getSubMenu().findItem(R.id.forward_menu_id).isVisible()); + assertTrue(iconRow.getSubMenu().findItem(R.id.reload_menu_id).isVisible()); + assertTrue(iconRow.getSubMenu().findItem(R.id.bookmark_this_page_id).isVisible()); + assertTrue(iconRow.getSubMenu().findItem(R.id.info_menu_id).isVisible()); + } + + private CustomTabActivity launchIncognitoCustomTab(Intent intent) throws InterruptedException { mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); - return mCustomTabActivityTestRule.getActivity(); } -} + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void launchesIncognitoWhenEnabled() throws Exception { + Intent intent = createMinimalIncognitoCustomTabIntent(); + CustomTabActivity activity = launchIncognitoCustomTab(intent); + assertTrue(activity.getActivityTab().isIncognito()); + } + + @Test + @MediumTest + @Features.DisableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void doesntLaunchIncognitoWhenDisabled() throws Exception { + Intent intent = createMinimalIncognitoCustomTabIntent(); + CustomTabActivity activity = launchIncognitoCustomTab(intent); + assertFalse(activity.getActivityTab().isIncognito()); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void toolbarHasIncognitoThemeColor() throws Exception { + Intent intent = createMinimalIncognitoCustomTabIntent(); + CustomTabActivity activity = launchIncognitoCustomTab(intent); + assertEquals(getIncognitoThemeColor(activity), getToolbarColor(activity)); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void ignoresCustomizedToolbarColor() throws Exception { + Intent intent = createMinimalIncognitoCustomTabIntent(); + intent.putExtra(CustomTabsIntent.EXTRA_TOOLBAR_COLOR, Color.RED); + CustomTabActivity activity = launchIncognitoCustomTab(intent); + assertEquals(getIncognitoThemeColor(activity), getToolbarColor(activity)); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + @DisabledTest + // TODO(crbug.com/1023759) : The test is flaky on marshmallow. + // Need to investigate. + public void incognitoNotificationClosesIncognitoCustomTab() throws Exception { + Intent intent = createMinimalIncognitoCustomTabIntent(); + CustomTabActivity activity = launchIncognitoCustomTab(intent); + IncognitoNotificationService.getRemoveAllIncognitoTabsIntent(activity) + .getPendingIntent() + .send(); + CriteriaHelper.pollUiThread(activity::isFinishing); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void openInBrowserMenuItemIsNotVisible() throws Exception { + launchAndTestMenuItemIsNotVisible(R.id.open_in_browser_id, "Open in Browser not visible"); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void doesNotHaveAddToHomeScreenMenuItem() throws Exception { + launchAndTestMenuItemIsNotVisible( + R.id.add_to_homescreen_id, "Add to home screen not visible"); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void bookmarkTopIconIsVisible() throws Exception { + launchAndTestMenuItemIsVisible(R.id.bookmark_this_page_id, "Bookmark icon is visible"); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void downloadTopIconIsNotVisible() throws Exception { + launchAndTestMenuItemIsNotVisible(R.id.offline_page_id, "Download icon not visible"); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void shareMenuItemByDefaultIsNotVisibile() throws Exception { + launchAndTestMenuItemIsNotVisible( + R.id.share_row_menu_id, "Share menu item not visible by default"); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void shareMenuItemViaIntentExtraIsVisibile() throws Exception { + Intent intent = createMinimalIncognitoCustomTabIntent(); + intent.putExtra(CustomTabsIntent.EXTRA_DEFAULT_SHARE_MENU_ITEM, true); + CustomTabActivity activity = launchIncognitoCustomTab(intent); + CustomTabsTestUtils.openAppMenuAndAssertMenuShown(activity); + + MenuItem item = mCustomTabActivityTestRule.getMenu().findItem(R.id.share_row_menu_id); + assertTrue(item.isVisible()); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void ensureOnlyFourTopIconsAreVisible() throws Exception { + launchMenuItem(); + testTopActionIconsIsVisible("Forward, info, bookmark and reload is visible"); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void ensureAddCustomMenuItemHasNoEffect() throws Exception { + Intent intent = createMinimalIncognitoCustomTabIntent(); + CustomTabsTestUtils.addMenuEntriesToIntent(intent, 3, TEST_MENU_TITLE); + CustomTabActivity activity = launchIncognitoCustomTab(intent); + CustomTabsTestUtils.openAppMenuAndAssertMenuShown(activity); + + Menu menu = mCustomTabActivityTestRule.getMenu(); + // Check the menu items have only 3 items visible including the top icon row menu. + assertEquals(3, CustomTabsTestUtils.getVisibleMenuSize(menu)); + assertTrue(menu.findItem(R.id.icon_row_menu_id).isVisible()); + assertTrue(menu.findItem(R.id.find_in_page_id).isVisible()); + assertTrue(menu.findItem(R.id.request_desktop_site_row_menu_id).isVisible()); + + // Check top icons are still the same. + testTopActionIconsIsVisible("Custom menu items not visible"); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void ensureAddCustomTopMenuItemHasNoEffect() throws Exception { + Bitmap expectedIcon = createVectorDrawableBitmap(R.drawable.ic_credit_card_black, 77, 48); + Intent intent = createMinimalIncognitoCustomTabIntent(); + final PendingIntent pi = + addActionButtonToIntent(intent, expectedIcon, "Good test", sIdToIncrement++); + CustomTabActivity activity = launchIncognitoCustomTab(intent); + + final OnFinishedForTest onFinished = new OnFinishedForTest(pi); + activity.getComponent() + .resolveToolbarCoordinator() + .setCustomButtonPendingIntentOnFinishedForTesting(onFinished); + + View toolbarView = mCustomTabActivityTestRule.getActivity().findViewById(R.id.toolbar); + Assert.assertTrue( + "A custom tab toolbar is never shown", toolbarView instanceof CustomTabToolbar); + CustomTabToolbar toolbar = (CustomTabToolbar) toolbarView; + final ImageButton actionButton = toolbar.getCustomActionButtonForTest(0); + + Assert.assertNull(actionButton); + } + + @Test + @MediumTest + @Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO}) + public void ensureAddRemoteViewsHasNoEffect() throws Exception { + Intent intent = createMinimalIncognitoCustomTabIntent(); + Bitmap expectedIcon = createVectorDrawableBitmap(R.drawable.ic_credit_card_black, 77, 48); + final PendingIntent pi = + addActionButtonToIntent(intent, expectedIcon, "Good test", sIdToIncrement++); + + // Create a RemoteViews. The layout used here is pretty much arbitrary, but with the + // constraint that a) it already exists in production code, and b) it only contains + // views with the @RemoteView annotation. + RemoteViews remoteViews = + new RemoteViews(InstrumentationRegistry.getTargetContext().getPackageName(), + R.layout.web_notification); + remoteViews.setTextViewText(R.id.title, "Kittens!"); + remoteViews.setTextViewText(R.id.body, "So fluffy"); + remoteViews.setImageViewResource(R.id.icon, R.drawable.ic_email_googblue_36dp); + intent.putExtra(CustomTabsIntent.EXTRA_REMOTEVIEWS, remoteViews); + intent.putExtra(CustomTabsIntent.EXTRA_REMOTEVIEWS_VIEW_IDS, new int[] {R.id.icon}); + + CustomTabActivity activity = launchIncognitoCustomTab(intent); + final OnFinishedForTest onFinished = new OnFinishedForTest(pi); + activity.getComponent() + .resolveToolbarCoordinator() + .setCustomButtonPendingIntentOnFinishedForTesting(onFinished); + + View bottomBarView = mCustomTabActivityTestRule.getActivity().findViewById(R.id.bottom_bar); + assertTrue(bottomBarView == null); + } + }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index 423cf69..653fdc5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -14,6 +14,8 @@ import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE; import static org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule.LONG_TIMEOUT_MS; +import static org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.createTestBitmap; +import static org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.getVisibleMenuSize; import static org.chromium.components.content_settings.PrefNames.BLOCK_THIRD_PARTY_COOKIES; import android.app.Activity; @@ -24,7 +26,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -88,6 +89,7 @@ import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider.CustomTabsUiType; import org.chromium.chrome.browser.browserservices.OriginVerifier; import org.chromium.chrome.browser.browserservices.SessionDataHolder; +import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.OnFinishedForTest; import org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController.FinishReason; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.firstrun.FirstRunStatus; @@ -267,16 +269,6 @@ InstrumentationRegistry.getTargetContext(), mTestPage); } - /** - * Add a bundle specifying a a number of custom menu entries. - * @param customTabIntent The intent to modify. - * @param numEntries The number of menu entries to add. - * @return The pending intent associated with the menu entries. - */ - private PendingIntent addMenuEntriesToIntent(Intent customTabIntent, int numEntries) { - return addMenuEntriesToIntent(customTabIntent, numEntries, new Intent()); - } - @Test @SmallTest public void testWhitelistedHeadersReceivedWhenConnectionVerified() throws Exception { @@ -320,54 +312,10 @@ pageLoadFinishedHelper.waitForCallback(0); } - /** - * Add a bundle specifying a custom menu entry. - * @param customTabIntent The intent to modify. - * @param numEntries The number of menu entries to add. - * @param callbackIntent The intent to use as the base for the pending intent. - * @return The pending intent associated with the menu entry. - */ - private PendingIntent addMenuEntriesToIntent( - Intent customTabIntent, int numEntries, Intent callbackIntent) { - PendingIntent pi = PendingIntent.getBroadcast(InstrumentationRegistry.getTargetContext(), 0, - callbackIntent, PendingIntent.FLAG_UPDATE_CURRENT); - ArrayList<Bundle> menuItems = new ArrayList<>(); - for (int i = 0; i < numEntries; i++) { - Bundle bundle = new Bundle(); - bundle.putString(CustomTabsIntent.KEY_MENU_ITEM_TITLE, TEST_MENU_TITLE); - bundle.putParcelable(CustomTabsIntent.KEY_PENDING_INTENT, pi); - menuItems.add(bundle); - } - customTabIntent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_MENU_ITEMS, menuItems); - return pi; - } - private void addToolbarColorToIntent(Intent intent, int color) { intent.putExtra(CustomTabsIntent.EXTRA_TOOLBAR_COLOR, color); } - /** - * Adds an action button to the custom tab toolbar. - * @return The {@link PendingIntent} that will be triggered when the action button is clicked. - */ - private PendingIntent addActionButtonToIntent(Intent intent, Bitmap icon, String description) { - PendingIntent pi = PendingIntent.getBroadcast( - InstrumentationRegistry.getTargetContext(), 0, new Intent(), 0); - intent.putExtra(CustomTabsIntent.EXTRA_ACTION_BUTTON_BUNDLE, - makeToolbarItemBundle(icon, description, pi)); - return pi; - } - - private Bundle makeToolbarItemBundle(Bitmap icon, String description, PendingIntent pi) { - Bundle bundle = new Bundle(); - bundle.putInt(CustomTabsIntent.KEY_ID, sIdToIncrement++); - bundle.putParcelable(CustomTabsIntent.KEY_ICON, icon); - bundle.putString(CustomTabsIntent.KEY_DESCRIPTION, description); - bundle.putParcelable(CustomTabsIntent.KEY_PENDING_INTENT, pi); - bundle.putBoolean(CustomButtonParams.SHOW_ON_TOOLBAR, true); - return bundle; - } - private Bundle makeBottomBarBundle(int id, Bitmap icon, String description) { Bundle bundle = new Bundle(); PendingIntent pi = PendingIntent.getBroadcast( @@ -404,25 +352,6 @@ return actualMenuSize; } - /** - * @return The number of visible items in the given menu. - */ - private int getVisibleMenuSize(Menu menu) { - int visibleMenuSize = 0; - for (int i = 0; i < menu.size(); i++) { - MenuItem item = menu.getItem(i); - if (item.isVisible()) visibleMenuSize++; - } - return visibleMenuSize; - } - - private Bitmap createTestBitmap(int widthDp, int heightDp) { - Resources testRes = InstrumentationRegistry.getTargetContext().getResources(); - float density = testRes.getDisplayMetrics().density; - return Bitmap.createBitmap((int) (widthDp * density), - (int) (heightDp * density), Bitmap.Config.ARGB_8888); - } - private Bitmap createVectorDrawableBitmap(@DrawableRes int resId, int widthDp, int heightDp) { Context context = InstrumentationRegistry.getTargetContext(); Drawable vectorDrawable = AppCompatResources.getDrawable(context, resId); @@ -625,7 +554,7 @@ public void testAppMenu() throws Exception { Intent intent = createMinimalCustomTabIntent(); int numMenuEntries = 1; - addMenuEntriesToIntent(intent, numMenuEntries); + CustomTabsTestUtils.addMenuEntriesToIntent(intent, numMenuEntries, TEST_MENU_TITLE); mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); openAppMenuAndAssertMenuShown(); @@ -647,6 +576,8 @@ Assert.assertNotNull(menu.findItem(R.id.add_to_homescreen_id)); Assert.assertNotNull(menu.findItem(R.id.request_desktop_site_row_menu_id)); Assert.assertNotNull(menu.findItem(R.id.translate_id)); + + mScreenShooter.shoot("Testtttt"); } /** @@ -748,7 +679,7 @@ Intent intent = createMinimalCustomTabIntent(); int numMenuEntries = 7; Assert.assertTrue(MAX_MENU_CUSTOM_ITEMS < numMenuEntries); - addMenuEntriesToIntent(intent, numMenuEntries); + CustomTabsTestUtils.addMenuEntriesToIntent(intent, numMenuEntries, TEST_MENU_TITLE); mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); openAppMenuAndAssertMenuShown(); @@ -769,7 +700,8 @@ Intent customTabIntent = createMinimalCustomTabIntent(); Intent baseCallbackIntent = new Intent(); baseCallbackIntent.putExtra("FOO", 42); - final PendingIntent pi = addMenuEntriesToIntent(customTabIntent, 1, baseCallbackIntent); + final PendingIntent pi = CustomTabsTestUtils.addMenuEntriesToIntent( + customTabIntent, 1, baseCallbackIntent, TEST_MENU_TITLE); mCustomTabActivityTestRule.startCustomTabActivityWithIntent(customTabIntent); final OnFinishedForTest onFinished = new OnFinishedForTest(pi); @@ -942,7 +874,8 @@ public void testActionButton() throws TimeoutException { Bitmap expectedIcon = createVectorDrawableBitmap(R.drawable.ic_credit_card_black, 77, 48); Intent intent = createMinimalCustomTabIntent(); - final PendingIntent pi = addActionButtonToIntent(intent, expectedIcon, "Good test"); + final PendingIntent pi = CustomTabsTestUtils.addActionButtonToIntent( + intent, expectedIcon, "Good test", sIdToIncrement++); mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); final OnFinishedForTest onFinished = new OnFinishedForTest(pi); @@ -994,12 +927,14 @@ final PendingIntent pi1 = PendingIntent.getBroadcast( InstrumentationRegistry.getTargetContext(), 0, new Intent(), 0); final OnFinishedForTest onFinished1 = new OnFinishedForTest(pi1); - toolbarItems.add(makeToolbarItemBundle(expectedIcon1, "Good test", pi1)); + toolbarItems.add(CustomTabsTestUtils.makeToolbarItemBundle( + expectedIcon1, "Good test", pi1, sIdToIncrement++)); final PendingIntent pi2 = PendingIntent.getBroadcast( InstrumentationRegistry.getTargetContext(), 1, new Intent(), 0); Assert.assertThat(pi2, not(equalTo(pi1))); final OnFinishedForTest onFinished2 = new OnFinishedForTest(pi2); - toolbarItems.add(makeToolbarItemBundle(expectedIcon2, "Even gooder test", pi2)); + toolbarItems.add(CustomTabsTestUtils.makeToolbarItemBundle( + expectedIcon2, "Even gooder test", pi2, sIdToIncrement++)); intent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_TOOLBAR_ITEMS, toolbarItems); mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); @@ -1059,7 +994,8 @@ public void testActionButtonBadRatio() { Bitmap expectedIcon = createTestBitmap(60, 20); Intent intent = createMinimalCustomTabIntent(); - addActionButtonToIntent(intent, expectedIcon, "Good test"); + CustomTabsTestUtils.addActionButtonToIntent( + intent, expectedIcon, "Good test", sIdToIncrement++); mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); View toolbarView = mCustomTabActivityTestRule.getActivity().findViewById(R.id.toolbar); @@ -1120,7 +1056,8 @@ Intent intent = createMinimalCustomTabIntent(); Bitmap expectedIcon = createVectorDrawableBitmap(R.drawable.ic_credit_card_black, 77, 48); - PendingIntent pi = addActionButtonToIntent(intent, expectedIcon, "Good test"); + PendingIntent pi = CustomTabsTestUtils.addActionButtonToIntent( + intent, expectedIcon, "Good test", sIdToIncrement++); // Create a RemoteViews. The layout used here is pretty much arbitrary, but with the // constraint that a) it already exists in production code, and b) it only contains views @@ -1161,7 +1098,9 @@ CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage2)); })); CriteriaHelper.pollInstrumentationThread(() -> { - Criteria.checkThat(getActivity().getActivityTab().getUrlString(), is(mTestPage)); + Criteria.checkThat( + ChromeTabUtils.getUrlStringOnUiThread(getActivity().getActivityTab()), + is(mTestPage)); }); Assert.assertTrue("CustomTabContentHandler can't handle intent with same session", TestThreadUtils.runOnUiThreadBlockingNoException(() -> { @@ -1178,7 +1117,9 @@ }); pageLoadFinishedHelper.waitForCallback(0); CriteriaHelper.pollInstrumentationThread(() -> { - Criteria.checkThat(getActivity().getActivityTab().getUrlString(), is(mTestPage2)); + Criteria.checkThat( + ChromeTabUtils.getUrlStringOnUiThread(getActivity().getActivityTab()), + is(mTestPage2)); }); } @@ -1426,7 +1367,7 @@ mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); CriteriaHelper.pollUiThread(() -> { final Tab currentTab = mCustomTabActivityTestRule.getActivity().getActivityTab(); - Criteria.checkThat(currentTab.getUrlString(), is(url)); + Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(currentTab), is(url)); }); CriteriaHelper.pollUiThread(() -> { CustomTabToolbar toolbar = @@ -1455,7 +1396,7 @@ mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); CriteriaHelper.pollInstrumentationThread(() -> { final Tab currentTab = mCustomTabActivityTestRule.getActivity().getActivityTab(); - Criteria.checkThat(currentTab.getUrlString(), is(mTestPage)); + Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(currentTab), is(mTestPage)); }); Assert.assertTrue( connection.postMessage(token, "Message", null) == CustomTabsService.RESULT_SUCCESS); @@ -1487,7 +1428,7 @@ mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); CriteriaHelper.pollInstrumentationThread(() -> { final Tab currentTab = mCustomTabActivityTestRule.getActivity().getActivityTab(); - Criteria.checkThat(currentTab.getUrlString(), is(mTestPage)); + Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(currentTab), is(mTestPage)); }); Assert.assertTrue( connection.postMessage(token, "Message", null) == CustomTabsService.RESULT_SUCCESS); @@ -1525,7 +1466,7 @@ mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); CriteriaHelper.pollInstrumentationThread(() -> { final Tab currentTab = mCustomTabActivityTestRule.getActivity().getActivityTab(); - Criteria.checkThat(currentTab.getUrlString(), is(mTestPage)); + Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(currentTab), is(mTestPage)); }); Assert.assertTrue(connection.postMessage(token, "Message", null) == CustomTabsService.RESULT_FAILURE_MESSAGING_ERROR); @@ -1549,7 +1490,7 @@ mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); CriteriaHelper.pollInstrumentationThread(() -> { final Tab currentTab = mCustomTabActivityTestRule.getActivity().getActivityTab(); - Criteria.checkThat(currentTab.getUrlString(), is(url)); + Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(currentTab), is(url)); }); Assert.assertTrue(connection.postMessage(token, "New title", null) == CustomTabsService.RESULT_SUCCESS); @@ -1627,7 +1568,7 @@ mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); CriteriaHelper.pollInstrumentationThread(() -> { final Tab currentTab = mCustomTabActivityTestRule.getActivity().getActivityTab(); - Criteria.checkThat(currentTab.getUrlString(), is(url)); + Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(currentTab), is(url)); }); session.requestPostMessageChannel(Uri.parse("https://www.example.com/")); @@ -1728,7 +1669,7 @@ CriteriaHelper.pollInstrumentationThread(() -> { final Tab currentTab = mCustomTabActivityTestRule.getActivity().getActivityTab(); - Criteria.checkThat(currentTab.getUrlString(), is(url)); + Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(currentTab), is(url)); }); if (requestTime == AFTER_INTENT) { @@ -1776,7 +1717,7 @@ mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); CriteriaHelper.pollInstrumentationThread(() -> { final Tab currentTab = mCustomTabActivityTestRule.getActivity().getActivityTab(); - Criteria.checkThat(currentTab.getUrlString(), is(mTestPage)); + Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(currentTab), is(mTestPage)); }); Assert.assertFalse(mCustomTabActivityTestRule.getActivity().getActivityTab().canGoBack()); @@ -2235,8 +2176,8 @@ Tab tab = tabbedActivity.get().getActivityTab(); Criteria.checkThat("Tab is null", tab, Matchers.notNullValue()); Criteria.checkThat("Incognito tab not selected", tab.isIncognito(), is(true)); - Criteria.checkThat( - "Wrong URL loaded in incognito tab", tab.getUrlString(), is("about:blank")); + Criteria.checkThat("Wrong URL loaded in incognito tab", + ChromeTabUtils.getUrlStringOnUiThread(tab), is("about:blank")); }); ApplicationStatus.unregisterActivityStateListener(listener); @@ -2448,7 +2389,7 @@ mCustomTabActivityTestRule.startCustomTabActivityWithIntent( CustomTabsTestUtils.createMinimalCustomTabIntent(context, mTestPage)); Tab tab = mCustomTabActivityTestRule.getActivity().getActivityTab(); - assertEquals(mTestPage, tab.getUrlString()); + assertEquals(mTestPage, ChromeTabUtils.getUrlStringOnUiThread(tab)); } private ChromeActivity reparentAndVerifyTab() { @@ -2630,40 +2571,6 @@ ChromeTabUtils.waitForTabPageLoaded(connection.getSpeculationParamsForTesting().tab, url); } - /** - * A helper class to monitor sending status of a {@link PendingIntent}. - */ - private class OnFinishedForTest implements PendingIntent.OnFinished { - - private final PendingIntent mPendingIntent; - private final CallbackHelper mCallbackHelper = new CallbackHelper(); - private Intent mCallbackIntent; - - /** - * Create an instance of {@link OnFinishedForTest}, testing the given {@link PendingIntent}. - */ - public OnFinishedForTest(PendingIntent pendingIntent) { - mPendingIntent = pendingIntent; - } - - public Intent getCallbackIntent() { - return mCallbackIntent; - } - - public void waitForCallback(String failureReason) throws TimeoutException { - mCallbackHelper.waitForCallback(failureReason, 0); - } - - @Override - public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, - String resultData, Bundle resultExtras) { - if (pendingIntent.equals(mPendingIntent)) { - mCallbackIntent = intent; - mCallbackHelper.notifyCalled(); - } - } - } - private static class ElementContentCriteria implements Runnable { private final Tab mTab; private final String mJsFunction;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java index 47c081b..0bda78a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java
@@ -4,26 +4,18 @@ package org.chromium.chrome.browser.customtabs; +import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.res.Resources; +import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.os.Process; import android.support.test.InstrumentationRegistry; - -import org.junit.Assert; - -import org.chromium.base.task.PostTask; -import org.chromium.base.test.util.CallbackHelper; -import org.chromium.chrome.R; -import org.chromium.chrome.browser.document.ChromeLauncherActivity; -import org.chromium.content_public.browser.UiThreadTaskTraits; -import org.chromium.content_public.browser.test.util.CriteriaHelper; -import org.chromium.content_public.browser.test.util.TestThreadUtils; - -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicReference; +import android.view.Menu; +import android.view.MenuItem; import androidx.browser.customtabs.CustomTabsCallback; import androidx.browser.customtabs.CustomTabsClient; @@ -31,6 +23,21 @@ import androidx.browser.customtabs.CustomTabsServiceConnection; import androidx.browser.customtabs.CustomTabsSession; +import org.junit.Assert; + +import org.chromium.base.task.PostTask; +import org.chromium.base.test.util.CallbackHelper; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.IntentHandler; +import org.chromium.chrome.browser.document.ChromeLauncherActivity; +import org.chromium.content_public.browser.UiThreadTaskTraits; +import org.chromium.content_public.browser.test.util.CriteriaHelper; +import org.chromium.content_public.browser.test.util.TestThreadUtils; + +import java.util.ArrayList; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; + /** * Utility class that contains convenience calls related with custom tabs testing. */ @@ -52,6 +59,39 @@ } /** + * A utility class to ensure that a pending intent assigned to a menu item in CCT was invoked. + */ + public static class OnFinishedForTest implements PendingIntent.OnFinished { + private final PendingIntent mPendingIntent; + private final CallbackHelper mCallbackHelper = new CallbackHelper(); + private Intent mCallbackIntent; + + /** + * Create an instance of {@link OnFinishedForTest}, testing the given {@link PendingIntent}. + */ + public OnFinishedForTest(PendingIntent pendingIntent) { + mPendingIntent = pendingIntent; + } + + public Intent getCallbackIntent() { + return mCallbackIntent; + } + + public void waitForCallback(String failureReason) throws TimeoutException { + mCallbackHelper.waitForCallback(failureReason, 0); + } + + @Override + public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, + String resultData, Bundle resultExtras) { + if (pendingIntent.equals(mPendingIntent)) { + mCallbackIntent = intent; + mCallbackHelper.notifyCalled(); + } + } + } + + /** * Creates the simplest intent that is sufficient to let {@link ChromeLauncherActivity} launch * the {@link CustomTabActivity}. */ @@ -68,6 +108,20 @@ return intent; } + /** + * Creates the simplest intent that that is sufficient to let {@link ChromeLauncherActivity} + * launch the incognito {@link CustomTabActivity}. + * + * @param context The instrumentation context to use. + * @param url The URL to load in the incognito CCT. + * @return Returns the intent to launch the incognito CCT. + */ + public static Intent createMinimalIncognitoCustomTabIntent(Context context, String url) { + Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(context, url); + intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true); + return intent; + } + public static CustomTabsConnection setUpConnection() { CustomTabsConnection connection = CustomTabsConnection.getInstance(); connection.resetThrottling(Process.myUid()); @@ -127,4 +181,102 @@ .getAppMenuHandler()::isAppMenuShowing, "App menu was not shown"); } + + public static int getVisibleMenuSize(Menu menu) { + int visibleMenuSize = 0; + for (int i = 0; i < menu.size(); i++) { + MenuItem item = menu.getItem(i); + if (item.isVisible()) visibleMenuSize++; + } + return visibleMenuSize; + } + + /** + * Add a bundle specifying a a number of custom menu entries. + * + * @param customTabIntent The intent to modify. + * @param numEntries The number of menu entries to add. + * @param menuTitle The title of the menu. + * + * @return The pending intent associated with the menu entries. + */ + public static PendingIntent addMenuEntriesToIntent( + Intent customTabIntent, int numEntries, String menuTitle) { + return addMenuEntriesToIntent(customTabIntent, numEntries, new Intent(), menuTitle); + } + + /** + * Add a bundle specifying a custom menu entry. + * + * @param customTabIntent The intent to modify. + * @param numEntries The number of menu entries to add. + * @param callbackIntent The intent to use as the base for the pending intent. + * @param menuTitle The title of the menu. + * + * @return The pending intent associated with the menu entry. + */ + public static PendingIntent addMenuEntriesToIntent( + Intent customTabIntent, int numEntries, Intent callbackIntent, String menuTitle) { + PendingIntent pi = PendingIntent.getBroadcast(InstrumentationRegistry.getTargetContext(), 0, + callbackIntent, PendingIntent.FLAG_UPDATE_CURRENT); + ArrayList<Bundle> menuItems = new ArrayList<>(); + for (int i = 0; i < numEntries; i++) { + Bundle bundle = new Bundle(); + bundle.putString(CustomTabsIntent.KEY_MENU_ITEM_TITLE, menuTitle); + bundle.putParcelable(CustomTabsIntent.KEY_PENDING_INTENT, pi); + menuItems.add(bundle); + } + customTabIntent.putParcelableArrayListExtra(CustomTabsIntent.EXTRA_MENU_ITEMS, menuItems); + return pi; + } + + /** + * Creates a CCT Toolbar menu item bundle. + * + * @param icon The Bitmap icon to be add in the toolbar. + * @param description The description about the icon which will be added. + * @param pi The pending intent that would be triggered when the icon is clicked on. + * @param id A unique id for this new icon. + * + * @return Returns the bundle encapsulating the toolbar item. + */ + public static Bundle makeToolbarItemBundle( + Bitmap icon, String description, PendingIntent pi, int id) { + Bundle bundle = new Bundle(); + bundle.putInt(CustomTabsIntent.KEY_ID, id); + bundle.putParcelable(CustomTabsIntent.KEY_ICON, icon); + bundle.putString(CustomTabsIntent.KEY_DESCRIPTION, description); + bundle.putParcelable(CustomTabsIntent.KEY_PENDING_INTENT, pi); + bundle.putBoolean(CustomButtonParams.SHOW_ON_TOOLBAR, true); + return bundle; + } + + /** + * Adds an action button to the custom tab toolbar. + * + * @param intent The intent where the action button would be added. + * @param icon The icon representing the action button. + * @param description The description associated with the action button. + * @param id The unique id that would be used for this new Action button. + * + * @return The {@link PendingIntent} that will be triggered when the action button is clicked. + */ + public static PendingIntent addActionButtonToIntent( + Intent intent, Bitmap icon, String description, int id) { + PendingIntent pi = PendingIntent.getBroadcast( + InstrumentationRegistry.getTargetContext(), 0, new Intent(), 0); + intent.putExtra(CustomTabsIntent.EXTRA_ACTION_BUTTON_BUNDLE, + makeToolbarItemBundle(icon, description, pi, id)); + return pi; + } + + /** + * @return The test bitmap which can be used to represent an action item on the Toolbar. + */ + public static Bitmap createTestBitmap(int widthDp, int heightDp) { + Resources testRes = InstrumentationRegistry.getTargetContext().getResources(); + float density = testRes.getDisplayMetrics().density; + return Bitmap.createBitmap( + (int) (widthDp * density), (int) (heightDp * density), Bitmap.Config.ARGB_8888); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java index adb6e38..a186597 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabControllerTest.java
@@ -34,6 +34,7 @@ import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; +import org.chromium.chrome.test.util.ChromeTabUtils; import java.util.Arrays; import java.util.List; @@ -96,7 +97,8 @@ ((CustomTabActivityTestRule) mActivityTestRule).startCustomTabActivityWithIntent(intent); CustomTabActivityTabProvider tabProvider = getActivityTabProvider(); - assertEquals(mediaViewerUrl, tabProvider.getTab().getUrl().getSpec()); + assertEquals( + mediaViewerUrl, ChromeTabUtils.getUrlOnUiThread(tabProvider.getTab()).getSpec()); assertNotEquals(TabCreationMode.FROM_STARTUP_TAB_PRELOADER, tabProvider.getInitialTabCreationMode()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeTest.java index bd37b28..eef8cc8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/ReaderModeTest.java
@@ -209,7 +209,7 @@ // Load the page that has an offline copy. The offline page should be shown. Tab tab = mDownloadTestRule.getActivity().getActivityTab(); Assert.assertFalse(isOfflinePage(tab)); - mDownloadTestRule.loadUrl(tab.getUrl().getSpec()); + mDownloadTestRule.loadUrl(ChromeTabUtils.getUrlOnUiThread(tab).getSpec()); Assert.assertTrue(isOfflinePage(tab)); } @@ -430,7 +430,9 @@ private void waitForDistillation(@SuppressWarnings("SameParameterValue") String expectedTitle, Tab tab) throws TimeoutException { CriteriaHelper.pollUiThread( - () -> Criteria.checkThat(tab.getUrl().getScheme(), is("chrome-distiller"))); + () + -> Criteria.checkThat(ChromeTabUtils.getUrlOnUiThread(tab).getScheme(), + is("chrome-distiller"))); ChromeTabUtils.waitForTabPageLoaded(tab, null); // Distiller Viewer load the content dynamically, so waitForTabPageLoaded() is not enough. CriteriaHelper.pollUiThread(() -> Criteria.checkThat(tab.getTitle(), is(expectedTitle)));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogTest.java index 33fd454..3eb8a645 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogTest.java
@@ -7,9 +7,11 @@ import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.Matchers.not; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; @@ -21,6 +23,7 @@ import static org.mockito.Mockito.when; import android.view.View; +import android.widget.CheckBox; import androidx.test.espresso.NoMatchingViewException; import androidx.test.filters.MediumTest; @@ -88,20 +91,33 @@ mActivityTestRule.startMainActivityOnBlankPage(); mDialogCoordinator = new DownloadLaterDialogCoordinator(mDateTimePicker); - mModel = new PropertyModel.Builder(DownloadLaterDialogProperties.ALL_KEYS) - .with(DownloadLaterDialogProperties.CONTROLLER, mDialogCoordinator) - .with(DownloadLaterDialogProperties.INITIAL_CHOICE, - DownloadLaterDialogChoice.ON_WIFI) - .with(DownloadLaterDialogProperties.DONT_SHOW_AGAIN_SELECTION, - DownloadLaterPromptStatus.SHOW_INITIAL) - .build(); + mModel = createModel( + DownloadLaterDialogChoice.ON_WIFI, DownloadLaterPromptStatus.SHOW_INITIAL); + Assert.assertNotNull(mController); mDialogCoordinator.initialize(mController); } + private PropertyModel createModel(Integer choice, Integer promptStatus) { + PropertyModel.Builder builder = + new PropertyModel.Builder(DownloadLaterDialogProperties.ALL_KEYS) + .with(DownloadLaterDialogProperties.CONTROLLER, mDialogCoordinator); + if (choice != null) { + builder.with(DownloadLaterDialogProperties.INITIAL_CHOICE, choice); + } + + if (promptStatus != null) { + builder.with(DownloadLaterDialogProperties.DONT_SHOW_AGAIN_SELECTION, promptStatus); + } + + return builder.build(); + } + private void showDialog() { - mDialogCoordinator.showDialog( - mActivityTestRule.getActivity(), getModalDialogManager(), mPrefService, mModel); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mDialogCoordinator.showDialog( + mActivityTestRule.getActivity(), getModalDialogManager(), mPrefService, mModel); + }); } private void clickPositiveButton() { @@ -112,23 +128,87 @@ onView(withId(org.chromium.chrome.R.id.negative_button)).perform(click()); } + private void assertPositiveButtonText(String expectedText) { + onView(withId(org.chromium.chrome.R.id.positive_button)) + .check(matches(withText(expectedText))); + } + + private void assertShowAgainCheckBox(boolean enabled, int visibility, boolean checked) { + onView(withId(R.id.show_again_checkbox)).check((View view, NoMatchingViewException e) -> { + Assert.assertEquals(enabled, view.isEnabled()); + Assert.assertEquals(visibility, view.getVisibility()); + if (visibility == View.VISIBLE) { + Assert.assertEquals(checked, ((CheckBox) (view)).isChecked()); + } + }); + } + + private void assertEditText(boolean hasEditText) { + if (hasEditText) { + onView(withId(R.id.edit_location)).check(matches(isDisplayed())); + } else { + onView(withId(R.id.edit_location)).check(matches(not(isDisplayed()))); + } + } + @Test @MediumTest - public void testShowDialogThenDismiss() { - TestThreadUtils.runOnUiThreadBlocking(() -> { - showDialog(); - }); + public void testInitialSelectionDownloadNowWithOutCheckbox() { + mModel = createModel(DownloadLaterDialogChoice.DOWNLOAD_NOW, null); + showDialog(); + assertPositiveButtonText("Download"); + assertShowAgainCheckBox(true, View.GONE, true); + assertEditText(false); + } + @Test + @MediumTest + public void testInitialSelectionOnWifiWithCheckbox() { + mModel = createModel( + DownloadLaterDialogChoice.ON_WIFI, DownloadLaterPromptStatus.SHOW_INITIAL); + showDialog(); + assertPositiveButtonText("Download"); + assertShowAgainCheckBox(true, View.VISIBLE, true); + assertEditText(false); + } + + @Test + @MediumTest + public void testInitialSelectionOnWifiWithEditLocation() { + mModel = createModel( + DownloadLaterDialogChoice.ON_WIFI, DownloadLaterPromptStatus.SHOW_PREFERENCE); + mModel.set(DownloadLaterDialogProperties.LOCATION_TEXT, "location"); + showDialog(); + assertPositiveButtonText("Download"); + assertShowAgainCheckBox(true, View.VISIBLE, false); + assertEditText(true); + } + + @Test + @MediumTest + public void testInitialSelectionDownloadLater() { + mModel = createModel( + DownloadLaterDialogChoice.DOWNLOAD_LATER, DownloadLaterPromptStatus.SHOW_INITIAL); + showDialog(); + assertPositiveButtonText("Next"); + assertShowAgainCheckBox(false, View.VISIBLE, true); + assertEditText(false); + } + + @Test + @MediumTest + public void testClickNegativeButtonShouldCancel() { + showDialog(); clickNegativeButton(); verify(mController).onDownloadLaterDialogCanceled(); } @Test @MediumTest - public void testSelectRadioButton() { - TestThreadUtils.runOnUiThreadBlocking(() -> { - showDialog(); + public void testSelectFromOnWifiToDownloadNow() { + showDialog(); + TestThreadUtils.runOnUiThreadBlocking(() -> { // Verify the initial selection of the dialog. The controller should not get an event // for the initial setup. RadioButtonWithDescription onWifiButton = @@ -153,10 +233,10 @@ @Test @MediumTest - public void testSelectDownloadLater() { - TestThreadUtils.runOnUiThreadBlocking(() -> { - showDialog(); + public void testSelectFromOnWifiToDownloadLater() { + showDialog(); + TestThreadUtils.runOnUiThreadBlocking(() -> { RadioButtonWithDescription downloadLaterButton = getDownloadLaterDialogView().findViewById(R.id.choose_date_time); Assert.assertNotNull(downloadLaterButton); @@ -164,10 +244,8 @@ getDownloadLaterDialogView().onCheckedChanged(null, -1); }); - onView(withId(org.chromium.chrome.R.id.positive_button)).check(matches(withText("Next"))); - onView(withId(R.id.show_again_checkbox)).check((View view, NoMatchingViewException e) -> { - Assert.assertFalse(view.isEnabled()); - }); + assertPositiveButtonText("Next"); + assertShowAgainCheckBox(false, View.VISIBLE, true); clickPositiveButton(); verify(mController, times(0)).onDownloadLaterDialogComplete(anyInt(), anyLong());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java index fa26608e..19a56e1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java
@@ -97,8 +97,11 @@ private void assertNavigateOnSwipeFrom(boolean edge, String toUrl) { ChromeTabUtils.waitForTabPageLoaded(currentTab(), toUrl, () -> swipeFromEdge(edge), 10); CriteriaHelper.pollUiThread( - () -> Criteria.checkThat(currentTab().getUrlString(), Matchers.is(toUrl))); - Assert.assertEquals("Didn't navigate back", toUrl, currentTab().getUrlString()); + () + -> Criteria.checkThat(ChromeTabUtils.getUrlStringOnUiThread(currentTab()), + Matchers.is(toUrl))); + Assert.assertEquals( + "Didn't navigate back", toUrl, ChromeTabUtils.getUrlStringOnUiThread(currentTab())); } private void swipeFromEdge(boolean leftEdge) { @@ -145,7 +148,7 @@ CriteriaHelper.pollUiThread(mNavigationLayout::isLayoutDetached, "Navigation Layout should be detached after use"); Assert.assertEquals("Current page should not change", UrlConstants.NTP_URL, - currentTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread(currentTab())); } @Test @@ -224,7 +227,7 @@ mActivityTestRule.getActivity().isInOverviewMode()); setTabSwitcherModeAndWait(false); Assert.assertEquals("Current page should not change", UrlConstants.RECENT_TABS_URL, - currentTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread(currentTab())); } /**
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 6494f8e..fab4a56 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
@@ -140,7 +140,8 @@ destroyAndRestartActivity(); Assert.assertEquals("Start up homepage should be the same as the policy setting", TEST_URL, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); } @Test @@ -152,7 +153,8 @@ .fullyLoadUrl(anotherUrl); Assert.assertNotEquals("Did not switch to a different URL", TEST_URL, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); ChromeTabUtils.waitForTabPageLoaded( mActivityTestRule.getActivity().getActivityTab(), TEST_URL, () -> { @@ -173,7 +175,8 @@ }); Assert.assertEquals("After clicking HomeButton, URL should be back to Homepage", TEST_URL, - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); } @Test @@ -226,6 +229,7 @@ // Start a new ChromeActivity. mActivityTestRule.startActivityCompletely(intent); Assert.assertEquals("Start up page is not homepage", HomepageManager.getHomepageUri(), - mActivityTestRule.getActivity().getActivityTab().getUrlString()); + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageNavigationTest.java index 35e33ab..23fc7ae 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageNavigationTest.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.net.test.EmbeddedTestServer; @@ -56,7 +57,7 @@ public void testNTPIsDefault() { Tab tab = mActivityTestRule.getActivity().getActivityTab(); Assert.assertNotNull(tab); - String url = tab.getUrlString(); + String url = ChromeTabUtils.getUrlStringOnUiThread(tab); Assert.assertTrue("Unexpected url: " + url, url.startsWith("chrome-native://newtab/") || url.startsWith("chrome-native://bookmarks/") @@ -72,7 +73,9 @@ public void testNavigatingFromNTP() { String url = mTestServer.getURL("/chrome/test/data/android/google.html"); mActivityTestRule.loadUrl(url); - Assert.assertEquals(url, mActivityTestRule.getActivity().getActivityTab().getUrlString()); + Assert.assertEquals(url, + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); } /** @@ -84,12 +87,14 @@ public void testNavigateBackToNTPViaUrl() { String url = mTestServer.getURL("/chrome/test/data/android/google.html"); mActivityTestRule.loadUrl(url); - Assert.assertEquals(url, mActivityTestRule.getActivity().getActivityTab().getUrlString()); + Assert.assertEquals(url, + ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab())); mActivityTestRule.loadUrl(UrlConstants.NTP_URL); Tab tab = mActivityTestRule.getActivity().getActivityTab(); Assert.assertNotNull(tab); - url = tab.getUrlString(); + url = ChromeTabUtils.getUrlStringOnUiThread(tab); Assert.assertEquals(UrlConstants.NTP_URL, url); // Check that the NTP is actually displayed.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index 951a51554..22a4028c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -258,7 +258,8 @@ TouchCommon.singleClickView(mostVisitedItem); } }); - Assert.assertEquals(mSiteSuggestions.get(0).url, mTab.getUrlString()); + Assert.assertEquals( + mSiteSuggestions.get(0).url, ChromeTabUtils.getUrlStringOnUiThread(mTab)); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/promo/HomepagePromoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/promo/HomepagePromoTest.java index 66d8d080..1e8f217 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/promo/HomepagePromoTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/cards/promo/HomepagePromoTest.java
@@ -491,8 +491,11 @@ private void scrollToHomepagePromo() { onView(instanceOf(RecyclerView.class)) .perform(RecyclerViewActions.scrollToPosition(NTP_HEADER_POSITION + 1)); - waitForView((ViewGroup) mActivityTestRule.getActivity().findViewById(R.id.homepage_promo), - allOf(withId(R.id.promo_primary_button), isDisplayed())); + TestThreadUtils.runOnUiThreadBlocking(() -> { + waitForView( + (ViewGroup) mActivityTestRule.getActivity().findViewById(R.id.homepage_promo), + allOf(withId(R.id.promo_primary_button), isDisplayed())); + }); // Verify impress tracking metrics is working. Assert.assertEquals("Promo created should be seen.", 1,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerTest.java index c43885a..321e02a8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/indicator/OfflineIndicatorControllerTest.java
@@ -351,7 +351,7 @@ Tab tab = mActivityTestRule.getActivity().getActivityTab(); mActivityTestRule.loadUrl(pageUrl); - Assert.assertEquals(pageUrl, tab.getUrlString()); + Assert.assertEquals(pageUrl, ChromeTabUtils.getUrlStringOnUiThread(tab)); if (mIsConnected) { Assert.assertFalse(isErrorPage(tab)); Assert.assertFalse(isOfflinePage(tab));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java index b2c148c..c27b059 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java
@@ -49,6 +49,7 @@ import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.base.Clipboard; +import org.chromium.ui.base.ClipboardAndroidTestSupport; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.url.GURL; @@ -156,6 +157,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { Clipboard.getInstance().overrideClipboardManagerForTesting(mOldClipboardManager); }); + ClipboardAndroidTestSupport.cleanup(); } /** Test that the suggestion is triggered. */
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 5c6eda6..2bb2bd2 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
@@ -76,7 +76,8 @@ @Feature({"Homepage"}) public void testHomepageInitialLoading() { Assert.assertEquals(Uri.parse(TestPartnerBrowserCustomizationsProvider.HOMEPAGE_URI), - Uri.parse(mActivityTestRule.getActivity().getActivityTab().getUrlString())); + Uri.parse(ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab()))); } /** @@ -93,7 +94,8 @@ mActivityTestRule.loadUrl(testServer.getURL(TEST_PAGE)); UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation()); Assert.assertNotSame(Uri.parse(TestPartnerBrowserCustomizationsProvider.HOMEPAGE_URI), - Uri.parse(mActivityTestRule.getActivity().getActivityTab().getUrlString())); + Uri.parse(ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab()))); // Click homepage button. ChromeTabUtils.waitForTabPageLoaded(mActivityTestRule.getActivity().getActivityTab(), @@ -108,7 +110,8 @@ } }); Assert.assertEquals(Uri.parse(TestPartnerBrowserCustomizationsProvider.HOMEPAGE_URI), - Uri.parse(mActivityTestRule.getActivity().getActivityTab().getUrlString())); + Uri.parse(ChromeTabUtils.getUrlStringOnUiThread( + mActivityTestRule.getActivity().getActivityTab()))); } finally { testServer.stopAndDestroyServer(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/OmniboxQueryTileSuggestionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/OmniboxQueryTileSuggestionTest.java index c72422f..c8ff83e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/OmniboxQueryTileSuggestionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/OmniboxQueryTileSuggestionTest.java
@@ -45,6 +45,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.NewTabPageTestUtils; import org.chromium.chrome.test.util.OmniboxTestUtils; import org.chromium.chrome.test.util.browser.Features; @@ -235,7 +236,8 @@ } private String getTabUrl() { - return mActivityTestRule.getActivity().getActivityTab().getUrl().getValidSpecOrEmpty(); + return ChromeTabUtils.getUrlOnUiThread(mActivityTestRule.getActivity().getActivityTab()) + .getValidSpecOrEmpty(); } private void waitForOmniboxQueryTileSuggestion(boolean visible) { @@ -253,7 +255,8 @@ private void waitForSearchResultsPage() { CriteriaHelper.pollUiThread(() -> { - Criteria.checkThat("The SRP was never loaded.", mTab.getUrl().getValidSpecOrEmpty(), + Criteria.checkThat("The SRP was never loaded.", + ChromeTabUtils.getUrlOnUiThread(mTab).getValidSpecOrEmpty(), Matchers.containsString(SEARCH_URL_PATTERN)); }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionTest.java index 7fb46ecb0..4bb2037 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/query_tiles/QueryTileSectionTest.java
@@ -40,6 +40,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.NewTabPageTestUtils; import org.chromium.chrome.test.util.OmniboxTestUtils; import org.chromium.chrome.test.util.browser.Features; @@ -209,12 +210,14 @@ } private String getTabUrl() { - return mActivityTestRule.getActivity().getActivityTab().getUrl().getValidSpecOrEmpty(); + return ChromeTabUtils.getUrlOnUiThread(mActivityTestRule.getActivity().getActivityTab()) + .getValidSpecOrEmpty(); } private void waitForSearchResultsPage() { CriteriaHelper.pollUiThread(() -> { - Criteria.checkThat("The SRP was never loaded.", mTab.getUrl().getValidSpecOrEmpty(), + Criteria.checkThat("The SRP was never loaded.", + ChromeTabUtils.getUrlOnUiThread(mTab).getValidSpecOrEmpty(), Matchers.containsString(SEARCH_URL_PATTERN)); }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationControllerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationControllerIntegrationTest.java index 2b0cd07..1b7b9fce 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationControllerIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/reengagement/ReengagementNotificationControllerIntegrationTest.java
@@ -54,6 +54,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.feature_engagement.Tracker; @@ -294,7 +295,7 @@ tabAddedCallback.waitForCallback(0); Tab tab = TestThreadUtils.runOnUiThreadBlocking( () -> mTabbedActivityTestRule.getActivity().getActivityTab()); - Assert.assertTrue(NewTabPage.isNTPUrl(tab.getUrl())); + Assert.assertTrue(NewTabPage.isNTPUrl(ChromeTabUtils.getUrlOnUiThread(tab))); Assert.assertFalse(tab.isIncognito()); Assert.assertEquals(initialTabCount + 1, mTabbedActivityTestRule.getActivity().getTabModelSelector().getTotalTabCount());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java index c955f64..28f16543 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninSignoutIntegrationTest.java
@@ -216,7 +216,9 @@ mBookmarkModel = new BookmarkModel(Profile.fromWebContents( mActivityTestRule.getActivity().getActivityTab().getWebContents())); mBookmarkModel.loadFakePartnerBookmarkShimForTesting(); - BookmarkTestUtil.waitForBookmarkModelLoaded(); + }); + BookmarkTestUtil.waitForBookmarkModelLoaded(); + TestThreadUtils.runOnUiThreadBlocking(() -> { Assert.assertEquals(0, mBookmarkModel.getChildCount(mBookmarkModel.getDefaultFolder())); mBookmarkModel.addBookmark( mBookmarkModel.getDefaultFolder(), 0, "Test Bookmark", "http://google.com");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java index 059982c..f1a7036 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabDataTest.java
@@ -43,7 +43,7 @@ private static final String APP_ID = "AppId"; private static final String OPENER_APP_ID = "OpenerAppId"; private static final int THEME_COLOR = 5; - private static final int LAUNCH_TYPE_AT_CREATION = 3; + private static final Integer LAUNCH_TYPE_AT_CREATION = 3; static { WEB_CONTENTS_STATE.buffer().put(WEB_CONTENTS_STATE_BYTES);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java index ef743182..c5e501e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
@@ -1462,7 +1462,7 @@ tab0 = model.getTabAt(0); Tab tab1 = model.getTabAt(1); tabs = new Tab[]{tab0, tab1}; - Assert.assertEquals(TEST_URL_0, tab1.getUrlString()); + Assert.assertEquals(TEST_URL_0, ChromeTabUtils.getUrlStringOnUiThread(tab1)); checkState(model, tabs, tab0, EMPTY, tabs, tab0); } @@ -1537,8 +1537,8 @@ firstModelTab); checkState(secondModel, secondWindowTabs, secondModelTab, EMPTY, secondWindowTabs, secondModelTab); - Assert.assertEquals(TEST_URL_0, firstWindowTabs[1].getUrlString()); - Assert.assertEquals(TEST_URL_1, secondWindowTabs[1].getUrlString()); + Assert.assertEquals(TEST_URL_0, ChromeTabUtils.getUrlStringOnUiThread(firstWindowTabs[1])); + Assert.assertEquals(TEST_URL_1, ChromeTabUtils.getUrlStringOnUiThread(secondWindowTabs[1])); secondActivity.finishAndRemoveTask(); } @@ -1602,6 +1602,6 @@ Tab tab1 = firstModel.getTabAt(1); Tab[] firstWindowTabs = new Tab[]{tab0, tab1}; checkState(firstModel, firstWindowTabs, tab0, EMPTY, firstWindowTabs, tab0); - Assert.assertEquals(TEST_URL_1, tab1.getUrlString()); + Assert.assertEquals(TEST_URL_1, ChromeTabUtils.getUrlStringOnUiThread(tab1)); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java index be3f220c..884ab05 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java
@@ -32,6 +32,7 @@ import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.MenuUtils; import org.chromium.chrome.test.util.OmniboxTestUtils; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; @@ -126,7 +127,7 @@ // Load new tab page. mActivityTestRule.loadUrl(UrlConstants.NTP_URL); - Assert.assertEquals(UrlConstants.NTP_URL, tab.getUrlString()); + Assert.assertEquals(UrlConstants.NTP_URL, ChromeTabUtils.getUrlStringOnUiThread(tab)); assertFalse(isErrorPage(tab)); // Stop the server and also disconnect the network. @@ -135,7 +136,7 @@ () -> NetworkChangeNotifier.forceConnectivityState(false)); mActivityTestRule.loadUrl(testUrl); - Assert.assertEquals(testUrl, tab.getUrlString()); + Assert.assertEquals(testUrl, ChromeTabUtils.getUrlStringOnUiThread(tab)); assertTrue(isErrorPage(tab)); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java index 015f40d..f2587a5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappNavigationTest.java
@@ -356,7 +356,7 @@ String otherInScopeUrl = WebappTestPage.getNonServiceWorkerUrl(mActivityTestRule.getTestServer()); mActivityTestRule.loadUrlInTab(otherInScopeUrl, PageTransition.LINK, tab); - assertEquals(otherInScopeUrl, tab.getUrlString()); + assertEquals(otherInScopeUrl, ChromeTabUtils.getUrlStringOnUiThread(tab)); mActivityTestRule.loadUrlInTab( offOriginUrl(), PageTransition.LINK, tab, 10 /* secondsToWait */);
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/UnitTestUtils.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/UnitTestUtils.java deleted file mode 100644 index 8c140e2..0000000 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/UnitTestUtils.java +++ /dev/null
@@ -1,51 +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. - -package org.chromium.chrome.browser; - -import android.os.Handler; -import android.os.Looper; - -import org.junit.Assert; - -import org.chromium.base.ThreadUtils; -import org.chromium.base.test.util.TimeoutTimer; -import org.chromium.content_public.browser.test.NestedSystemMessageHandler; -import org.chromium.content_public.browser.test.util.CriteriaHelper; - -import java.util.concurrent.Callable; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Utilities for use in Native Java Unit Tests. - */ -public class UnitTestUtils { - /** - * Polls the UI thread waiting for the Callable |criteria| to return true. - * - * In practice, this nests the looper and checks the criteria after each task is run as these - * tests run on the UI thread and sleeping would block the thing we're waiting for. - */ - public static void pollUiThread(final Callable<Boolean> criteria) throws Exception { - assert ThreadUtils.runningOnUiThread(); - boolean isSatisfied = criteria.call(); - TimeoutTimer timer = new TimeoutTimer(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL); - Handler handler = new Handler(Looper.myLooper()); - AtomicBoolean called = new AtomicBoolean(true); - - while (!isSatisfied && !timer.isTimedOut()) { - // Ensure we pump the message handler in case no new tasks arrive. - if (called.get()) { - called.set(false); - handler.postDelayed( - () -> { called.set(true); }, CriteriaHelper.DEFAULT_POLLING_INTERVAL); - } - - NestedSystemMessageHandler.runSingleNestedLooperTask(Looper.myQueue()); - isSatisfied = criteria.call(); - } - Assert.assertFalse("Timed out waiting for condition", timer.isTimedOut()); - Assert.assertTrue(isSatisfied); - } -} \ No newline at end of file
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderTest.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderTest.java index e6a2ffa..6c48a17 100644 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderTest.java +++ b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderTest.java
@@ -18,9 +18,9 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNativeJavaTest; import org.chromium.base.annotations.DisabledCalledByNativeJavaTest; -import org.chromium.chrome.browser.UnitTestUtils; import org.chromium.chrome.browser.instantapps.InstantAppsHandler; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.installedapp.mojom.InstalledAppProvider; import org.chromium.installedapp.mojom.RelatedApplication; import org.chromium.url.GURL; @@ -372,7 +372,7 @@ called.set(true); } }); - UnitTestUtils.pollUiThread(() -> called.get()); + CriteriaHelper.pollUiThreadNested(() -> called.get()); } @CalledByNative
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppUnitTest.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppUnitTest.java index d906537..86f028b 100644 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppUnitTest.java +++ b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppUnitTest.java
@@ -14,10 +14,10 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNativeJavaTest; -import org.chromium.chrome.browser.UnitTestUtils; import org.chromium.components.payments.PayerData; import org.chromium.components.payments.PaymentApp; import org.chromium.components.payments.SupportedDelegations; +import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.payments.mojom.PaymentCurrencyAmount; import org.chromium.payments.mojom.PaymentDetailsModifier; import org.chromium.payments.mojom.PaymentItem; @@ -93,7 +93,7 @@ mReadyToPayResponse = isReadyToPay; } }); - UnitTestUtils.pollUiThread(() -> mReadyToPayQueryFinished); + CriteriaHelper.pollUiThreadNested(() -> mReadyToPayQueryFinished); Assert.assertTrue("Payment app should be ready to pay", mReadyToPayResponse); PaymentItem total = new PaymentItem(); @@ -131,6 +131,6 @@ intentResult.data.putExtras(extras); app.onIntentCompletedForTesting(intentResult); - UnitTestUtils.pollUiThread(() -> mInvokePaymentAppFinished); + CriteriaHelper.pollUiThreadNested(() -> mInvokePaymentAppFinished); } }
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java index 0b46212..25c4f40 100644 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java +++ b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java
@@ -26,7 +26,6 @@ import org.chromium.base.annotations.CalledByNativeJavaTest; import org.chromium.base.task.TaskRunner; import org.chromium.base.test.util.Feature; -import org.chromium.chrome.browser.UnitTestUtils; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; @@ -35,6 +34,7 @@ import org.chromium.chrome.browser.tabmodel.TabPersistentStore.TabRestoreDetails; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.test.util.CriteriaHelper; import java.util.concurrent.atomic.AtomicBoolean; @@ -88,7 +88,7 @@ // Flush pending PersistentStore tasks. final AtomicBoolean flushed = new AtomicBoolean(false); mPersistentStore.getTaskRunnerForTests().postTask(() -> { flushed.set(true); }); - UnitTestUtils.pollUiThread(() -> flushed.get()); + CriteriaHelper.pollUiThreadNested(() -> flushed.get()); } @CalledByNativeJavaTest
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 1535f083..4f491cf 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -5432,6 +5432,66 @@ Hide password </message> + <!-- Borealis strings --> + <!-- TODO(danielng): Add string descriptions and remove translateable tags + when strings are finalized. --> + <message name="IDS_BOREALIS_APP_NAME" desc="" translateable="false"> + Borealis + </message> + <message name="IDS_BOREALIS_INSTALLER_CONFIRMATION_TITLE" desc="" translateable="false"> + Set up <ph name="APP_NAME">$1<ex>BOREALIS</ex></ph> + </message> + <message name="IDS_BOREALIS_INSTALLER_CONFIRMATION_MESSAGE" desc="" translateable="false"> + Set up Borealis on your device. + </message> + <message name="IDS_BOREALIS_INSTALLER_INSTALL_BUTTON" desc="" translateable="false"> + Install + </message> + <message name="IDS_BOREALIS_INSTALLER_ENVIRONMENT_SETTING_TITLE" desc="" translateable="false"> + Setting up <ph name="APP_NAME">$1<ex>BOREALIS</ex></ph>... + </message> + <message name="IDS_BOREALIS_INSTALLER_ERROR_TITLE" desc="" translateable="false"> + Setup couldn't complete + </message> + <message name="IDS_BOREALIS_INSTALLER_FINISHED_TITLE" desc="" translateable="false"> + Setup complete + </message> + <message name="IDS_BOREALIS_INSTALLER_IMPORTING_MESSAGE" desc="" translateable="false"> + Configuring the virtual machine. This may take a few minutes. + </message> + <message name="IDS_BOREALIS_INSTALLER_IMPORTED_MESSAGE" desc="" translateable="false"> + <ph name="APP_NAME">$1<ex>BOREALIS</ex></ph> is ready to use. + </message> + <message name="IDS_BOREALIS_INSTALLER_ERROR_MESSAGE" desc="" translateable="false"> + Something went wrong. + </message> + <message name="IDS_BOREALIS_INSTALLER_RETRY_BUTTON" desc="" translateable="false"> + Retry + </message> + <message name="IDS_BOREALIS_INSTALLER_LAUNCH_BUTTON" desc="" translateable="false"> + Launch + </message> + <message name="IDS_BOREALIS_INSTALLER_NOT_ALLOWED_TITLE" desc="" translateable="false"> + <ph name="APP_NAME">$1<ex>BOREALIS</ex></ph> needs permission to run + </message> + <message name="IDS_BOREALIS_INSTALLER_NOT_ALLOWED_MESSAGE" desc="" translateable="false"> + <ph name="APP_NAME">$1<ex>BOREALIS</ex></ph> isn't allowed on this device. Contact your administrator. Error code: <ph name="ERROR_CODE">$2<ex>7</ex></ph>. + </message> + <message name="IDS_BOREALIS_DLC_INTERNAL_FAILED_MESSAGE" desc="" translateable="false"> + Your device needs to be updated before you can use <ph name="APP_NAME">$1<ex>BOREALIS</ex></ph>. + </message> + <message name="IDS_BOREALIS_DLC_BUSY_FAILED_MESSAGE" desc="" translateable="false"> + Something went wrong. Please wait a few minutes and run <ph name="APP_NAME">$1<ex>BOREALIS</ex></ph> again. + </message> + <message name="IDS_BOREALIS_DLC_NEED_REBOOT_FAILED_MESSAGE" desc="" translateable="false"> + Please restart your device to use <ph name="APP_NAME">$1<ex>BOREALIS</ex></ph>. + </message> + <message name="IDS_BOREALIS_INSUFFICIENT_DISK_SPACE_MESSAGE" desc="" translateable="false"> + Your device is low on storage. To increase free space, delete files from device. + </message> + <message name="IDS_BOREALIS_GENERIC_ERROR_MESSAGE" desc="" translateable="false"> + Couldn't install <ph name="APP_NAME">$1<ex>BOREALIS</ex></ph>. Please try again later. + </message> <!-- ================================================================================== If you change any IDS_EDU_LOGIN_INFO_* string, update kConsentScreenTextVersion in
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp index e91eee1..1122f0f 100644 --- a/chrome/app/os_settings_search_tag_strings.grdp +++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -859,6 +859,12 @@ <message name="IDS_OS_SETTINGS_TAG_INPUT" translateable="false" desc="Text for search result item which, when clicked, navigates the user to input settings."> Input </message> + <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_CHANGE_SYSTEM_LANGUAGE" translateable="false" desc="Text for search result item which, when clicked, navigates the user to languages and input settings, with allows users to change system display language."> + Change system language + </message> + <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_OFFER_TRANSLATION" translateable="false" desc="Text for search result item which, when clicked, navigates the user to languages and input settings, with a toggle to enable/disable translation prompts."> + Translation suggestion + </message> <message name="IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT_ADD_LANGUAGE" desc="Text for search result item which, when clicked, navigates the user to languages and input settings, with an option to add a new language."> Add languages </message>
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 2cfc274..ec09d56 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -247,6 +247,30 @@ <message name="IDS_OS_SETTINGS_LANGUAGES_INPUT_PAGE_TITLE" translateable="false" desc="A page under “Languages and input” section in the OS settings page that users can add, remove and manage input methods."> Input </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_SYSTEM_LANGUAGE_TITLE" translateable="false" desc="The label for the section where users can see their display language. This language will be used for system surfaces (launcher, shelf, and notifications etc.) and the preferred application language if it’s provided by the application developer."> + System display language + </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_SYSTEM_LANGUAGE_DESCRIPTION" translateable="false" desc="The description for the section where users can see their display language. This language will be used for system surfaces (launcher, shelf, and notifications etc.) and the preferred application language if it’s provided by the application developer."> + System features like launcher, Settings and Files will appear in this language. + </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_CHANGE_SYSTEM_LANGUAGE_BUTTON_LABEL" translateable="false" desc="The label for the button where users can change their display language. This language will be used for system surfaces (launcher, shelf, and notifications etc.) and the preferred application language if it’s provided by the application developer."> + Change + </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_CHANGE_SYSTEM_LANGUAGE_BUTTON_DESCRIPTION" translateable="false" desc="The description read by screenreader for the button where users can change their display language. This language will be used for system surfaces (launcher, shelf, and notifications etc.) and the preferred application language if it’s provided by the application developer."> + Change system language. Current language is <ph name="LANGUAGE">$1<ex>English</ex></ph>. System features like launcher, Settings and Files will appear in the language you choose. + </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PREFERENCE_TITLE" translateable="false" desc="The label of the section in the language settings page where users can add languages they read to an ordered list. The web content languages will be served in the order of the list."> + Languages you read + </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PREFERENCE_DESCRIPTION" translateable="false" desc="The description of the section in the language settings page where users can add languages they read to an ordered list. The web content languages will be served in the order of the list."> + Add and order languages you read. Apps and websites will be displayed in the most preferred language available. <ph name="BEGIN_LINK_LEARN_MORE"><a target="_blank" href="$1"></ph>Learn more<ph name="END_LINK_LEARN_MORE"></a></ph> + </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_OFFER_TRANSLATION_LABEL" translateable="false" desc="The label of the toggle that enables the prompt to translate a page to users."> + Translation suggestion + </message> + <message name="IDS_OS_SETTINGS_LANGUAGES_OFFER_TRANSLATION_SUBLABEL" translateable="false" desc="The sublabel of the toggle that enables the prompt to translate a page to users."> + Allow the system to offer to translate web pages when it detects languages you don't read + </message> <message name="IDS_OS_SETTINGS_LANGUAGES_LIST_TITLE" desc="Title for the list of the user's preferred written languages."> Languages </message> @@ -457,7 +481,7 @@ Change device account image </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_TITLE" desc="Label for row in settings page that opens the ambient mode settings page to customize what you see on your screen when the device is idle."> - Ambient mode + Screen saver </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_ENABLED" desc="Sub label for the ambient mode row in settings page when it is enabled."> Enabled @@ -465,8 +489,10 @@ <message name="IDS_OS_SETTINGS_AMBIENT_MODE_DISABLED" desc="Sub label for the ambient mode row in settings page when it is disabled."> Disabled </message> + + <!-- Ambient Mode Page --> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_PAGE_DESCRIPTION" desc="Description for the ambient mode settings page."> - Personalize your idle display. Keep your screen on when device is charging. + When your screen is idle, show photos, time, weather, and media info </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_ON" desc="Label for the toggle row in ambient mode settings page when it is enabled."> On @@ -475,13 +501,13 @@ Off </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_TITLE" desc="Label for the radio button group of ambient mode topic source, where the screen contents come from."> - Photo Frame + Background </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS" desc="Label for the radio button to choose the topic source from Google Photos. The radio button allows the user to set Google Photos for ambient mode, which shows photos to the user when their device is idle."> Google Photos </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS_DESC" desc="Description for the radio button to choose the topic source from Google Photos. The radio button allows the user to set Google Photos for ambient mode, which shows photos to the user when their device is idle."> - Select your memories + Choose your favorite photos and albums </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS_DESC_NO_ALBUM" desc="Description for the radio button to choose the topic source from Google Photos when there is no album. The radio button allows the user to set Google Photos for ambient mode, which shows photos to the user when their device is idle."> To create albums, go to Google Photos @@ -490,7 +516,7 @@ Art gallery </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY_DESCRIPTION" desc="Description for the radio button to choose the topic source from art gallery. The radio button allows the user to set Art gallery for ambient mode, which shows photos to the user when their device is idle."> - Curated images and artwork + Select curated artwork and images </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_SELECTED_ROW" desc="A11y label for the selected topic source row in ambient mode."> <ph name="TOPIC_SOURCE">$1<ex>Google Photos</ex></ph> <ph name="TOPIC_SOURCE_DESC">$2<ex>Select your memories</ex></ph> selected, press Enter to select <ph name="TOPIC_SOURCE">$1<ex>Google Photos</ex></ph> albums @@ -502,13 +528,13 @@ Select <ph name="TOPIC_SOURCE">$1<ex>Google Photos</ex></ph> albums </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_TITLE" desc="Label for the subpage to select albums of Google Photos in ambient mode."> - A slideshow of selected memories will be created. To make any changes to the existing albums, go to<ph name="LINK_BEGIN"><a target="_blank" href="$1<ex>https://google.com/</ex>"></ph>Google Photos<ph name="LINK_END"></a></ph>. + Relive your favorite memories. To add or edit albums, go to<ph name="LINK_BEGIN"><a target="_blank" href="$1<ex>https://google.com/</ex>"></ph>Google Photos<ph name="LINK_END"></a></ph>. </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_NO_ALBUM" desc="Text for the subpage to select albums of Google Photos when there is no album in ambient mode."> - No albums set up yet + No albums. Create an album in<ph name="LINK_BEGIN"><a target="_blank" href="$1<ex>https://google.com/</ex>"></ph>Google Photos<ph name="LINK_END"></a></ph>. </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_RECENT_DESC" desc="Description for the Recent highlights album in ambient mode."> - Your best auto selected photos + Your best photos, selected automatically </message> <message name="IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_PHOTOS_NUM_PLURAL" desc="Number of photos in an album in ambient mode."> <ph name="NUMBER">$1<ex>100</ex></ph> photos
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_NO_ALBUM.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_NO_ALBUM.png.sha1 index 8febe91b..c17b600 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_NO_ALBUM.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_NO_ALBUM.png.sha1
@@ -1 +1 @@ -bf8cd7aff9ee521e28f3b73978c03a2bfc21acee \ No newline at end of file +2951dee8302a35c689bfad352d75db0e1b01174a \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_TITLE.png.sha1 index c2e4515c..c17b600 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_TITLE.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_TITLE.png.sha1
@@ -1 +1 @@ -ac082b74674f163872219d5f64954a4576852321 \ No newline at end of file +2951dee8302a35c689bfad352d75db0e1b01174a \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_RECENT_DESC.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_RECENT_DESC.png.sha1 index a1350c1..76b814a 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_RECENT_DESC.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_ALBUMS_SUBPAGE_RECENT_DESC.png.sha1
@@ -1 +1 @@ -47bd082ca731bd2b7f80d31ca565c286cc72f908 \ No newline at end of file +785187a81f988af3c79254de1ec1665e5bb207c7 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_PAGE_DESCRIPTION.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_PAGE_DESCRIPTION.png.sha1 index 3c4fcc9..6cc0e34 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_PAGE_DESCRIPTION.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_PAGE_DESCRIPTION.png.sha1
@@ -1 +1 @@ -c8a3be00b8006564c838bae42958dcef728e44c7 \ No newline at end of file +cadc6b7d912dcedea632b552528a77af596c8f81 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TITLE.png.sha1 index e691a93..f8761946 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TITLE.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TITLE.png.sha1
@@ -1 +1 @@ -22d883ef436173ef138214b2731e4371af96dcce \ No newline at end of file +e4abc530dea5221ceaf7dc7f9e1f0f9e9486da65 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY_DESCRIPTION.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY_DESCRIPTION.png.sha1 index 3c4fcc9..6cc0e34 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY_DESCRIPTION.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY_DESCRIPTION.png.sha1
@@ -1 +1 @@ -c8a3be00b8006564c838bae42958dcef728e44c7 \ No newline at end of file +cadc6b7d912dcedea632b552528a77af596c8f81 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS_DESC.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS_DESC.png.sha1 index 3c4fcc9..6cc0e34 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS_DESC.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS_DESC.png.sha1
@@ -1 +1 @@ -c8a3be00b8006564c838bae42958dcef728e44c7 \ No newline at end of file +cadc6b7d912dcedea632b552528a77af596c8f81 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_TITLE.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_TITLE.png.sha1 index a1f9b883..6cc0e34 100644 --- a/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_TITLE.png.sha1 +++ b/chrome/app/os_settings_strings_grdp/IDS_OS_SETTINGS_AMBIENT_MODE_TOPIC_SOURCE_TITLE.png.sha1
@@ -1 +1 @@ -6c9a91e5dcdcdc3cc1ea1b1fe9b5a1f5f76f9179 \ No newline at end of file +cadc6b7d912dcedea632b552528a77af596c8f81 \ No newline at end of file
diff --git a/chrome/app/resources/chromium_strings_af.xtb b/chrome/app/resources/chromium_strings_af.xtb index 13cf5be..f1424dc 100644 --- a/chrome/app/resources/chromium_strings_af.xtb +++ b/chrome/app/resources/chromium_strings_af.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium is in agtergrondmodus.</translation> <translation id="4987820182225656817">Gaste kan Chromium gebruik sonder om iets agter te laat.</translation> <translation id="4994636714258228724">Voeg jouself by Chromium</translation> -<translation id="5037694917996535813">Jy het met 'n werkrekening aangemeld. Wil jy graag 'n nuwe Chromium-profiel vir werk skep om jou data apart te hou?</translation> <translation id="5224391634244552924">Geen gestoorde wagwoorde nie. Chromium kan jou wagwoorde nagaan wanneer jy hulle stoor.</translation> <translation id="5277894862589591112">Herbegin Chromium om jou veranderinge toe te pas</translation> <translation id="5358375970380395591">Jy meld tans met 'n bestuurde rekening aan en gee sy administrateur beheer oor jou Chromium-profiel. Jou Chromium-data, soos jou programme, boekmerke, geskiedenis, wagwoorde en ander instellings, sal permanent aan <ph name="USER_NAME" /> gekoppel word. Jy sal hierdie data via die Google-rekening se kontroleskerm kan uitvee, maar jy sal nie hierdie data met 'n ander rekening kan assosieer nie. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_am.xtb b/chrome/app/resources/chromium_strings_am.xtb index 6c7dbc3..abe5b060 100644 --- a/chrome/app/resources/chromium_strings_am.xtb +++ b/chrome/app/resources/chromium_strings_am.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium በጀርባ ሁነታ ላይ ነው።</translation> <translation id="4987820182225656817">እንግዳዎች ማንኛውንም ነገር ወደኋላ ሳይተዉ Chromium መጠቀም ይችላሉ።</translation> <translation id="4994636714258228724">እራስዎን በChromium ላይ ያክሉ</translation> -<translation id="5037694917996535813">በሥራ መለያ ገብተዋል። የእርስዎን ውሂብ ለብቻው ለይቶ ለማቆየት አዲስ የChromium መገለጫ ለሥራ መፍጠር ይፈልጋሉ?</translation> <translation id="5224391634244552924">ምንም የተቀመጡ የይለፍ ቃላት የሉም። እርስዎ የይለፍ ቃላትዎን ሲያስቀምጧቸው Chromium መፈተሽ ይችላል።</translation> <translation id="5277894862589591112">የእርስዎን ለውጦች ተፈጻሚ ለማድረግ፣ Chromiumን ዳግም ያስጀምሩ</translation> <translation id="5358375970380395591">በሚተዳደር መለያ እየገቡ ነው፣ እና አስተዳዳሪው በእርስዎ Chromium መገለጫ ላይ ቁጥጥር እየሰጡት ነው። እንደ እርስዎ መተግበሪያዎች፣ ዕልባቶች፣ ታሪክ፣ የይለፍ ቃላት እና ሌሎች ቅንብሮች ያሉ የእርስዎ Chromium ውሂብ እስከ መጨረሻው ከ<ph name="USER_NAME" /> ጋር የተያያዙ ይሆናሉ። ይህን ውሂብ በGoogle የመለያዎች Dashboard አማካኝነት ሊሰርዙት ይችላሉ፣ ነገር ግን ይህን ውሂብ ከሌላ መለያ ጋር ሊያጎዳኙት አይችሉም። <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ar.xtb b/chrome/app/resources/chromium_strings_ar.xtb index 736f626e..149f1cf 100644 --- a/chrome/app/resources/chromium_strings_ar.xtb +++ b/chrome/app/resources/chromium_strings_ar.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium في وضع الخلفية.</translation> <translation id="4987820182225656817">يمكن للضيف استخدام Chromium بدون أن يترك أي أثر وراءه.</translation> <translation id="4994636714258228724">إضافة نفسك إلى Chromium</translation> -<translation id="5037694917996535813">لقد سجَّلت الدخول باستخدام حساب عمل. هل تريد إنشاء ملف شخصي جديد على Chromium للعمل حتى تُبقي بياناتك منفصلة؟</translation> <translation id="5224391634244552924">ما مِن كلمات مرور محفوظة. لا يستطيع Chromium التحقُّق من كلمات المرور إلا عند حفظها.</translation> <translation id="5277894862589591112">لتطبيق التغييرات، يُرجى إعادة تشغيل Chromium</translation> <translation id="5358375970380395591">أنت تسجل الدخول باستخدام حساب يخضع للإدارة وتتيح للمشرف إمكانية التحكم في ملفك الشخصي على Chromium. وستكون بياناتك في Chromium مثل تطبيقاتك وإشاراتك المرجعية وسجلك وكلمات المرور التابعة لك والإعدادات الأخرى مرتبطة دائمًا بالمستخدم <ph name="USER_NAME" />. ستتمكن من حذف هذه البيانات عبر لوحة تحكم حسابات Google، ولكنك لن تتمكن من إقران هذه البيانات بحساب آخر. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_as.xtb b/chrome/app/resources/chromium_strings_as.xtb index 6591cf4..260dec1 100644 --- a/chrome/app/resources/chromium_strings_as.xtb +++ b/chrome/app/resources/chromium_strings_as.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium নেপথ্য ম’ডত আছে।</translation> <translation id="4987820182225656817">অতিথিসকলে কোনো সুবিধা বাদ নিদিয়াকৈ Chromium ব্যৱহাৰ কৰিব পাৰে।</translation> <translation id="4994636714258228724">নিজকে Chromiumত যোগ কৰক</translation> -<translation id="5037694917996535813">আপুনি এটা কৰ্মস্থানৰ একাউণ্টেৰে ছাইন ইন কৰিছে। আপোনাৰ ডেটা পৃথক কৰি ৰাখিবলৈ আপুনি কৰ্মস্থানৰ বাবে এটা নতুন Chromium প্ৰ’ফাইল সৃষ্টি কৰিব বিচাৰেনে?</translation> <translation id="5224391634244552924">ছেভ কৰা কোনো পাছৱৰ্ড নাই। আপুনি নিজৰ পাছৱর্ডসমূহ ছেভ কৰিলে Chromiumএ সেইবোৰ পৰীক্ষা কৰিব পাৰে।</translation> <translation id="5277894862589591112">আপুনি কৰা সলনি কার্যসমূহ প্ৰযোজ্য কৰিবলৈ Chromium পুনৰ লঞ্চ কৰক</translation> <translation id="5358375970380395591">আপুনি এটা পৰিচালিত একাউণ্টৰ জৰিয়তে ছাইন ইন কৰি আছে আৰু আপোনাৰ Chromium প্ৰ’ফাইলৰ জৰিয়তে ইয়াৰ প্ৰশাসনিক নিয়ন্ত্ৰণ দি আছে। আপোনাৰ এপ্, বুকমার্ক, ইতিহাস, পাছৱর্ড আৰু অন্য ছেটিংসমূহৰ দৰে নিজৰ Chromium ডেটা স্থায়ীভাৱে <ph name="USER_NAME" />ৰ সৈতে সংযুক্ত হ’ব। আপুনি Google একাউণ্ট ডেশ্বব’ৰ্ডৰ জৰিয়তে এই ডেটা মচিব পাৰিব কিন্তু আপুনি এই ডেটা অন্য একাউণ্টৰ সৈতে সংলগ্ন কৰিব নোৱাৰিব। <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_az.xtb b/chrome/app/resources/chromium_strings_az.xtb index 41f8b8b..b97b90c 100644 --- a/chrome/app/resources/chromium_strings_az.xtb +++ b/chrome/app/resources/chromium_strings_az.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium arxa fon rejimindədir.</translation> <translation id="4987820182225656817">Qonaqlar geridə heç nə buraxmadan Chromium istifadə edə bilər.</translation> <translation id="4994636714258228724">Özünüzü Chromium'a əlavə edin</translation> -<translation id="5037694917996535813">İş hesabı ilə daxil olmusunuz. Datanızı ayrı saxlamaq üçün yeni Chromium İş Profili yaratmaq istərdinizmi?</translation> <translation id="5224391634244552924">Yadda saxlanmış parol yoxdur. Parollarınızı yadda saxladıqda Chromium onları yoxlaya bilər.</translation> <translation id="5277894862589591112">Dəyişiklikləri tətbiq etmək üçün Chromium'u yenidən başladın</translation> <translation id="5358375970380395591">İdarə olunan hesabla daxil olursnuz və onun inzibati idarəetməsini Chromium profilinizə verirsiniz. Tətbiqləriniz, əlfəcinləriniz, tarixçəniz və digər ayarlarınız Chromimum datanızla birlikdə <ph name="USER_NAME" /> üzərinə həmişəlik bənd olacaq. Bu datanı Google Hesabları Paneli vasitəsilə silə bilərsiniz, lakin bu datanı digər hesabla əlaqəli edə bilməzsiniz. Mövcud Chrome datanızı ayrı saxlamaq üçün yeni profil yarada bilərsiniz. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_be.xtb b/chrome/app/resources/chromium_strings_be.xtb index fcb1838..a7de15a 100644 --- a/chrome/app/resources/chromium_strings_be.xtb +++ b/chrome/app/resources/chromium_strings_be.xtb
@@ -106,7 +106,6 @@ <translation id="4943838377383847465">Chromium працуе ў фонавым рэжыме.</translation> <translation id="4987820182225656817">Госці могуць выкарыстоўваць Chromium, не пакідаючы нічога пасля сябе.</translation> <translation id="4994636714258228724">Дадаць мяне ў Chromium</translation> -<translation id="5037694917996535813">Вы ўвайшлі ў працоўны ўліковы запіс. Ці не хочаце стварыць новы профіль Chromium для работы, каб трымаць свае даныя асобна?</translation> <translation id="5224391634244552924">Няма захаваных пароляў. Chromium можа правяраць толькі захаваныя паролі.</translation> <translation id="5277894862589591112">Каб прымяніць змяненні, перазапусціце Chromium</translation> <translation id="5358375970380395591">Вы ўваходзіце праз уліковы запіс пад кіраваннем, што дае адміністратару кантроль над вашым профілем у браўзеры Chromium. Даныя Chromium (праграмы, закладкі, гісторыя, паролі і іншыя налады) будуць назаўсёды прывязаны да ўліковага запісу <ph name="USER_NAME" />. Вы зможаце выдаліць гэтыя даныя праз панэль кіравання Уліковымі запісамі Google, але іх нельга будзе звязаць з іншым уліковым запісам. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_bg.xtb b/chrome/app/resources/chromium_strings_bg.xtb index 13aa89a..e9ef082 100644 --- a/chrome/app/resources/chromium_strings_bg.xtb +++ b/chrome/app/resources/chromium_strings_bg.xtb
@@ -103,7 +103,6 @@ <translation id="4943838377383847465">Chromium работи на заден план.</translation> <translation id="4987820182225656817">Гостите могат да използват Chromium, без да оставят следи.</translation> <translation id="4994636714258228724">Добавяне на вас към Chromium</translation> -<translation id="5037694917996535813">Влязохте със служебен профил. Искате ли да създадете в Chromium нов потребителски профил за служебни цели, за да поддържате данните си разделени?</translation> <translation id="5224391634244552924">Няма запазени пароли. Chromium може да проверява паролите ви, когато ги запазите.</translation> <translation id="5277894862589591112">За да приложите промените си, рестартирайте Chromium</translation> <translation id="5358375970380395591">Влизате с управляван профил и давате на администратора му контрол над потребителския си профил в Chromium. Данните ви там, като например приложения, отметки, история, пароли и други настройки, ще се свържат за постоянно с/ъс <ph name="USER_NAME" />. Ще можете да ги изтриете чрез таблото за управление на Google Профили, но не и да ги свържете с друг профил. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_bn.xtb b/chrome/app/resources/chromium_strings_bn.xtb index 9b69df19..854f713 100644 --- a/chrome/app/resources/chromium_strings_bn.xtb +++ b/chrome/app/resources/chromium_strings_bn.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium পটভূমিতে চলছে৷</translation> <translation id="4987820182225656817">অতিথিগণ কোনো কিছুর জন্য অভাব বোধ না করেই Chromium ব্যবহার করতে পারবেন৷</translation> <translation id="4994636714258228724">Chromium এর সাথে নিজেকে যোগ করুন</translation> -<translation id="5037694917996535813">আপনি অফিস অ্যাকাউন্ট দিয়ে সাইন-ইন করেছেন। আপনার ডেটা আলাদা রাখতে আপনি কি অফিসের জন্য একটি নতুন Chromium প্রোফাইল তৈরি করতে চান?</translation> <translation id="5224391634244552924">কোনও পাসওয়ার্ড সেভ করা নেই। আপনি পাসওয়ার্ড সেভ করলে Chromium সেটি চেক করতে পারবে।</translation> <translation id="5277894862589591112">আপনার পরিবর্তনগুলি প্রয়োগ করতে, Chromium রিলঞ্চ করুন</translation> <translation id="5358375970380395591">আপনি একটি পরিচালিত অ্যাকাউন্টের মাধ্যমে সাইন-ইন করছেন এবং এর অ্যাডমিনিস্ট্রেটরকে আপনার Chromium প্রোফাইলের উপরে নিয়ন্ত্রণ দিচ্ছেন৷ আপনার Chromium ডেটা, যেমন অ্যাপ, বুকমার্ক, ইতিহাস, পাসওয়ার্ড এবং অন্যান্য সেটিংস <ph name="USER_NAME" /> এতে স্থায়ীভাবে সম্পৃক্ত হবে৷ আপনি Google অ্যাকাউন্টগুলির ড্যাশবোর্ডের মাধ্যমে এই ডেটাগুলি মুছতে চালু হবেন, কিন্তু অন্য অ্যাকাউন্টের সাথে এই ডেটা সংশ্লিষ্ট করতে পারবেন না৷ <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_bs.xtb b/chrome/app/resources/chromium_strings_bs.xtb index 7dd7bbe..3d1e422 100644 --- a/chrome/app/resources/chromium_strings_bs.xtb +++ b/chrome/app/resources/chromium_strings_bs.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium je u pozadinskom načinu rada.</translation> <translation id="4987820182225656817">Gosti mogu koristiti Chromium, a da ne ostave tragove o korištenju.</translation> <translation id="4994636714258228724">Dodajte se u Chromium</translation> -<translation id="5037694917996535813">Prijavili ste se s poslovnim računom. Želite li kreirati novi Chromium profil za posao da odvojite podatke?</translation> <translation id="5224391634244552924">Nema sačuvanih lozinki. Chromium može provjeravati vaše lozinke kada ih sačuvate.</translation> <translation id="5277894862589591112">Za primjenu promjena, ponovo pokrenite Chromium</translation> <translation id="5358375970380395591">Prijavljujete se s upravljanim računom i dajete njegovom administratoru kontrolu nad svojim Chromium profilom. Vaši podaci iz Chromiuma, kao što su vaše aplikacije, oznake, historija, lozinke i druge postavke, trajno će se vezati za račun <ph name="USER_NAME" />. Moći ćete izbrisati ove podatke na kontrolnoj tabli Google računa, ali nećete moći povezati ove podatke s drugim računom. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ca.xtb b/chrome/app/resources/chromium_strings_ca.xtb index 83b8d36c..b32b2e2 100644 --- a/chrome/app/resources/chromium_strings_ca.xtb +++ b/chrome/app/resources/chromium_strings_ca.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium està en mode de segon pla.</translation> <translation id="4987820182225656817">Els convidats poden utilitzar Chromium sense deixar-hi rastre.</translation> <translation id="4994636714258228724">Afegeix-me a Chromium</translation> -<translation id="5037694917996535813">Has iniciat la sessió amb un compte de la feina. Vols crear un perfil de Chromium per a la feina que et permeti mantenir les dades separades?</translation> <translation id="5224391634244552924">No hi ha cap contrasenya desada. Chromium pot comprovar les teves contrasenyes quan les deses.</translation> <translation id="5277894862589591112">Torna a iniciar Chromium perquè s'apliquin els canvis</translation> <translation id="5358375970380395591">Esteu a punt d'iniciar la sessió amb un compte gestionat i d'atorgar el control del vostre perfil de Chromium a l'administrador corresponent. Les dades de Chromium, com ara aplicacions, adreces d'interès, historial, contrasenyes i altres configuracions, s'enllaçaran permanentment amb <ph name="USER_NAME" />. Podreu suprimir aquestes dades mitjançant el Tauler de Comptes de Google, però no les podreu associar amb un altre compte. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_cs.xtb b/chrome/app/resources/chromium_strings_cs.xtb index 65e14df..0f4af8f5 100644 --- a/chrome/app/resources/chromium_strings_cs.xtb +++ b/chrome/app/resources/chromium_strings_cs.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium je v režimu na pozadí.</translation> <translation id="4987820182225656817">Hosté mohou Chromium používat, aniž by po nich zůstaly jakékoliv stopy.</translation> <translation id="4994636714258228724">Přidejte do prohlížeče Chromium svůj účet</translation> -<translation id="5037694917996535813">Přihlásili jste se pomocí pracovního účtu. Chcete v prohlížeči Chromium vytvořit nový pracovní profil, aby data byla oddělená?</translation> <translation id="5224391634244552924">Nemáte žádná uložená hesla. Chromium může hesla zkontrolovat, pouze když si je uložíte.</translation> <translation id="5277894862589591112">Chcete-li změny použít, restartujte Chromium</translation> <translation id="5358375970380395591">Přihlašujete se pomocí spravovaného účtu a poskytujete jeho správci kontrolu nad vaším profilem prohlížeče Chromium. Vaše údaje prohlížeče Chromium, například aplikace, záložky, historie, hesla a jiná nastavení, budou trvale přidružena k účtu <ph name="USER_NAME" />. Tyto údaje budete moci smazat pomocí Hlavního panelu v Účtech Google, ale nebudete je moci přidružit k jinému účtu. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_da.xtb b/chrome/app/resources/chromium_strings_da.xtb index c6ac149..0e585b3 100644 --- a/chrome/app/resources/chromium_strings_da.xtb +++ b/chrome/app/resources/chromium_strings_da.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium kører i baggrunden.</translation> <translation id="4987820182225656817">Gæster kan bruge Chromium uden at efterlade noget.</translation> <translation id="4994636714258228724">Tilføj dig selv i Chromium</translation> -<translation id="5037694917996535813">Du er logget ind med en arbejdskonto. Vi du oprette en ny Chromium-profil til dit arbejde for at holde dine data adskilt?</translation> <translation id="5224391634244552924">Der er ingen gemte adgangskoder. Chromium kan tjekke dine adgangskoder, når du gemmer dem.</translation> <translation id="5277894862589591112">Åbn Chromium igen for at anvende ændringerne</translation> <translation id="5358375970380395591">Du er ved at logge ind med en managerstyret konto og giver dens administrator kontrol over din profil i Chromium. Dine Chromium-data, f.eks. dine apps, bogmærker, historikdata, adgangskoder og andre indstillinger, knyttes permanent til <ph name="USER_NAME" />. Du kan slette disse data via kontrolpanelet for Google Konti, men du kan ikke knytte disse data til en anden konto. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_de.xtb b/chrome/app/resources/chromium_strings_de.xtb index 317e915..c1191274 100644 --- a/chrome/app/resources/chromium_strings_de.xtb +++ b/chrome/app/resources/chromium_strings_de.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium wird im Hintergrundmodus ausgeführt.</translation> <translation id="4987820182225656817">Gastnutzer können Chromium verwenden, ohne Daten zu hinterlassen.</translation> <translation id="4994636714258228724">Mich zu Chromium hinzufügen</translation> -<translation id="5037694917996535813">Sie haben sich mit einem Arbeitskonto angemeldet. Möchten Sie ein neues Chromium-Profil für die Arbeit erstellen, um Ihre Daten getrennt zu halten?</translation> <translation id="5224391634244552924">Keine gespeicherten Passwörter. Chromium kann Ihre Passwörter prüfen, wenn Sie sie speichern.</translation> <translation id="5277894862589591112">Starten Sie Chromium neu, um die Änderungen zu übernehmen</translation> <translation id="5358375970380395591">Sie melden sich mit einem verwalteten Konto an und ermöglichen dessen Administrator Zugriff auf Ihr Chromium-Profil. Ihre Chromium-Daten, wie Apps, Lesezeichen, Verlauf, Passwörter und andere Einstellungen, werden dauerhaft mit <ph name="USER_NAME" /> verknüpft. Sie können diese Daten über das Google Konten-Dashboard löschen, aber nicht mit einem anderen Konto verknüpfen. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_el.xtb b/chrome/app/resources/chromium_strings_el.xtb index 90803eb..aa2b64c9 100644 --- a/chrome/app/resources/chromium_strings_el.xtb +++ b/chrome/app/resources/chromium_strings_el.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Το Chromium εκτελείται στο παρασκήνιο.</translation> <translation id="4987820182225656817">Οι επισκέπτες μπορούν να χρησιμοποιούν το Chromium χωρίς να αφήνουν κανένα ίχνος.</translation> <translation id="4994636714258228724">Προσθήκη του εαυτού σας στο Chromium</translation> -<translation id="5037694917996535813">Συνδεθήκατε με έναν λογαριασμό εργασίας. Θέλετε να δημιουργήσετε ένα νέο προφίλ Chromium για την εργασία έτσι ώστε να διατηρείτε τα δεδομένα σας ξεχωριστά;</translation> <translation id="5224391634244552924">Δεν υπάρχουν αποθηκευμένοι κωδικοί πρόσβασης. Το Chromium μπορεί να ελέγξει τους κωδικούς πρόσβασής σας όταν τους αποθηκεύσετε.</translation> <translation id="5277894862589591112">Για να εφαρμόσετε τις αλλαγές σας, επανεκκινήστε το Chromium</translation> <translation id="5358375970380395591">Είστε συνδεδεμένοι με έναν διαχειριζόμενο λογαριασμό και παραχωρείτε στο διαχειριστή του τον έλεγχο του προφίλ σας στο Chromium. Τα δεδομένα σας στο Chromium, όπως οι εφαρμογές, οι σελιδοδείκτες, το ιστορικό, οι κωδικοί πρόσβασης και άλλες ρυθμίσεις θα συνδεθούν μόνιμα με το όνομα χρήστη <ph name="USER_NAME" />. Θα έχετε τη δυνατότητα να διαγράψετε αυτά τα δεδομένα μέσω του Πίνακα ελέγχου των Λογαριασμών Google, αλλά δεν θα μπορείτε να τα συσχετίσετε με άλλο λογαριασμό. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_en-GB.xtb b/chrome/app/resources/chromium_strings_en-GB.xtb index 2559825..9b0ba6b 100644 --- a/chrome/app/resources/chromium_strings_en-GB.xtb +++ b/chrome/app/resources/chromium_strings_en-GB.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium is in background mode.</translation> <translation id="4987820182225656817">Guests can use Chromium without leaving anything behind.</translation> <translation id="4994636714258228724">Add yourself to Chromium</translation> -<translation id="5037694917996535813">You signed in with a work account. Would you like to create a new Chromium profile for work to keep your data separate?</translation> <translation id="5224391634244552924">No saved passwords. Chromium can check your passwords when you save them.</translation> <translation id="5277894862589591112">To apply your changes, relaunch Chromium</translation> <translation id="5358375970380395591">You are signing in with a managed account and giving its administrator control over your Chromium profile. Your Chromium data, such as your apps, bookmarks, history, passwords and other settings will become permanently tied to <ph name="USER_NAME" />. You will be able to delete this data via the Google Accounts Dashboard, but you will not be able to associate this data with another account. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_es-419.xtb b/chrome/app/resources/chromium_strings_es-419.xtb index 4d3bcbb7..65e4af9e 100644 --- a/chrome/app/resources/chromium_strings_es-419.xtb +++ b/chrome/app/resources/chromium_strings_es-419.xtb
@@ -103,7 +103,6 @@ <translation id="4943838377383847465">Chromium está en modo de segundo plano</translation> <translation id="4987820182225656817">Los invitados pueden utilizar Chromium sin dejar nada detrás.</translation> <translation id="4994636714258228724">Agregarte a Chromium</translation> -<translation id="5037694917996535813">Accediste con una cuenta de trabajo. ¿Quieres crear un perfil de trabajo nuevo en Chromium para mantener los datos separados?</translation> <translation id="5224391634244552924">No hay contraseñas guardadas. Chromium puede revisar las contraseñas cuando las guardas.</translation> <translation id="5277894862589591112">Para aplicar los cambios, vuelve a ejecutar Chromium</translation> <translation id="5358375970380395591">Estás por acceder con una cuenta administrada, lo que significa que proporcionarás al administrador el control sobre tu perfil de Chromium. Tus datos de Chromium, como las aplicaciones, los favoritos, el historial, las contraseñas y otros parámetros de configuración quedarán vinculados a <ph name="USER_NAME" /> de forma permanente. Podrás eliminar estos datos a través del Panel de control de Cuentas de Google, pero no podrás asociarlos a otra cuenta. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_es.xtb b/chrome/app/resources/chromium_strings_es.xtb index 5228f5c6..86955b58 100644 --- a/chrome/app/resources/chromium_strings_es.xtb +++ b/chrome/app/resources/chromium_strings_es.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium está en modo de segundo plano.</translation> <translation id="4987820182225656817">Los invitados pueden utilizar Chromium sin dejar nada atrás.</translation> <translation id="4994636714258228724">Añadirte a Chromium</translation> -<translation id="5037694917996535813">Has iniciado sesión con una cuenta de trabajo. ¿Quieres crear un nuevo perfil de trabajo de Chromium para mantener tus datos de forma separada?</translation> <translation id="5224391634244552924">No hay ninguna contraseña guardada. Chromium puede comprobar tus contraseñas si las guardas.</translation> <translation id="5277894862589591112">Reinicia Chromium para aplicar los cambios</translation> <translation id="5358375970380395591">Vas a iniciar sesión con una cuenta gestionada, lo que significa que proporcionarás a su administrador control sobre tu perfil de Chromium. Tus datos de Chromium como, por ejemplo, tus aplicaciones, tus marcadores, tu historial, tus contraseñas y otras opciones se vincularán de forma permanente a la cuenta <ph name="USER_NAME" />. Podrás eliminar estos datos a través del Panel de control de cuentas de Google, pero no podrás asociarlos a otra cuenta. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_et.xtb b/chrome/app/resources/chromium_strings_et.xtb index d8f3206..ed7691c 100644 --- a/chrome/app/resources/chromium_strings_et.xtb +++ b/chrome/app/resources/chromium_strings_et.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium on taustarežiimis.</translation> <translation id="4987820182225656817">Külastajad saavad kasutada Chromiumi jälgi jätmata.</translation> <translation id="4994636714258228724">Lisa Chromiumi</translation> -<translation id="5037694917996535813">Logisite sisse oma töökontoga. Kas soovite luua uue Chromiumi tööprofiili, et andmed eraldi hoida?</translation> <translation id="5224391634244552924">Salvestatud paroole ei ole. Chromium saab teie paroole kontrollida, kui olete need salvestanud.</translation> <translation id="5277894862589591112">Muudatuste rakendamiseks käivitage Chromium uuesti</translation> <translation id="5358375970380395591">Logite sisse hallatud kontoga ja annate selle administraatorile üle Chromiumi profiili juhtimise. Teie Chromiumi andmed, näiteks rakendused, järjehoidjad, ajalugu, paroolid ja muud seaded seotakse jäädavalt kasutajaga <ph name="USER_NAME" />. Saate need andmed kustutada Google'i kontode juhtpaneeli kaudu, kuid te ei saa neid seostada teise kontoga. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_eu.xtb b/chrome/app/resources/chromium_strings_eu.xtb index 405309b..c07dedf 100644 --- a/chrome/app/resources/chromium_strings_eu.xtb +++ b/chrome/app/resources/chromium_strings_eu.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium atzeko planoko moduan dago.</translation> <translation id="4987820182225656817">Gonbidatuek Chromium erabil dezakete aztarnarik utzi gabe.</translation> <translation id="4994636714258228724">Gaitu zure burua Chromium-en</translation> -<translation id="5037694917996535813">Laneko kontu batekin hasi duzu saioa. Laneko profil bat sortu nahi duzu Chromium-en, datuak bereiz gordetzeko?</translation> <translation id="5224391634244552924">Ez dago pasahitzik gordeta. Gordeta dituzun pasahitzak egiaztatu egin ditzake Chromium-ek.</translation> <translation id="5277894862589591112">Aldaketak aplikatzeko, berrabiarazi Chromium</translation> <translation id="5358375970380395591">Kontu kudeatu batekin hasten ari zara saioa eta kontuaren administratzaileari zure Chromium profila kontrolatzeko ahalmena ematera zoaz. Chromium aplikazioan dituzun datuak, esaterako, aplikazioak, laster-markak, historia, pasahitzak eta beste ezarpen batzuk betiko lotuko zaizkio <ph name="USER_NAME" /> erabiltzaileari. Google kontuetako Panelaren bidez ezabatu ahalko dituzu datu horiek, baina ezingo dituzu beste kontu batekin lotu. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_fa.xtb b/chrome/app/resources/chromium_strings_fa.xtb index 21ef20f..0857d80 100644 --- a/chrome/app/resources/chromium_strings_fa.xtb +++ b/chrome/app/resources/chromium_strings_fa.xtb
@@ -104,7 +104,6 @@ <translation id="4943838377383847465">Chromium در حالت پسزمینه است.</translation> <translation id="4987820182225656817">مهمانها می توانند از Chromium استفاده کنند بدون اینکه اثری از خود به جا بگذارند.</translation> <translation id="4994636714258228724">افرودن خودتان به Chromium</translation> -<translation id="5037694917996535813">با حساب کاری به سیستم وارد شدهاید. مایلید «نمایه ویژه کار Chromium» جدیدی ایجاد کنید تا دادههایتان بهصورت جداگانه نگهداری شود؟</translation> <translation id="5224391634244552924">گذرواژه ذخیرهشدهای وجود ندارد. Chromium زمانی میتواند گذرواژههایتان را بررسی کند که آنها را ذخیره کرده باشید.</translation> <translation id="5277894862589591112">برای اعمال تغییراتتان، Chromium را راهاندازی مجدد کنید</translation> <translation id="5358375970380395591">شما با حساب مدیریتشده وارد سیستم میشوید و به سرپرست آن اجازه کنترل بر نمایه Chromium خود را میدهید. دادههای Chromium شما شامل برنامهها، نشانکها، سابقه، گذرواژهها و سایر تنظیمات برای همیشه به <ph name="USER_NAME" /> مرتبط خواهد شد. میتوانید این دادهها را از طریق داشبورد حسابهای Google حذف کنید اما نمیتوانید این دادهها را به حساب دیگری مرتبط سازید. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_fi.xtb b/chrome/app/resources/chromium_strings_fi.xtb index bcc9fb2..4545a33 100644 --- a/chrome/app/resources/chromium_strings_fi.xtb +++ b/chrome/app/resources/chromium_strings_fi.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium on käynnissä taustalla</translation> <translation id="4987820182225656817">Vierailijat voivat käyttää Chromiumia jälkiä jättämättä.</translation> <translation id="4994636714258228724">Lisää itsesi Chromiumiin</translation> -<translation id="5037694917996535813">Kirjauduit sisään työtilillä. Haluatko luoda uuden Chromium-profiilin pitääksesi datasi erillään?</translation> <translation id="5224391634244552924">Ei tallennettuja salasanoja. Chromium voi tarkistaa salasanasi, kun tallennat niitä.</translation> <translation id="5277894862589591112">Ota muutokset käyttöön käynnistämällä Chromium uudelleen</translation> <translation id="5358375970380395591">Olet kirjautumassa sisään hallinnoidulla tilillä ja antamassa tilin järjestelmänvalvojalle oikeuden hallita Chromium-profiiliasi. Chromium-tietosi, kuten sovelluksesi, kirjanmerkkisi, historiasi, salasanasi ja muut asetuksesi, yhdistetään pysyvästi käyttäjätiliin <ph name="USER_NAME" />. Voit poistaa nämä tiedot Google-tilien Hallintapaneelissa, mutta et voi liittää tietoja toiseen tiliin. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_fil.xtb b/chrome/app/resources/chromium_strings_fil.xtb index feaba324..7df570e 100644 --- a/chrome/app/resources/chromium_strings_fil.xtb +++ b/chrome/app/resources/chromium_strings_fil.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Nasa background mode ang Chromium.</translation> <translation id="4987820182225656817">Makakagamit ng Chromium ang mga bisita nang hindi nag-iiwan ng anumang bakas.</translation> <translation id="4994636714258228724">Idagdag ang iyong sarili sa Chromium</translation> -<translation id="5037694917996535813">Nag-sign in ka gamit ang isang account sa trabaho. Gusto mo bang gumawa ng bagong Profile sa Chromium para sa Trabaho para mapanatiling nakahiwalay ang iyong data?</translation> <translation id="5224391634244552924">Walang naka-save na password. Masusuri ng Chromium ang iyong mga password kapag na-save mo ang mga ito.</translation> <translation id="5277894862589591112">Para ilapat ang iyong mga pagbabago, muling ilunsad ang Chromium</translation> <translation id="5358375970380395591">Nagsa-sign in ka gamit ang isang pinamamahalaang account at nagbibigay sa administrator nito ng kontrol sa iyong profile sa Chromium. Permanenteng mauugnay ang iyong data sa Chromium, gaya ng iyong apps, mga bookmark, kasaysayan, password, at iba pang mga setting sa <ph name="USER_NAME" />. Matatanggal mo ang data na ito sa Google Accounts Dashboard, ngunit hindi mo maiuugnay ang data na ito sa isa pang account. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_fr-CA.xtb b/chrome/app/resources/chromium_strings_fr-CA.xtb index f4dba2b..022ff5a 100644 --- a/chrome/app/resources/chromium_strings_fr-CA.xtb +++ b/chrome/app/resources/chromium_strings_fr-CA.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium fonctionne en mode arrière-plan.</translation> <translation id="4987820182225656817">Les invités peuvent utiliser Chromium sans rien laisser derrière eux.</translation> <translation id="4994636714258228724">Ajouter un utilisateur à Chromium</translation> -<translation id="5037694917996535813">Vous vous êtes connecté à l'aide d'un compte professionnel. Voulez-vous créer un profil Chromium pour le travail afin de garder vos données distinctes?</translation> <translation id="5224391634244552924">Aucun mot de passe enregistré. Chromium ne peut vérifier vos mots de passe que si vous les enregistrez.</translation> <translation id="5277894862589591112">Pour appliquer vos modifications, relancez Chromium</translation> <translation id="5358375970380395591">Vous vous connectez avec un compte géré et rendez son administrateur maître de votre profil Chromium. Vos données de Chromium, comme vos applications, vos favoris, votre historique, vos mots de passe et vos autres paramètres, vont être associées de manière permanente à <ph name="USER_NAME" />. Vous pourrez supprimer ces données à l'aide du tableau de bord des comptes Google, mais vous ne pourrez pas les associer à un autre compte. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_fr.xtb b/chrome/app/resources/chromium_strings_fr.xtb index 8e054145..304383d 100644 --- a/chrome/app/resources/chromium_strings_fr.xtb +++ b/chrome/app/resources/chromium_strings_fr.xtb
@@ -106,7 +106,6 @@ <translation id="4943838377383847465">Chromium est exécuté en mode arrière-plan</translation> <translation id="4987820182225656817">Les invités peuvent utiliser Chromium sans laisser aucune trace.</translation> <translation id="4994636714258228724">Ajouter un utilisateur à Chromium</translation> -<translation id="5037694917996535813">Vous vous êtes connecté avec un compte professionnel. Voulez-vous créer un profil Chromium pour le travail afin de séparer vos données ?</translation> <translation id="5224391634244552924">Aucun mot de passe enregistré. Chromium ne peut vérifier vos mots de passe que si vous les enregistrez.</translation> <translation id="5277894862589591112">Pour appliquer vos modifications, relancez Chromium</translation> <translation id="5358375970380395591">Vous vous connectez avec un compte géré et donnez le contrôle de votre profil Chromium à son administrateur. Vos données Chromium, telles que les applications, les favoris, l'historique, les mots de passe et les autres paramètres, vont être définitivement associées à <ph name="USER_NAME" />. Vous pouvez supprimer ces données via le tableau de bord des comptes Google, mais vous ne pouvez pas les associer à un autre compte. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_gl.xtb b/chrome/app/resources/chromium_strings_gl.xtb index 0e3d42d..84c2b34 100644 --- a/chrome/app/resources/chromium_strings_gl.xtb +++ b/chrome/app/resources/chromium_strings_gl.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium está no modo de segundo plano.</translation> <translation id="4987820182225656817">Os invitados poden utilizar Chromium sen perder información.</translation> <translation id="4994636714258228724">Engádete a Chromium</translation> -<translation id="5037694917996535813">Iniciaches sesión cunha conta de traballo. Queres crear un perfil de Chromium novo para o traballo para manter separados os datos?</translation> <translation id="5224391634244552924">Non hai contrasinais gardados. Chromium pode comprobar os teus contrasinais cando os gardes.</translation> <translation id="5277894862589591112">Para aplicar os cambios, reinicia Chromium</translation> <translation id="5358375970380395591">Estás iniciando sesión cunha conta xestionada e concedendo control ao seu administrador sobre o teu perfil de Chromium. Os teus datos de Chromium, como as túas aplicacións, marcadores, historial, contrasinais e outras configuracións ligaranse permanentemente a <ph name="USER_NAME" />. Poderás eliminar estes datos a través do Panel de control das contas de Google, pero non poderás asociar estes datos a outra conta. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_gu.xtb b/chrome/app/resources/chromium_strings_gu.xtb index 8119aa01..30aca30 100644 --- a/chrome/app/resources/chromium_strings_gu.xtb +++ b/chrome/app/resources/chromium_strings_gu.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium પૃષ્ઠભૂમિ મોડમાં છે.</translation> <translation id="4987820182225656817">અતિથિઓ કંઈપણ પાછળ છોડ્યાં વિના Chromium નો ઉપયોગ કરી શકે છે.</translation> <translation id="4994636714258228724">સ્વયંને Chromium માં ઉમેરો</translation> -<translation id="5037694917996535813">તમે ઑફિસના એકાઉન્ટ વડે લૉગ ઇન કર્યું છે. તમારો ડેટા અલગ રાખવા માટે, શું તમે ઑફિસ માટે નવી Chromium પ્રોફાઇલ બનાવવા માગો છો?</translation> <translation id="5224391634244552924">કોઈ સાચવેલા પાસવર્ડ નથી. જ્યારે તમે તમારા પાસવર્ડ સાચવો ત્યારે Chromium તેને ચેક કરી શકે છે.</translation> <translation id="5277894862589591112">તમારા ફેરફારો લાગુ કરવા માટે, Chromiumને ફરી લૉન્ચ કરો</translation> <translation id="5358375970380395591">તમે મેનેજ કરેલા એકાઉન્ટ સાથે સાઇન ઇન કરી રહ્યાં છો અને તમારી Chromium પ્રોફાઇલ પર એનું એડમિન નિયંત્રણ આપી રહ્યાં છો. તમારો Chromium ડેટા, જેમ કે ઍપ, બુકમાર્ક, ઇતિહાસ, પાસવર્ડ અને બીજા સેટિંગ, કાયમ માટે <ph name="USER_NAME" /> થી બંધાયેલ રહેશે. તમે Google એકાઉન્ટ ડૅશબોર્ડથી આ ડેટાને કાઢી શકશો, પરંતુ તમે આ ડેટાને બીજા એકાઉન્ટ સાથે સાંકળી શકશો નહિ. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_hi.xtb b/chrome/app/resources/chromium_strings_hi.xtb index 3402ce75..c4871c2 100644 --- a/chrome/app/resources/chromium_strings_hi.xtb +++ b/chrome/app/resources/chromium_strings_hi.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">क्रोमियम पृष्ठभूमि मोड में है.</translation> <translation id="4987820182225656817">अतिथि कुछ भी छोड़े बिना क्रोमियम का उपयोग कर सकते हैं.</translation> <translation id="4994636714258228724">स्वयं को क्रोमियम में जोड़ें</translation> -<translation id="5037694917996535813">आपने काम से जुड़े खाते से साइन इन किया है. क्या आप डेटा को अलग रखने के लिए, क्रोमियम पर नई प्रोफ़ाइल बनाना चाहते हैं?</translation> <translation id="5224391634244552924">कोई भी पासवर्ड सेव नहीं किया गया है. आप जब अपने पासवर्ड सेव करते हैं, तो क्रोमियम उनकी जांच कर सकता है.</translation> <translation id="5277894862589591112">अपने बदलाव लागू करने के लिए, क्रोमियम को फिर से लॉन्च करें</translation> <translation id="5358375970380395591">आप प्रबंधित खाते से साइन इन कर रहे हैं और उसके एडमिन को अपनी क्रोमियम प्रोफ़ाइल पर नियंत्रण दे रहे हैं. आपका क्रोमियम डेटा, जैसे आपके ऐप्लिकेशन, बुकमार्क, इतिहास, पासवर्ड, और दूसरे सेटिंग स्थायी रूप से <ph name="USER_NAME" /> से जुड़ जाएंगे. आप Google खाता डैशबोर्ड के ज़रिए इस डेटा को मिटा सकेंगे, लेकिन आप किसी अन्य खाते से इस डेटा को जोड़ नहीं सकेंगे. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_hr.xtb b/chrome/app/resources/chromium_strings_hr.xtb index f08855b8..c9e4b30 100644 --- a/chrome/app/resources/chromium_strings_hr.xtb +++ b/chrome/app/resources/chromium_strings_hr.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium radi u pozadini.</translation> <translation id="4987820182225656817">Gosti mogu upotrebljavati Chromium bez ostavljanja tragova o upotrebi.</translation> <translation id="4994636714258228724">Dodajte sebe kao korisnika Chromiuma</translation> -<translation id="5037694917996535813">Prijavili ste se poslovnim računom. Želite li izraditi novi Chromiumov profil za posao da bi podaci ostali odvojeni?</translation> <translation id="5224391634244552924">Nema nijedne spremljene zaporke. Chromium može provjeriti vaše zaporke kad ih spremite.</translation> <translation id="5277894862589591112">Da bi se vaše promjene primijenile, ponovo pokrenite Chromium</translation> <translation id="5358375970380395591">Prijavljujete se upravljanim računom i dajete administratoru kontrolu nad svojim profilom u sustavu Chromium. Vaši podaci u sustavu Chromium, primjerice, aplikacije, oznake, povijest, zaporke i ostale postavke, trajno će se povezati s korisnikom <ph name="USER_NAME" />. Moći ćete izbrisati te podatke putem Nadzorne ploče Google računa, ali ih nećete moći povezati s nekim drugim računom. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_hu.xtb b/chrome/app/resources/chromium_strings_hu.xtb index c297a36..d82da9e5 100644 --- a/chrome/app/resources/chromium_strings_hu.xtb +++ b/chrome/app/resources/chromium_strings_hu.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">A Chromium háttérmódban van.</translation> <translation id="4987820182225656817">A vendégek úgy használhatják a Chromiumot, hogy nem hagynak hátra semmit.</translation> <translation id="4994636714258228724">Adja hozzá magát a Chromiumban</translation> -<translation id="5037694917996535813">Ön munkahelyi fiókkal jelentkezett be. Szeretne új Chromium-profilt létrehozni a munkához, hogy adatait elkülönítve tárolhassa?</translation> <translation id="5224391634244552924">Nincsenek mentett jelszavak. A Chromium képes a jelszavak ellenőrzésére, ha Ön elmenti őket.</translation> <translation id="5277894862589591112">A módosítások alkalmazásához indítsa újra a Chromiumot</translation> <translation id="5358375970380395591">Kezelt fiókkal jelentkezik be, és annak adminisztrátora számára hozzáférést biztosít Chromium-profiljához. Chromium-adatait – például alkalmazásait, könyvjelzőit, előzményeit, jelszavait és más beállításait – a rendszer véglegesen társítja a(z) <ph name="USER_NAME" /> fiókhoz. Ezen adatokat a Google-fiók Irányítópultján törölheti, de más fiókhoz nem társíthatja őket. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_hy.xtb b/chrome/app/resources/chromium_strings_hy.xtb index 5d2e4d5..3f382ac 100644 --- a/chrome/app/resources/chromium_strings_hy.xtb +++ b/chrome/app/resources/chromium_strings_hy.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium-ն աշխատում է ֆոնային ռեժիմում:</translation> <translation id="4987820182225656817">Օգտագործելով Chromium-ը հյուրի ռեժիմում՝ դուք ոչ մի հետք չեք թողնում:</translation> <translation id="4994636714258228724">Ավելացրեք ձեր հաշիվը Chromium-ին</translation> -<translation id="5037694917996535813">Դուք մուտք եք գործել աշխատանքային հաշվով։ Ուզո՞ւմ եք ստեղծել Chromium-ի նոր աշխատանքային պրոֆիլ՝ ձեր տվյալներն առանձին պահելու համար։</translation> <translation id="5224391634244552924">Պահված գաղտնաբառեր չկան։ Chromium-ը կարող է ստուգել ձեր գաղտնաբառերը, երբ պահում եք դրանք։</translation> <translation id="5277894862589591112">Փոփոխությունները կիրառելու համար վերագործարկեք Chromium-ը</translation> <translation id="5358375970380395591">Դուք մուտք եք գործում վերահսկվող հաշիվ՝ թույլ տալով ադմինիստրատորին կառավարել ձեր Chromium պրոֆիլը: Ձեր Chromium-ի տվյալները, ինչպես օրինակ՝ հավելվածները, էջանիշները, պատմությունը, գաղտնաբառերը և այլ կարգավորումները, մշտապես կկապվեն <ph name="USER_NAME" />-ի հետ: Դուք կկարողանաք ջնջել այս տվյալները Google Dashboard-ի միջոցով, սակայն չեք կարողանա համակցել դրանք այլ հաշվի հետ: <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_id.xtb b/chrome/app/resources/chromium_strings_id.xtb index c0a2bf0..d57ebdd 100644 --- a/chrome/app/resources/chromium_strings_id.xtb +++ b/chrome/app/resources/chromium_strings_id.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium berjalan di mode latar belakang.</translation> <translation id="4987820182225656817">Tamu dapat menggunakan Chromium tanpa meninggalkan apa pun.</translation> <translation id="4994636714258228724">Tambahkan diri Anda ke Chromium</translation> -<translation id="5037694917996535813">Anda login dengan akun kerja. Ingin membuat Profil Chromium baru untuk Kerja agar data pribadi dan data kerja tetap terpisah?</translation> <translation id="5224391634244552924">Tidak ada sandi yang tersimpan. Chromium dapat memeriksa sandi Anda jika Anda menyimpannya.</translation> <translation id="5277894862589591112">Untuk menerapkan perubahan Anda, luncurkan ulang Chromium</translation> <translation id="5358375970380395591">Anda masuk dengan akun terkelola dan memberikan administratornya kontrol atas profil Chromium Anda. Data Chromium Anda, seperti aplikasi, bookmark, histori, sandi, dan setelan lain selamanya akan dikaitkan ke <ph name="USER_NAME" />. Anda dapat menghapus data ini melalui Dasbor Akun Google, namun Anda tidak akan dapat mengaitkan data ini dengan akun yang lain. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_is.xtb b/chrome/app/resources/chromium_strings_is.xtb index 0a252961..42dadad7 100644 --- a/chrome/app/resources/chromium_strings_is.xtb +++ b/chrome/app/resources/chromium_strings_is.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium er í bakgrunnsstillingu.</translation> <translation id="4987820182225656817">Gestir geta notað Chromium án þess að skilja eftir sig nokkur spor.</translation> <translation id="4994636714258228724">Bættu þér við Chromium</translation> -<translation id="5037694917996535813">Þú skráðir þig inn með vinnureikningi. Viltu búa til nýtt Chromium vinnusnið til að halda gögnunum þínum aðskildum?</translation> <translation id="5224391634244552924">Engin vistuð aðgangsorð. Chromium getur athugað aðgangsorðin þín þegar þú vistar þau.</translation> <translation id="5277894862589591112">Endurræstu Chromium til að breytingarnar taki gildi</translation> <translation id="5358375970380395591">Þú ert að skrá þig inn með stýrðum reikningi og veitir stjórnanda hans vald yfir Chromium prófílnum þínum. Chromium gögnin þín, s.s. forrit, bókamerki, ferill, aðgangsorð og aðrar stillingar, verða tengd varanlega við <ph name="USER_NAME" />. Þú getur eytt þessum gögnum á stjórnborði Google reikninga en getur ekki tengt þau öðrum reikningi. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_it.xtb b/chrome/app/resources/chromium_strings_it.xtb index cc6c0a6..f06b4dfc 100644 --- a/chrome/app/resources/chromium_strings_it.xtb +++ b/chrome/app/resources/chromium_strings_it.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium è in modalità background.</translation> <translation id="4987820182225656817">Gli ospiti possono utilizzare Chromium senza lasciare tracce.</translation> <translation id="4994636714258228724">Aggiungiti a Chromium</translation> -<translation id="5037694917996535813">Hai effettuato l'accesso con un account di lavoro. Vuoi creare un nuovo profilo Chromium di lavoro per mantenere i tuoi dati separati?</translation> <translation id="5224391634244552924">Nessuna password salvata. Chromium può controllare le password quando le salvi.</translation> <translation id="5277894862589591112">Riavvia Chromium per applicare le modifiche</translation> <translation id="5358375970380395591">Stai per accedere con un account gestito e per dare al relativo amministratore il controllo del tuo profilo Chromium. I tuoi dati di Chromium, come app, Preferiti, cronologia, password e altre impostazioni, verranno collegati definitivamente a <ph name="USER_NAME" />. Potrai eliminare questi dati tramite la Dashboard di Google Account, ma non potrai associare questi dati a un altro account. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_iw.xtb b/chrome/app/resources/chromium_strings_iw.xtb index 6b6ab0c..a860543a 100644 --- a/chrome/app/resources/chromium_strings_iw.xtb +++ b/chrome/app/resources/chromium_strings_iw.xtb
@@ -103,7 +103,6 @@ <translation id="4943838377383847465">Chromium נמצא במצב רקע.</translation> <translation id="4987820182225656817">אורחים יכולים להשתמש ב-Chromium בלי להשאיר דבר מאחור.</translation> <translation id="4994636714258228724">הוסף את עצמך ל-Chromium</translation> -<translation id="5037694917996535813">נכנסת באמצעות חשבון לצורכי עבודה. האם ברצונך ליצור פרופיל Chromium חדש לצורכי עבודה כדי לשמור את הנתונים שלך בנפרד?</translation> <translation id="5224391634244552924">אין סיסמאות שמורות. Chromium יכול לבדוק את הסיסמאות שלך רק אם שמרת אותן.</translation> <translation id="5277894862589591112">כדי להחיל את השינויים שביצעת, יש להפעיל מחדש את Chromium</translation> <translation id="5358375970380395591">אתה נכנס עם חשבון מנוהל ונותן למנהל המערכת שלו שליטה על הפרופיל שלך ב-Chromium. הנתונים שלך ב-Chromium, כגון יישומים, סימניות, היסטוריה, סיסמאות והגדרות אחרות ייקשרו באופן קבוע ל-<ph name="USER_NAME" />. תוכל למחוק את הנתונים האלה באמצעות לוח הבקרה של חשבונות Google, אבל לא תוכל לשייך את הנתונים האלה לחשבון אחר. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ja.xtb b/chrome/app/resources/chromium_strings_ja.xtb index fa200fe..cc6e880 100644 --- a/chrome/app/resources/chromium_strings_ja.xtb +++ b/chrome/app/resources/chromium_strings_ja.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium はバックグラウンド モードです。</translation> <translation id="4987820182225656817">ゲスト ユーザーは、記録を残さずに Chromium を使用できます。</translation> <translation id="4994636714258228724">Chromium に自分を追加</translation> -<translation id="5037694917996535813">仕事用アカウントでログインしています。データを分けて保持するよう仕事用の Chromium プロフィールを新しく作成しますか?</translation> <translation id="5224391634244552924">保存されているパスワードがありません。パスワードを保存すると、Chromium で確認できるようになります。</translation> <translation id="5277894862589591112">変更を適用するには Chromium を再起動してください</translation> <translation id="5358375970380395591">現在、管理対象アカウントでログインしており、あなたの Chromium プロフィールを管理者が制御できる状態になっています。あなたの Chromium データ(アプリ、ブックマーク、履歴、パスワードなどの設定)は永続的に <ph name="USER_NAME" /> に関連付けられます。このデータは Google アカウントのダッシュボードを介して削除できますが、このデータを別のアカウントに関連付けることはできなくなります。<ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ka.xtb b/chrome/app/resources/chromium_strings_ka.xtb index e7eaef4..a9c0d6b 100644 --- a/chrome/app/resources/chromium_strings_ka.xtb +++ b/chrome/app/resources/chromium_strings_ka.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium ფონურ რეჟიმშია.</translation> <translation id="4987820182225656817">სტუმრებს შეუძლიათ Chromium-ის გამოყენება და მისი ყველა ფუნქციით სარგებლობა.</translation> <translation id="4994636714258228724">საკუთარი თავის დამატება Chromium-ში</translation> -<translation id="5037694917996535813">თქვენ შეხვედით სამსახურის ანგარიშით. გსურთ, მონაცემების განსაცალკევებლად, შექმნათ ახალი Chromium პროფილი სამსახურისთვის?</translation> <translation id="5224391634244552924">შენახული პაროლები არ არის. პაროლების შემოწმებას Chromium შეძლებს მათი შენახვის შემდეგ.</translation> <translation id="5277894862589591112">ცვლილებების მისასადაგებლად ხელახლა გაუშვით Chromium</translation> <translation id="5358375970380395591">მართული ანგარიშით შედიხართ სისტემაში და ადმინისტრატორს თქვენს Chromium-ის პროფილზე კონტროლს აძლევთ. თქვენი Chromium ის მონაცემები როგორიცაა თქვენი აპლიკაციები, სანიშნები, ისტორიები, პაროლები, და სხვა პარამეტრები მუდმივად მიბმული გახდება <ph name="USER_NAME" />-თან. ამ მონაცემების წაშლას Google ანგარიშის საინფორმაციო დაფის გზით შეძლებთ, მაგრამ შეუძლებელი იქნება ამ მონაცემების სხვა ანგარიშთან გაერთიანება. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_kk.xtb b/chrome/app/resources/chromium_strings_kk.xtb index bfd859e..d2deaf7 100644 --- a/chrome/app/resources/chromium_strings_kk.xtb +++ b/chrome/app/resources/chromium_strings_kk.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium фондық режимде.</translation> <translation id="4987820182225656817">Қонақтар Chromium қолданбасын ешқандай дерек қалдырмай пайдалана алады.</translation> <translation id="4994636714258228724">Chromium жүйесіне өзіңізді қосу</translation> -<translation id="5037694917996535813">Жұмыс есептік жазбасымен кірдіңіз. Деректеріңізді бөлек сақтау үшін жұмысқа жаңа Chromium профилін жасағыңыз келе ме?</translation> <translation id="5224391634244552924">Ешқандай құпия сөз сақталмаған. Құпия сөздер сақталған кезде, Chromium оларды тексере алады.</translation> <translation id="5277894862589591112">Өзгерістер енуі үшін, Chromium браузерін қайта қосыңыз</translation> <translation id="5358375970380395591">Бақыланатын есептік жазба арқылы кірдіңіз және оның әкімшілік бөлігін Chromium профилі арқылы басқару мүмкіндігін бердіңіз. Қолданбалар, бетбелгілер, журнал, құпия сөздер сияқты Chromium деректеріңіз және басқа параметрлер біржола <ph name="USER_NAME" /> пайдаланушысына байланыстырылады. Бұл деректерді Google есептік жазба бақылау тақтасы арқылы жоя аласыз, бірақ бұл деректерді басқа есептік жазбамен байланыстыра алмайсыз. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_km.xtb b/chrome/app/resources/chromium_strings_km.xtb index 7ac6e7af..06613af 100644 --- a/chrome/app/resources/chromium_strings_km.xtb +++ b/chrome/app/resources/chromium_strings_km.xtb
@@ -108,7 +108,6 @@ <translation id="4943838377383847465">Chromium នៅក្នុងរបៀបផ្ទៃខាងក្រោយ។</translation> <translation id="4987820182225656817">ភ្ញៀវអាចប្រើ Chromium ដោយមិនមានបន្សល់ទុកអ្វីឡើយ។</translation> <translation id="4994636714258228724">បន្ថែមខ្លួនអ្នកទៅ Chromium</translation> -<translation id="5037694917996535813">អ្នកបានចូលដោយប្រើគណនីការងារ។ តើអ្នកចង់បង្កើតកម្រងព័ត៌មាន Chromium ថ្មីសម្រាប់ការងារ ដើម្បីរក្សាទុកទិន្នន័យរបស់អ្នកដាច់ដោយឡែកដែរទេ?</translation> <translation id="5224391634244552924">គ្មានពាក្យសម្ងាត់ដែលបានរក្សាទុកទេ។ Chromium អាចពិនិត្យពាក្យសម្ងាត់របស់អ្នក នៅពេលអ្នករក្សាទុកពាក្យសម្ងាត់ទាំងនោះ។</translation> <translation id="5277894862589591112">ដើម្បីអនុវត្តការផ្លាស់ប្ដូររបស់អ្នក សូមចាប់ផ្ដើម Chromium ឡើងវិញ</translation> <translation id="5358375970380395591">អ្នកកំពុងចូលជាមួយគណនីដែលបានគ្រប់គ្រង ហើយផ្តល់ឲ្យអ្នកគ្រប់គ្រងនូវការគ្រប់គ្រងលើទម្រង់ Chromium របស់អ្នក។ ទិន្នន័យ Chromium របស់អ្នក ដូចជាកម្មវិធី គេហទំព័រ ប្រវត្តិ ពាក្យសម្ងាត់ និងការកំណត់ផ្សេងទៀតរបស់អ្នកនឹងភ្ជាប់ជាមួយ <ph name="USER_NAME" /> ជាអចិន្ត្រៃយ៍។ អ្នកនឹងអាចលុបទិន្នន័យនេះតាមរយៈ Google Accounts Dashboard ប៉ុន្តែអ្នកនឹងមិនអាចភ្ជាប់ទិន្នន័យនេះជាមួយគណនីដ៏ទៃទៀតឡើយ។ <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_kn.xtb b/chrome/app/resources/chromium_strings_kn.xtb index 2aca653a..295c14e 100644 --- a/chrome/app/resources/chromium_strings_kn.xtb +++ b/chrome/app/resources/chromium_strings_kn.xtb
@@ -103,7 +103,6 @@ <translation id="4943838377383847465">Chromium ಹಿನ್ನೆಲೆ ಮೋಡ್ನಲ್ಲಿದೆ.</translation> <translation id="4987820182225656817">ಅತಿಥಿಗಳು ಏನನ್ನೂ ಉಳಿಸದೆಯೇ Chromium ಬಳಸಬಹುದು.</translation> <translation id="4994636714258228724">ನೀವಾಗಿಯೇ Chromium ಗೆ ಸೇರಿಕೊಳ್ಳಿ</translation> -<translation id="5037694917996535813">ನೀವು ಕೆಲಸದ ಖಾತೆಯೊಂದಿಗೆ ಸೈನ್ ಇನ್ ಆಗಿದ್ದೀರಿ. ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಪ್ರತ್ಯೇಕವಾಗಿಡಲು, ಕೆಲಸಕ್ಕಾಗಿ ಹೊಸ Chromium ಪ್ರೊಫೈಲ್ ಅನ್ನು ರಚಿಸಲು ನೀವು ಬಯಸುವಿರಾ?</translation> <translation id="5224391634244552924">ಯಾವುದೇ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಉಳಿಸಿಲ್ಲ. ನೀವು ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಉಳಿಸಿದಾಗ, Chromium ಅವುಗಳನ್ನು ಪರಿಶೀಲಿಸಬಹುದು.</translation> <translation id="5277894862589591112">ನಿಮ್ಮ ಬದಲಾವಣೆಗಳನ್ನು ಅನ್ವಯಿಸಲು, Chromium ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿ</translation> <translation id="5358375970380395591">ನೀವು ನಿರ್ವಹಿಸಲಾದ ಖಾತೆಯೊಂದಿಗೆ ಸೈನ್ ಇನ್ ಮಾಡುತ್ತಿರುವಿರಿ ಮತ್ತು ನಿಮ್ಮ Chromium ಪ್ರೊಫೈಲ್ ಮೂಲಕ ಅದರ ನಿರ್ವಾಹಕ ನಿಯಂತ್ರಣವನ್ನು ನೀಡುತ್ತಿರುವಿರಿ. ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ಗಳು, ಬುಕ್ಮಾರ್ಕ್ಗಳು, ಇತಿಹಾಸ, ಪಾಸ್ವರ್ಡ್ಗಳು, ಹಾಗೂ ಇತರ ಸೆಟ್ಟಿಂಗ್ಗಳಂತಹ ನಿಮ್ಮ Chromium ಡೇಟಾವನ್ನು <ph name="USER_NAME" /> ಅವರಿಗೆ ಶಾಶ್ವತವಾಗಿ ಬಂಧಿಸಲಾಗುತ್ತದೆ. Google ಖಾತೆಗಳ ಡ್ಯಾಶ್ಬೋರ್ಡ್ ಮೂಲಕ ಈ ಡೇಟಾವನ್ನು ಅಳಿಸಲು ನಿಮಗೆ ಸಾಧ್ಯ, ಆದರೆ ಬೇರೊಂದು ಖಾತೆಯೊಂದಿಗೆ ಈ ಡೇಟಾವನ್ನು ಸಂಯೋಜಿಸಲು ನಿಮಗೆ ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ko.xtb b/chrome/app/resources/chromium_strings_ko.xtb index 3a015ff..1468563 100644 --- a/chrome/app/resources/chromium_strings_ko.xtb +++ b/chrome/app/resources/chromium_strings_ko.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium이 백그라운드 모드로 실행 중입니다.</translation> <translation id="4987820182225656817">게스트로 사용 기록을 남기지 않고 Chromium을 사용할 수 있습니다.</translation> <translation id="4994636714258228724">Chromium에 본인 추가</translation> -<translation id="5037694917996535813">직장 계정으로 로그인했습니다. 데이터를 별도로 유지하기 위해 직장 Chromium 프로필을 새로 만드시겠습니까?</translation> <translation id="5224391634244552924">저장된 비밀번호가 없습니다. 비밀번호를 저장하면 Chromium에서 확인할 수 있습니다.</translation> <translation id="5277894862589591112">변경사항을 적용하려면 Chromium을 다시 실행하세요.</translation> <translation id="5358375970380395591">관리 계정으로 로그인하고 Chromium 프로필에 대한 관리자 제어권을 부여하려고 합니다. 앱, 북마크, 방문 기록, 비밀번호 및 기타 설정 등 Chromium 데이터가 <ph name="USER_NAME" /> 계정에 영구적으로 연결됩니다. 이후 이 데이터를 Google 계정 대시보드에서 삭제할 수는 있지만 다른 계정에 연결할 수는 없습니다. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ky.xtb b/chrome/app/resources/chromium_strings_ky.xtb index c3a7d170..12a6ca22 100644 --- a/chrome/app/resources/chromium_strings_ky.xtb +++ b/chrome/app/resources/chromium_strings_ky.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium фондук режимде.</translation> <translation id="4987820182225656817">Коноктор Chromium'ду артында эч нерсе калтырбай колдоно алышат.</translation> <translation id="4994636714258228724">Өзүңүздү Chromium'га кошуңуз</translation> -<translation id="5037694917996535813">Жумуш аккаунту менен кирдиңиз. Жумуш үчүн Chromium профилин түзүп, маалыматты өзүнчө сактагыңыз келеби?</translation> <translation id="5224391634244552924">Сакталган сырсөздөр жок. Сырсөздөрүңүздү сактаганда Chromium аларды текшере алат.</translation> <translation id="5277894862589591112">Өзгөртүүлөрдү киргизүү үчүн Chromium'ду кайра иштетиңиз</translation> <translation id="5358375970380395591">Башкарылган аккаунт менен кирип, анын администраторуна Chromiun профилиңизди көзөмөлдөө мүмкүнчүлүгүн берип жатасыз. Колдонмолоруңуз, кыстармалар, таржымал, сырсөздөр жана башка жөндөөлөр сыяктуу Chromium дайын-даректериңиз эми биротоло <ph name="USER_NAME" /> менен байланып калат. Бул дайындарды Google Каттоо эсептеринин Жеке кеңсеси аркылуу жок кылсаңыз болот, бирок башка аккаунтка байланыштыра албайсыз.<ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_lo.xtb b/chrome/app/resources/chromium_strings_lo.xtb index a45f346..0813f94 100644 --- a/chrome/app/resources/chromium_strings_lo.xtb +++ b/chrome/app/resources/chromium_strings_lo.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium ຢູ່ໃນໂໝດພື້ນຫຼັງ.</translation> <translation id="4987820182225656817">ແຂກສາມາດໃຊ້ Chromium ໂດຍບໍ່ມີການປະອັນໃດໄວ້ເບື້ອງຫຼັງ.</translation> <translation id="4994636714258228724">ເພີ່ມທ່ານເອງໃສ່ Chromium</translation> -<translation id="5037694917996535813">ທ່ານເຂົ້າສູ່ລະບົບດ້ວຍບັນຊີບ່ອນເຮັດວຽກ. ທ່ານຕ້ອງການສ້າງໂປຣໄຟລ໌ Chromium ໃໝ່ສຳລັບວຽກເພື່ອເກັບຮັກສາຂໍ້ມູນຂອງທ່ານແຍກໄວ້ຕ່າງຫາກ.</translation> <translation id="5224391634244552924">ບໍ່ມີລະຫັດຜ່ານທີ່ບັນທຶກໄວ້. Chromium ສາມາດກວດເບິ່ງລະຫັດຜ່ານຂອງທ່ານເມື່ອທ່ານບັນທຶກພວກມັນໄວ້.</translation> <translation id="5277894862589591112">ເພື່ອນຳໃຊ້ການປ່ຽນແປງຂອງທ່ານ, ກະລຸນາເປີດ Chromium ຄືນໃໝ່</translation> <translation id="5358375970380395591">ທ່ານກໍາລັງລົງຊື່ເຂົ້າໃຊ້ດ້ວຍບັນຊີຄຸ້ມຄອງ ແລະໃຫ້ຜູ້ຄວບຄຸມຂອງມັນຄວບຄຸມໂປຣໄຟລ໌ Chromium ຂອງທ່ານ. ຂໍ້ມູນ Chromium ຂອງທ່ານ, ເຊັ່ນ: ແອັບ, ບຸກມາກສ໌, ປະຫວັດ, ລະຫັດຜ່ານ, ແລະການຕັ້ງຄ່າອື່ນໆຂອງທ່ານຈະຖືກຜູກມັດກັບ <ph name="USER_NAME" /> ຢ່າງຖາວອນ. ທ່ານຈະສາມາດລຶບຂໍ້ມູນນີ້ໄດ້ຜ່ານ Google Accounts Dashboard, ແຕ່ທ່ານຈະບໍ່ສາມາດເອົາຂໍ້ມູນນີ້ເຂົ້າຮ່ວມກັບບັນຊີອື່ນໄດ້. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_lt.xtb b/chrome/app/resources/chromium_strings_lt.xtb index e8d75f72..d9df327 100644 --- a/chrome/app/resources/chromium_strings_lt.xtb +++ b/chrome/app/resources/chromium_strings_lt.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">„Chromium“ veikia fono režimu.</translation> <translation id="4987820182225656817">Svečiai gali naudoti „Chromium“ nepalikdami jokių duomenų.</translation> <translation id="4994636714258228724">Pridėkite save prie „Chromium“</translation> -<translation id="5037694917996535813">Prisijungėte naudodami darbo paskyrą. Ar norėtumėte sukurti naują „Chromium“ darbo profilį, kad duomenys būtų saugomi atskirai?</translation> <translation id="5224391634244552924">Nėra išsaugotų slaptažodžių. „Chromium“ gali tikrinti jūsų slaptažodžius, kai juos išsaugote.</translation> <translation id="5277894862589591112">Norėdami pritaikyti pakeitimus, paleiskite „Chromium“ iš naujo</translation> <translation id="5358375970380395591">Prisijungiate su valdoma paskyra ir leidžiate jos administratoriui valdyti jūsų „Chromium“ profilį. „Chromium“ duomenys, pvz., programos, žymės, istorija, slaptažodžiai ir kiti nustatymai, bus visam laikui susieti su <ph name="USER_NAME" />. Galėsite ištrinti šiuos duomenis naudodami „Google“ paskyrų informacijos suvestinę, bet negalėsite susieti šių duomenų su kita paskyra. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_lv.xtb b/chrome/app/resources/chromium_strings_lv.xtb index 36baef8..dc77c7c 100644 --- a/chrome/app/resources/chromium_strings_lv.xtb +++ b/chrome/app/resources/chromium_strings_lv.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium darbojas fona režīmā.</translation> <translation id="4987820182225656817">Viesi var izmantot Chromium, neatstājot nekādas pēdas.</translation> <translation id="4994636714258228724">Pievienot savu kontu pārlūkā Chromium</translation> -<translation id="5037694917996535813">Jūs pierakstījāties ar darba kontu. Vai vēlaties pārlūkā Chromium izveidot jaunu darba profilu, lai glabātu datus atsevišķi?</translation> <translation id="5224391634244552924">Nav saglabātu paroļu. Pārlūkprogrammā Chromium var pārbaudīt jūsu paroles, ja jūs tās saglabājat.</translation> <translation id="5277894862589591112">Lai ieviestu veiktās izmaiņas, atkārtoti palaidiet pārlūku Chromium.</translation> <translation id="5358375970380395591">Jūs pierakstāties ar pārvaldītu kontu, kura administrators var kontrolēt jūsu profilu. Jūsu Chromium dati, piemēram, lietotnes, grāmatzīmes, vēsture, paroles un citi iestatījumi, tiks neatgriezeniski saistīti ar lietotāju <ph name="USER_NAME" />. Varēsiet dzēst šos datus, izmantojot Google kontu informācijas paneli, taču nevarēsiet šos datus saistīt ar citu kontu. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_mk.xtb b/chrome/app/resources/chromium_strings_mk.xtb index 84a46ed..8163173 100644 --- a/chrome/app/resources/chromium_strings_mk.xtb +++ b/chrome/app/resources/chromium_strings_mk.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium е во заднински режим.</translation> <translation id="4987820182225656817">Гостите може да го користат Chromium без оставање никакви траги зад нив.</translation> <translation id="4994636714258228724">Додај се себеси на Chromium</translation> -<translation id="5037694917996535813">Се најавивте со работна сметка. Дали би сакале да создадете нов профил за работа на Chromium за да ги чувате податоците одделно?</translation> <translation id="5224391634244552924">Немате зачувани лозинки. Chromium може да ги проверува вашите лозинки ако ги зачувате.</translation> <translation id="5277894862589591112">За да се применат измените, рестартирајте го Chromium</translation> <translation id="5358375970380395591">Се пријавувате со управувана сметка и му давате контрола на администраторот над вашиот профил на Chromium. Вашите податоци на Chromium, како на пример ваши апликации, обележувачи, историја, лозинки и други поставки ќе бидат трајно поврзани со <ph name="USER_NAME" />. Може да ги бришете овие податоци преку информациската табла со сметки на Google, но нема да може да ги поврзувате овие податоци со друга сметка. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ml.xtb b/chrome/app/resources/chromium_strings_ml.xtb index ed7389a..4f4a850 100644 --- a/chrome/app/resources/chromium_strings_ml.xtb +++ b/chrome/app/resources/chromium_strings_ml.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium പശ്ചാത്തല മോഡിലാണ്.</translation> <translation id="4987820182225656817">അതിഥികൾക്ക് ഒന്നും ശേഷിപ്പിക്കാതെ തന്നെ Chromium ഉപയോഗിക്കാനാകും.</translation> <translation id="4994636714258228724">Chromium-ലേക്ക് സ്വയം ചേരുക</translation> -<translation id="5037694917996535813">നിങ്ങൾ ഒരു ഔദ്യോഗിക അക്കൗണ്ട് ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്തു. നിങ്ങളുടെ ഡാറ്റ പ്രത്യേകം വേർതിരിച്ച് സൂക്ഷിക്കാൻ ഔദ്യോഗികാവശ്യത്തിനുള്ള പുതിയൊരു Chromium പ്രൊഫൈൽ സൃഷ്ടിക്കണോ?</translation> <translation id="5224391634244552924">സംരക്ഷിച്ച പാസ്വേഡുകളൊന്നുമില്ല. നിങ്ങളുടെ പാസ്വേഡുകൾ സംരക്ഷിക്കുകയാണങ്കിൽ, Chromium-ന് അവ പരിശോധിക്കാനാവും.</translation> <translation id="5277894862589591112">നിങ്ങളുടെ മാറ്റങ്ങൾ ബാധകമാക്കാൻ Chromium സമാരംഭിക്കുക</translation> <translation id="5358375970380395591">നിങ്ങൾ ഒരു നിയന്ത്രിത അക്കൗണ്ട് ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്ത് അതിന്റെ അഡ്മിന് നിങ്ങളുടെ Chromium പ്രൊഫൈലിന്റെ നിയന്ത്രണം നൽകുന്നു. നിങ്ങളുടെ ആപ്പുകൾ, ബുക്ക്മാർക്കുകൾ, ചരിത്രം, പാസ്വേഡുകൾ, മറ്റ് ക്രമീകരണങ്ങൾ എന്നിവ പോലെയുള്ള Chromium ഡാറ്റ <ph name="USER_NAME" /> എന്നതുമായി ശാശ്വതമായി ബന്ധിപ്പിച്ചതായിത്തീരും. Google അക്കൗണ്ട്സ് ഡാഷ്ബോർഡ് വഴി നിങ്ങൾക്ക് ഈ ഡാറ്റ ഇല്ലാതാക്കാനാകുമെങ്കിലും, ഈ ഡാറ്റ മറ്റൊരു അക്കൗണ്ടുമായി ബന്ധപ്പെടുത്താനാകില്ല. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_mn.xtb b/chrome/app/resources/chromium_strings_mn.xtb index 4fbbc182..64629bcf 100644 --- a/chrome/app/resources/chromium_strings_mn.xtb +++ b/chrome/app/resources/chromium_strings_mn.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium нь суурь горимд байна.</translation> <translation id="4987820182225656817">Зочид Chromium-ийг ашигласнаар хамгийн сүүлийн үеийн мэдээллийг авна.</translation> <translation id="4994636714258228724">Өөрийгөө Chromium руу нэмэх</translation> -<translation id="5037694917996535813">Та ажлын бүртгэлээр нэвтэрсэн. Та өгөгдлөө тусад нь хадгалахын тулд ажилд зориулсан шинэ Chromium-н профайл үүсгэмээр байна уу?</translation> <translation id="5224391634244552924">Хадгалсан ямар ч нууц үг алга. Таныг нууц үгсээ хадгалах үед Chromium тэднийг шалгах боломжтой.</translation> <translation id="5277894862589591112">Өөрчлөлтөө хэрэгжүүлэхийн тулд Chromium-г дахин ажиллуулна уу</translation> <translation id="5358375970380395591">Та удирдан ажиллаж буй хаягт нэвтэрч байгаагаас гадна таны Chromium профайлыг хянах эрхийг системийн ажилтанд шилжүүлж байна. Таны апп, хавчуурга, түүх, нууц үг болон бусад тохиргоо гэх мэт таны Chromium өгөгдлийг <ph name="USER_NAME" />-тэй холбох болно. Та энэхүү өгөгдлийг Google Accounts Dashboard-р дамжуулан устгах боломжтой боловч та энэхүү өгөгдлийн өөр хаягтай холбох боломжгүй байна. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_mr.xtb b/chrome/app/resources/chromium_strings_mr.xtb index af6d39c..fb251851 100644 --- a/chrome/app/resources/chromium_strings_mr.xtb +++ b/chrome/app/resources/chromium_strings_mr.xtb
@@ -106,7 +106,6 @@ <translation id="4943838377383847465">Chromium पार्श्वभूमी मोड मध्ये आहे.</translation> <translation id="4987820182225656817">अतिथी कोणतीही गोष्ट मागे न सोडता Chromium वापरू शकतात.</translation> <translation id="4994636714258228724">आपल्या स्वतःस Chromium वर जोडा</translation> -<translation id="5037694917996535813">तुम्ही ऑफिस खाते वापरून साइन इन केले आहे. तुमचा डेटा स्वतंत्र ठेवण्यासाठी तुम्हाला कामासाठी नवीन Chromium प्रोफाइल तयार करायची आहे का?</translation> <translation id="5224391634244552924">सेव्ह केलेले पासवर्ड नाहीत. तुम्ही तुमचे पासवर्ड सेव्ह केल्यावर Chromium ते तपासू शकते.</translation> <translation id="5277894862589591112">तुम्ही केलेले बदल लागू करण्यासाठी, Chromium रीलाँच करा</translation> <translation id="5358375970380395591">तुम्ही एका व्यवस्थापित खात्यासह साइन इन करत आहात आणि तुमच्या Chromium प्रोफाइलवर त्याच्या ॲडमिनिस्ट्रेटरला नियंत्रण देत आहात. तुमचा Chromium डेटा, जसे की तुमचे अॅप्स, बुकमार्क, इतिहास, पासवर्ड आणि अन्य सेटिंग्ज <ph name="USER_NAME" /> वर कायमच्या बद्ध होतील. तुम्ही Google खाती डॅशबोर्डद्वारे हा डेटा हटवण्यात सक्षम व्हाल, परंतु तुम्ही दुसर्या खात्यासह हा डेटा संबद्ध करण्यात सक्षम असणार नाही. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ms.xtb b/chrome/app/resources/chromium_strings_ms.xtb index cd4d1d4..12d1794 100644 --- a/chrome/app/resources/chromium_strings_ms.xtb +++ b/chrome/app/resources/chromium_strings_ms.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium dalam mod latar belakang.</translation> <translation id="4987820182225656817">Tetamu boleh menggunakan Chromium tanpa meninggalkan apa-apa.</translation> <translation id="4994636714258228724">Tambahkan diri anda kepada Chromium</translation> -<translation id="5037694917996535813">Anda dilog masuk dengan akaun kerja. Adakah anda mahu membuat Profil Chromium untuk Kerja yang baharu untuk mengasingkan data anda?</translation> <translation id="5224391634244552924">Tiada kata laluan yang disimpan. Chromium boleh menyemak kata laluan anda yang disimpan.</translation> <translation id="5277894862589591112">Untuk menggunakan perubahan anda, mulakan semula Chromium</translation> <translation id="5358375970380395591">Anda log masuk menggunakan akaun yang terurus dan memberikan pentadbirnya kawalan ke atas profil Chromium anda. Data Chromium anda, seperti apl, penanda halaman, sejarah, kata laluan dan tetapan anda yang lain akan terikat kepada <ph name="USER_NAME" /> secara kekal. Anda akan dapat memadamkan data ini melalui Papan Pemuka Akaun Google, tetapi anda tidak akan dapat mengaitkan data ini dengan akaun lain. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_my.xtb b/chrome/app/resources/chromium_strings_my.xtb index 37caca6..45953736 100644 --- a/chrome/app/resources/chromium_strings_my.xtb +++ b/chrome/app/resources/chromium_strings_my.xtb
@@ -98,7 +98,7 @@ <translation id="4677944499843243528">ပရိုဖိုင်ကို အခြား ကွန်ပျူတာ <ph name="HOST_NAME" /> ထဲက (<ph name="PROCESS_ID" />) အခြား Chromium လုပ်ငန်းစဉ် တစ်ခုက သုံးနေပုံရသည်။ ထိုပရိုဖိုင် ပျက်စီး မသွားစေချင်ငှါ Chromium သည် ၎င်းကို ပိတ်ဆို့လိုက်သည်။ သင့်အနေနှင့် အခြား မည်သည့် လုပ်ငန်းစဉ်များကမှ ဒီပရိုဖိုင်ကို မသုံးကြောင်း သေချာလျှင်၊ သင်သည် ပရိုဖိုင်ကို သော့ဖွင့်လျက် Chromium ကို ပြန်ဖွင့်တင်နိုင်ပါသည်။</translation> <translation id="469338717132742108">Chromium OS အကူအညီရယူရန်</translation> <translation id="4708774505295300557">တစ်စုံတစ်ယောက်သည် ယခင်က ဤကွန်ပျူတာပေါ်တွင် Chromium သို့ <ph name="ACCOUNT_EMAIL_LAST" /> အဖြစ် လက်မှတ်ထိုးဝင်ခဲ့သည်။ သင့်အချက်အလက်များကို ခွဲခြားထားရန် Chromium အသုံးပြုသူ အသစ်သတ်မှတ်ပါ။</translation> -<translation id="4745225042341419983">ဤ space ၏ ကြည့်ရှုမှုဒေတာများကို ဤကိရိယာမှနေ၍ ဖျက်လိုက်ပါမည်။ ဒေတာကို ပြန်လည်ရယူရန် အဖြစ် Chromium သို့ လက်မှတ်ထိုးဝင်ပါ</translation> +<translation id="4745225042341419983">ဤ space ၏ ကြည့်ရှုမှုဒေတာများကို ဤကိရိယာမှနေ၍ ဖျက်လိုက်ပါမည်။ ဒေတာကို ပြန်လည်ရယူရန် အောက်ပါဖြင့် Chromium သို့ လက်မှတ်ထိုးဝင်ပါ</translation> <translation id="4746050847053251315">မည်သို့ပင်ဖြစ်စေ Chromium ကို ပိတ်လိုပါသလား။</translation> <translation id="4748217263233248895">Chromium အတွက် အထူးလုံခြုံရေးအပ်ဒိတ်ကို ယခုလေးတင် ထည့်သွင်းထားသည်။ ယခုပြန်လည်စတင်လိုက်ပါက သင်၏ တဘ်များကို ပြန်ဖွင့်ပေးပါမည်။</translation> <translation id="4750035648288509542">အပ်ဒိတ်လုပ်ပြီးပါတော့မည်။ အပ်ဒိတ်လုပ်ခြင်း အပြီးသတ်ရန် Chromium ကို ပြန်ဖွင့်ပါ။ ရုပ်ဖျက် ဝင်ဒိုးများကို ပြန်ဖွင့်မည် မဟုတ်ပါ။</translation> @@ -108,7 +108,6 @@ <translation id="4943838377383847465">Chromium သည် နောက်ခံ မုဒ်ထဲမှာ ရှိနေသည်။</translation> <translation id="4987820182225656817">ဧည့်သည်များသည် Chromium ကို သုံးနိုင်ကြကာ နောက်မှာ ဘာမှ ကျန်ရစ်မည် မဟုတ်ပါ။</translation> <translation id="4994636714258228724">Chromium သို့သင့်ကိုယ်သင် ပေါင်းထည့်ရန်</translation> -<translation id="5037694917996535813">အလုပ်သုံးအကောင့်ဖြင့် သင်လက်မှတ်ထိုးဝင်ခဲ့သည်။ သင့်ဒေတာကို ခွဲထားရန်အတွက် အလုပ်သုံး Chromium ပရိုဖိုင်အသစ်တစ်ခု ပြုလုပ်လိုသလား။</translation> <translation id="5224391634244552924">သိမ်းထားသော စကားဝှက် မရှိပါ။ သင်စကားဝှက်များကို သိမ်းသည့်အခါ Chromium က ၎င်းတို့ကို စစ်ဆေးနိုင်သည်။</translation> <translation id="5277894862589591112">သင့်အပြောင်းအလဲများ ထည့်သွင်းရန် Chromium ကို ပြန်စတင်ပါ</translation> <translation id="5358375970380395591">သင်သည် စီမံကွပ်ကဲထားသည့် အကောင့် ထဲသို့ လက်မှတ် ထိုးဝင်နေကာ စီမံအုပ်ချုပ်သူအား
diff --git a/chrome/app/resources/chromium_strings_ne.xtb b/chrome/app/resources/chromium_strings_ne.xtb index 86038ec..5f65466 100644 --- a/chrome/app/resources/chromium_strings_ne.xtb +++ b/chrome/app/resources/chromium_strings_ne.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium पृष्ठभूमि मोडमा छ।</translation> <translation id="4987820182225656817">अतिथिहरूले कुनैपनि कुरालाई पछाडि छोडे बिना Chromium प्रयोग गर्न सक्छन्।</translation> <translation id="4994636714258228724">तपाइँ अफैलाई Chromium मा थप्नुहोस्</translation> -<translation id="5037694917996535813">तपाईंले कार्य खाता प्रयोग गरी साइन इन गर्नुभयो। तपाईं कार्यसम्बन्धी आफ्नो डेटा छुट्टै राख्न Chromium को नयाँ प्रोफाइल बनाउन चाहनुहुन्छ?</translation> <translation id="5224391634244552924">कुनै पनि पासवर्ड सुरक्षित गरिएको छैन। तपाईंले आफ्ना पासवर्डहरू सुरक्षित गर्नुभएको छ भने मात्र Chromium ले तिनको जाँच गर्न सक्छ।</translation> <translation id="5277894862589591112">आफूले गरेका परिवर्तनहरू लागू गर्न Chromium पुनः सुरु गर्नुहोस्</translation> <translation id="5358375970380395591">तपाइँ एक व्यवस्थापित खाताको साथमा साइनइन गर्दै हुनुहुन्छ र त्यसको प्रशासकलाई तपाइँको Chromium प्रोफाइलमा नियन्त्रण दिँदै हुनुहुन्छ। तपाइँको Chromium लगत, जस्तै की तपाइँका एपहरू, पृष्ठमञ्जूषाहरू, इतिहास, पासवर्डहरू, र अन्य सेटिङहरू स्थायी रूपमा <ph name="USER_NAME" /> मा बाँधिनेछ। तपाइँले यस लगतलाई Google खााता ड्यासबोर्ड मार्पत हटाउन सक्नुहुनेछ, तर तपाइँले यस लगतलाई अर्को खातासँग सम्बन्ध गर्न सक्नुहुनेछैन। <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_nl.xtb b/chrome/app/resources/chromium_strings_nl.xtb index 3a5c06d5..557cf82 100644 --- a/chrome/app/resources/chromium_strings_nl.xtb +++ b/chrome/app/resources/chromium_strings_nl.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium bevindt zich in de achtergrondmodus.</translation> <translation id="4987820182225656817">Gasten kunnen Chromium gebruiken zonder iets achter te laten.</translation> <translation id="4994636714258228724">Jezelf toevoegen aan Chromium</translation> -<translation id="5037694917996535813">Je bent ingelogd met een werkaccount. Wil je een nieuw Chromium-profiel voor je werk maken zodat je je gegevens gescheiden kunt houden?</translation> <translation id="5224391634244552924">Geen opgeslagen wachtwoorden. Chromium kan je wachtwoorden checken als je deze hebt opgeslagen.</translation> <translation id="5277894862589591112">Als je de wijzigingen wilt toepassen, start je Chromium opnieuw</translation> <translation id="5358375970380395591">Je logt in op een beheerd account waarmee de eigenaar van dat account beheer krijgt over je Chromium-profiel. Je Chromium-gegevens zoals je apps, bookmarks, geschiedenis, wachtwoorden en andere instellingen worden permanent gekoppeld aan <ph name="USER_NAME" />. Je kunt deze gegevens verwijderen via het Google Accounts Dashboard, maar je kunt deze gegevens niet koppelen aan een ander account.<ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_no.xtb b/chrome/app/resources/chromium_strings_no.xtb index 8b7f214..a7c5822 100644 --- a/chrome/app/resources/chromium_strings_no.xtb +++ b/chrome/app/resources/chromium_strings_no.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium er i bakgrunnsmodus.</translation> <translation id="4987820182225656817">Gjester kan bruke Chromium uten å etterlate seg spor.</translation> <translation id="4994636714258228724">Legg til deg selv i Chromium</translation> -<translation id="5037694917996535813">Du har logget på med en jobbkonto. Vil du opprette en ny Chromium-profil for arbeid for å holde dataene dine atskilt?</translation> <translation id="5224391634244552924">Ingen lagrede passord. Chromium kan sjekke passordene dine når du lagrer dem.</translation> <translation id="5277894862589591112">For å bruke endringene dine må du starte Chromium på nytt</translation> <translation id="5358375970380395591">Du logger deg på med en administrert konto og gir tilhørende administratorer kontroll over Chromium-profilen din. Chromium-dataene dine, slik som apper, bokmerker, loggen, passord og andre innstillinger, knyttes permanent til <ph name="USER_NAME" />. Du kan slette disse dataene via oversikten for Google-kontoer, men du kan ikke knytte disse dataene til en annen konto. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_or.xtb b/chrome/app/resources/chromium_strings_or.xtb index 0a6bb6a..19f9277 100644 --- a/chrome/app/resources/chromium_strings_or.xtb +++ b/chrome/app/resources/chromium_strings_or.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium ପୃଷ୍ଠପଟ ମୋଡ୍ରେ ଅଛି।</translation> <translation id="4987820182225656817">କିଛି ପଛରେ ନଛାଡ଼ି ଅତିଥି Chromium ବ୍ୟବହାର କରିପାରିବେ।</translation> <translation id="4994636714258228724">Chromium ସହ ନିଜକୁ ଯୋଗ କରନ୍ତୁ</translation> -<translation id="5037694917996535813">ଆପଣ ଏକ କାର୍ଯ୍ୟସ୍ଥଳୀ ଆକାଉଣ୍ଟ ସହ ସାଇନ୍ ଇନ୍ କରିଛନ୍ତି। ଆପଣ ଆପଣଙ୍କ ଡାଟାକୁ ଅଲଗା ରଖିବା ପାଇଁ କାର୍ଯ୍ୟ ନିମନ୍ତେ ଏକ ନୂଆ Chromium ପ୍ରୋଫାଇଲ୍ ତିଆରି କରିବାକୁ ପସନ୍ଦ କରିବେ?</translation> <translation id="5224391634244552924">ସେଭ୍ କରାଯାଇଥିବା କୌଣସି ପାସୱାର୍ଡ ନାହିଁ। ଆପଣ ପାସୱାର୍ଡଗୁଡ଼ିକ ସେଭ୍ କଲେ Chromium ସେଗୁଡ଼ିକୁ ଯାଞ୍ଚ କରିପାରିବ।</translation> <translation id="5277894862589591112">ଆପଣ କରିଥିବା ପରିବର୍ତ୍ତନଗୁଡ଼ିକୁ ଲାଗୁ କରିବା ପାଇଁ Chromiumକୁ ପୁଣି ଲଞ୍ଚ କରନ୍ତୁ</translation> <translation id="5358375970380395591">ଆପଣ ଏକ ପରିଚାଳିତ ଆକାଉଣ୍ଟ ମାଧ୍ୟମରେ ସାଇନ୍ ଇନ୍ କରିଛନ୍ତି ଏବଂ ଏହାର ବ୍ୟବସ୍ଥାପକଙ୍କୁ ଆପଣଙ୍କ Chromium ପ୍ରୋଫାଇଲ୍ର ନିୟନ୍ତ୍ରଣ ଦେଇଛନ୍ତି। ଆପଣଙ୍କର Chromium ଡାଟା ଯେପରିକି, ଆପଣଙ୍କର ଆପ୍ସ, ବୁକ୍ମାର୍କଗୁଡ଼ିକ, ଇତିବୃତ୍ତି, ପାସ୍ୱର୍ଡଗୁଡ଼ିକ ଏବଂ ଅନ୍ୟାନ୍ୟ ସେଟିଂସ୍ ସ୍ଥାୟୀରୂପେ <ph name="USER_NAME" />କୁ ଯୋଡ଼ି ହୋଇଯିବ। ଆପଣ ଏହି ଡାଟାକୁ Google ଆକାଉଣ୍ଟ ଡ୍ୟାସ୍ବୋର୍ଡ ମାଧ୍ୟମରେ ଡିଲିଟ୍ କରିପାରିବେ, କିନ୍ତୁ ଆପଣ ଏହି ଡାଟାକୁ ଅନ୍ୟ ଆକାଉଣ୍ଟ ସହିତ ଜଡ଼ିତ କରିପାରିବେ ନାହିଁ। <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_pa.xtb b/chrome/app/resources/chromium_strings_pa.xtb index 7dae8a97..df6c1dba 100644 --- a/chrome/app/resources/chromium_strings_pa.xtb +++ b/chrome/app/resources/chromium_strings_pa.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium ਪਿਛੋਕੜ ਮੋਡ ਵਿੱਚ ਹੈ।</translation> <translation id="4987820182225656817">ਮਹਿਮਾਨ ਕੁਝ ਵੀ ਪਿੱਛੇ ਛੱਡੇ ਬਿਨਾਂ Chromium ਵਰਤ ਸਕਦੇ ਹਨ।</translation> <translation id="4994636714258228724">ਖੁਦ ਨੂੰ Chromium ਵਿੱਚ ਜੋੜੋ</translation> -<translation id="5037694917996535813">ਤੁਸੀਂ ਕਾਰਜ ਖਾਤੇ ਨਾਲ ਸਾਈਨ-ਇਨ ਹੋਏ। ਕੀ ਤੁਸੀਂ ਆਪਣੇ ਡਾਟੇ ਨੂੰ ਵੱਖਰਾ ਰੱਖਣ ਲਈ ਕਾਰਜ ਵਾਸਤੇ ਨਵਾਂ Chromium ਪ੍ਰੋਫਾਈਲ ਬਣਾਉਣਾ ਚਾਹੋਗੇ?</translation> <translation id="5224391634244552924">ਕੋਈ ਰੱਖਿਅਤ ਕੀਤਾ ਪਾਸਵਰਡ ਨਹੀਂ। ਤੁਹਾਡੇ ਵੱਲੋਂ ਆਪਣੇ ਪਾਸਵਰਡ ਰੱਖਿਅਤ ਕਰਨ 'ਤੇ Chromium ਉਹਨਾਂ ਦੀ ਜਾਂਚ ਕਰ ਸਕਦਾ ਹੈ।</translation> <translation id="5277894862589591112">ਆਪਣੀਆਂ ਤਬਦੀਲੀਆਂ ਲਾਗੂ ਕਰਨ ਲਈ, Chromium ਨੂੰ ਮੁੜ-ਲਾਂਚ ਕਰੋ</translation> <translation id="5358375970380395591">ਤੁਸੀਂ ਇੱਕ ਪ੍ਰਬੰਧਿਤ ਕੀਤੇ ਖਾਤੇ ਨਾਲ ਸਾਈਨ-ਇਨ ਕਰ ਰਹੇ ਹੋ ਅਤੇ ਇਸ ਦੇ ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਆਪਣੇ Chromium ਪ੍ਰੋਫਾਈਲ ਦਾ ਕੰਟਰੋਲ ਦੇ ਰਹੇ ਹੋ। ਤੁਹਾਡਾ Chromium ਡਾਟਾ, ਜਿਵੇਂ ਕਿ ਤੁਹਾਡੀਆਂ ਐਪਾਂ, ਬੁੱਕਮਾਰਕ, ਇਤਿਹਾਸ, ਪਾਸਵਰਡ, ਅਤੇ ਹੋਰ ਸੈਟਿੰਗਾਂ <ph name="USER_NAME" /> ਨਾਲ ਸਥਾਈ ਤੌਰ 'ਤੇ ਜੋੜੇ ਜਾਣਗੇ। ਤੁਸੀਂ ਇਸ ਡਾਟੇ ਨੂੰ Google ਖਾਤੇ ਡੈਸ਼ਬੋਰਡ ਰਾਹੀਂ ਮਿਟਾ ਸਕੋਗੇ, ਪਰ ਤੁਸੀਂ ਇਸ ਡਾਟੇ ਨੂੰ ਦੂਜੇ ਖਾਤੇ ਨਾਲ ਨਹੀਂ ਜੋੜ ਸਕੋਗੇ। <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_pl.xtb b/chrome/app/resources/chromium_strings_pl.xtb index b86fc554..2046ac6 100644 --- a/chrome/app/resources/chromium_strings_pl.xtb +++ b/chrome/app/resources/chromium_strings_pl.xtb
@@ -103,7 +103,6 @@ <translation id="4943838377383847465">Chromium jest w trybie działania w tle</translation> <translation id="4987820182225656817">Goście mogą korzystać z Chromium, nie pozostawiając żadnych danych.</translation> <translation id="4994636714258228724">Dodaj siebie do Chromium</translation> -<translation id="5037694917996535813">Używasz konta do pracy. Czy chcesz utworzyć nowy profil Chromium do pracy, by przechowywać dane oddzielnie?</translation> <translation id="5224391634244552924">Brak zapisanych haseł. Chromium może sprawdzać Twoje hasła, gdy je zapiszesz.</translation> <translation id="5277894862589591112">Aby zastosować zmiany, uruchom ponownie Chromium</translation> <translation id="5358375970380395591">Logujesz się na zarządzane konto i przekazujesz jego administratorowi kontrolę nad swoim profilem Chromium. Twoje dane Chromium, takie jak aplikacje, zakładki, historia, hasła i inne ustawienia, zostaną trwale powiązane z użytkownikiem <ph name="USER_NAME" />. Będzie można je usunąć w Panelu kont Google, ale nie będzie można ich powiązać z innym kontem. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_pt-BR.xtb b/chrome/app/resources/chromium_strings_pt-BR.xtb index 1a81011..7e7d34b 100644 --- a/chrome/app/resources/chromium_strings_pt-BR.xtb +++ b/chrome/app/resources/chromium_strings_pt-BR.xtb
@@ -103,7 +103,6 @@ <translation id="4943838377383847465">O Chromium está em modo de segundo plano.</translation> <translation id="4987820182225656817">Convidados podem usar o Chromium sem deixar nada para trás.</translation> <translation id="4994636714258228724">Cadastrar-se no Chromium</translation> -<translation id="5037694917996535813">Você fez login com uma conta de trabalho. Quer criar um novo perfil do Chromium para trabalho e manter seus dados separados?</translation> <translation id="5224391634244552924">Nenhuma senha salva. O Chromium poderá verificar suas senhas quando elas forem salvas.</translation> <translation id="5277894862589591112">Para que as alterações sejam aplicadas, reinicie o Chromium</translation> <translation id="5358375970380395591">Você está fazendo login com uma conta gerenciada e concedendo ao administrador da conta o controle sobre seu perfil do Chromium. Seus dados do Chromium, como aplicativos, favoritos, histórico, senhas e outras configurações serão permanentemente vinculados a <ph name="USER_NAME" />. Você pode excluir esses dados pelo painel das Contas do Google, mas não pode associá-los a outra conta. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_pt-PT.xtb b/chrome/app/resources/chromium_strings_pt-PT.xtb index 2b3ecb8..c8c8d7e 100644 --- a/chrome/app/resources/chromium_strings_pt-PT.xtb +++ b/chrome/app/resources/chromium_strings_pt-PT.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">O Chromium está no modo em segundo plano.</translation> <translation id="4987820182225656817">Os convidados podem utilizar o Chromium sem perder qualquer funcionalidade.</translation> <translation id="4994636714258228724">Adicionar-se ao Chromium</translation> -<translation id="5037694917996535813">Iniciou sessão com uma conta profissional. Pretende criar um novo perfil do Chromium para trabalho para manter os seus dados separados?</translation> <translation id="5224391634244552924">Não existem palavras-passe guardadas. O Chromium consegue verificar as suas palavras-passe quando as guarda.</translation> <translation id="5277894862589591112">Para aplicar as alterações, reinicie o Chromium.</translation> <translation id="5358375970380395591">Está a iniciar sessão com uma conta gerida e a permitir que o gestor controle o seu perfil do Chromium. Os seus dados do Chromium, como aplicações, marcadores, histórico, palavras-passe e outras definições, ficarão associados definitivamente a <ph name="USER_NAME" />. Poderá eliminar estes dados através do Painel de Controlo das Contas Google, mas não poderá associá-los a outra conta. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ro.xtb b/chrome/app/resources/chromium_strings_ro.xtb index 31a90a2..987e04c 100644 --- a/chrome/app/resources/chromium_strings_ro.xtb +++ b/chrome/app/resources/chromium_strings_ro.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium este în modul fundal.</translation> <translation id="4987820182225656817">Invitații pot folosi Chromium fără a lăsa nicio urmă.</translation> <translation id="4994636714258228724">Adăugați-vă la Chromium</translation> -<translation id="5037694917996535813">Te-ai conectat cu un cont de serviciu. Vrei să creezi un profil Chromium pentru serviciu ca să păstrezi datele separat?</translation> <translation id="5224391634244552924">Nu există parole salvate. Chromium îți poate verifica parolele dacă le salvezi.</translation> <translation id="5277894862589591112">Pentru a aplica modificările, relansează Chromium</translation> <translation id="5358375970380395591">Vă conectați cu un cont gestionat și îi permiteți administratorului acestuia controlul asupra profilului dvs. Chromium. Datele Chromium, cum ar fi aplicațiile, marcajele, istoricul, parolele și alte setări vor fi asociate definitiv cu <ph name="USER_NAME" />. Veți putea să ștergeți aceste date prin intermediul Tabloului de bord pentru Conturi Google, însă nu veți putea să asociați aceste date cu alt cont. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ru.xtb b/chrome/app/resources/chromium_strings_ru.xtb index cd07fe5..0dc29561 100644 --- a/chrome/app/resources/chromium_strings_ru.xtb +++ b/chrome/app/resources/chromium_strings_ru.xtb
@@ -103,7 +103,6 @@ <translation id="4943838377383847465">Chromium работает в фоновом режиме</translation> <translation id="4987820182225656817">Используйте Chromium в гостевом режиме, если не хотите сохранять данные о посещенных сайтах.</translation> <translation id="4994636714258228724">Добавить пользователя Chromium</translation> -<translation id="5037694917996535813">Вы вошли в рабочий аккаунт. Хотите создать для него отдельный профиль Chromium?</translation> <translation id="5224391634244552924">Сохраненных паролей нет. Чтобы браузер Chromium мог проверять пароли, сохраните их.</translation> <translation id="5277894862589591112">Чтобы изменения вступили в силу, перезапустите Chromium.</translation> <translation id="5358375970380395591">Выполнив вход в управляемый аккаунт, вы предоставляете администратору право контролировать настройки вашего профиля Chromium. Ваши данные Chromium (приложения, закладки, история, пароли и другие настройки) будут временно связаны с аккаунтом <ph name="USER_NAME" />. Эти данные можно удалить в Личном кабинете Google, но их нельзя связать с другим аккаунтом. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_si.xtb b/chrome/app/resources/chromium_strings_si.xtb index 7b44209..ce28059 100644 --- a/chrome/app/resources/chromium_strings_si.xtb +++ b/chrome/app/resources/chromium_strings_si.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium පසුබිම් ප්රකාරය තුළ ඇත.</translation> <translation id="4987820182225656817">අමුත්තන්ට කිසිවක් තබා යෑමෙන් තොරව Chromium භාවිත කළ හැක.</translation> <translation id="4994636714258228724">ඔබව Chromium වෙත එක් කරන්න</translation> -<translation id="5037694917996535813">ඔබ කාර්යාල ගිණුමක් සමගින් පුරා ඇත. ඔබගේ දත්ත වෙන් වෙන්ව තබා ගැනීම සඳහා කාර්යාලය සඳහා නව Chromium පැතිකඩක් තැනීමට ඔබ කැමතිද?</translation> <translation id="5224391634244552924">සුරැකි මුරපද නැත. ඔබ ඔබේ මුරපද පරීක්ෂා කරන විට Chromium හට ඒවා පරීක්ෂා කළ හැක.</translation> <translation id="5277894862589591112">ඔබේ වෙනස්කම් යෙදීමට, Chromium නැවත දියත් කරන්න</translation> <translation id="5358375970380395591">ඔබ කළමනාකරණය කළ ගිණුමක් සමගින් පුරමින් සිටින අතර ඔබේ Chromium පැතිකඩට වැඩියෙන් එහි පරිපාලක පාලනය ලබා දෙමින් සිටී. යෙදුම්, පිටු සලකුණු, ඉතිහාසය, රහස්වචන, සහ අනෙකුත් සැකසුම් වැනි ඔබේ Chromium දත්ත ස්ථිරවම <ph name="USER_NAME" /> වෙත බැඳෙනු ඇත. Google ගිණුම් පසුරු පුවරුව හරහා මෙම දත්ත මැකීමට ඔබට හැකි වනු ඇත, නමුත් ඔබට මෙම දත්ත වෙනත් ගිණුමක් සමඟ සම්බන්ධ කළ නොහැකි වනු ඇත. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_sk.xtb b/chrome/app/resources/chromium_strings_sk.xtb index 147445e..79ab0d1a 100644 --- a/chrome/app/resources/chromium_strings_sk.xtb +++ b/chrome/app/resources/chromium_strings_sk.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium je v režime na pozadí.</translation> <translation id="4987820182225656817">Hostia môžu používať prehliadač Chromium bez toho, aby po sebe zanechali akékoľvek informácie.</translation> <translation id="4994636714258228724">Pridajte si účet do prehliadača Chromium</translation> -<translation id="5037694917996535813">Prihlásili ste sa pracovným účtom. Chcete v prehliadači Chromium vytvoriť nový pracovný profil a ponechať tak svoje údaje oddelené?</translation> <translation id="5224391634244552924">Žiadne uložené heslá. Chromium môže skontrolovať heslá, keď ich uložíte.</translation> <translation id="5277894862589591112">Ak chcete zmeny použiť, spustite Chromium znova</translation> <translation id="5358375970380395591">Prihlasujete sa pomocou spravovaného účtu a jeho správcovi dávate kontrolu nad vaším profilom Chromium. Vaše údaje prehliadača Chromium, ako sú aplikácie, záložky, história, heslá a iné nastavenia, sa natrvalo priradia k účtu <ph name="USER_NAME" />. Tieto údaje budete môcť odstrániť len pomocou panela Dashboard v Účtoch Google, ale nebudete ich môcť priradiť k inému účtu. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_sl.xtb b/chrome/app/resources/chromium_strings_sl.xtb index 44335af..ea893fa 100644 --- a/chrome/app/resources/chromium_strings_sl.xtb +++ b/chrome/app/resources/chromium_strings_sl.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium se izvaja v ozadju.</translation> <translation id="4987820182225656817">Gostje lahko uporabljajo Chromium, ne da bi za seboj pustili kar koli.</translation> <translation id="4994636714258228724">Dodajte se v Chromium</translation> -<translation id="5037694917996535813">Prijavili ste se s službenim računom. Ali želite v Chromiumu ustvariti nov službeni profil, da bodo podatki ločeni?</translation> <translation id="5224391634244552924">Ni shranjenih gesel. Chromium lahko preveri gesla, če jih shranite.</translation> <translation id="5277894862589591112">Če želite uporabiti spremembe, znova zaženite Chromium</translation> <translation id="5358375970380395591">Prijavljate se z upravljanim računom in s tem njegovemu skrbniku omogočate nadzor vašega profila v Chromiumu. Vaši podatki v Chromiumu, kot so aplikacije, zaznamki, zgodovina, gesla in druge nastavitve, bodo postali trajno povezani z uporabnikom <ph name="USER_NAME" />. Te podatke boste lahko izbrisali na nadzorni plošči za Google Račune, vendar jih ne boste mogli povezati z drugim računom. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_sq.xtb b/chrome/app/resources/chromium_strings_sq.xtb index d3502b26..2e02f8f 100644 --- a/chrome/app/resources/chromium_strings_sq.xtb +++ b/chrome/app/resources/chromium_strings_sq.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium është në modalitetin e sfondit.</translation> <translation id="4987820182225656817">Vizitorët mund të përdorin Chromium pa lënë asgjë prapa.</translation> <translation id="4994636714258228724">Shtoje veten te Chromium</translation> -<translation id="5037694917996535813">U identifikove me një llogari pune. Dëshiron të krijosh një "Profil të ri Chromium për biznesin" për t'i mbajtur të dhënat e tua të ndara?</translation> <translation id="5224391634244552924">Nuk ka asnjë fjalëkalim të ruajtur. Chromium mund t'i kontrollojë fjalëkalimet e tua kur ti i ruan ato.</translation> <translation id="5277894862589591112">Për të zbatuar ndryshimet, rinis Chromium</translation> <translation id="5358375970380395591">Po identifikohesh me një llogari të menaxhuar dhe po i jep administratorit të saj kontroll mbi profilin tënd të Chromium. Të dhënat e tua të Chromium, siç janë aplikacionet, faqeshënuesit, fjalëkalimet dhe cilësime të tjera do të lidhen në mënyrë të përhershme me <ph name="USER_NAME" />. Ti do të jesh në gjendje t'i fshish këto të dhëna përmes Panelit të llogarive të Google, por nuk do të jesh në gjendje t'i shoqërosh këto të dhëna me një llogari tjetër. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_sr-Latn.xtb b/chrome/app/resources/chromium_strings_sr-Latn.xtb index f8337e9..cd19d7f 100644 --- a/chrome/app/resources/chromium_strings_sr-Latn.xtb +++ b/chrome/app/resources/chromium_strings_sr-Latn.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium je u pozadinskom režimu.</translation> <translation id="4987820182225656817">Gosti mogu da koriste Chromium a da ne ostavljaju nikakve tragove.</translation> <translation id="4994636714258228724">Dodajte sebe u Chromium</translation> -<translation id="5037694917996535813">Prijavljeni ste pomoću poslovnog naloga. Da li želite da napravite nov Chromium poslovni profil da bi podaci ostali odvojeni?</translation> <translation id="5224391634244552924">Nema sačuvanih lozinki. Chromium može da proverava lozinke kada ih sačuvate.</translation> <translation id="5277894862589591112">Da biste primenili promene, ponovo pokrenite Chromium</translation> <translation id="5358375970380395591">Prijavljujete se pomoću naloga kojim se upravlja i dajete njegovom administratoru kontrolu nad Chromium profilom. Chromium podaci, kao što su aplikacije, obeleživači, istorija, lozinke i druga podešavanja, biće trajno povezani sa nalogom <ph name="USER_NAME" />. Moći ćete da izbrišete te podatke preko Kontrolne table Google naloga, ali nećete moći da ih povežete sa nekim drugim nalogom. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_sr.xtb b/chrome/app/resources/chromium_strings_sr.xtb index be1fc139..ae3ae7be 100644 --- a/chrome/app/resources/chromium_strings_sr.xtb +++ b/chrome/app/resources/chromium_strings_sr.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium је у позадинском режиму.</translation> <translation id="4987820182225656817">Гости могу да користе Chromium а да не остављају никакве трагове.</translation> <translation id="4994636714258228724">Додајте себе у Chromium</translation> -<translation id="5037694917996535813">Пријављени сте помоћу пословног налога. Да ли желите да направите нов Chromium пословни профил да би подаци остали одвојени?</translation> <translation id="5224391634244552924">Нема сачуваних лозинки. Chromium може да проверава лозинке када их сачувате.</translation> <translation id="5277894862589591112">Да бисте применили промене, поново покрените Chromium</translation> <translation id="5358375970380395591">Пријављујете се помоћу налога којим се управља и дајете његовом администратору контролу над Chromium профилом. Chromium подаци, као што су апликације, обележивачи, историја, лозинке и друга подешавања, биће трајно повезани са налогом <ph name="USER_NAME" />. Моћи ћете да избришете те податке преко Контролне табле Google налога, али нећете моћи да их повежете са неким другим налогом. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_sv.xtb b/chrome/app/resources/chromium_strings_sv.xtb index 0816a700..a944cd7 100644 --- a/chrome/app/resources/chromium_strings_sv.xtb +++ b/chrome/app/resources/chromium_strings_sv.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium körs i bakgrundsläge.</translation> <translation id="4987820182225656817">Gäster kan använda Chromium utan att lämna spår efter sig.</translation> <translation id="4994636714258228724">Lägg till dig själv i Chromium</translation> -<translation id="5037694917996535813">Du har loggat in med ett jobbkonto. Vill du skapa en ny Chromium-profil för jobbet och hålla uppgifterna åtskilda?</translation> <translation id="5224391634244552924">Inga sparade lösenord. Chromium kan bara kontrollera dina lösenord om du sparar dem.</translation> <translation id="5277894862589591112">Ändringarna tillämpas när du startar om Chromium</translation> <translation id="5358375970380395591">Du loggar in med ett hanterat konto och ger dess administratör kontroll över din Chromium-profil. Dina uppgifter i Chromium, t.ex. dina appar, bokmärken, din historik, ditt lösenord och andra inställningar, kopplas då permanent till <ph name="USER_NAME" />. Du kommer att kunna ta bort dessa uppgifter via instrumentpanelen i Google Konton, men du kommer inte att kunna koppla dem till något annat konto. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_sw.xtb b/chrome/app/resources/chromium_strings_sw.xtb index 467bf09..6fa33553 100644 --- a/chrome/app/resources/chromium_strings_sw.xtb +++ b/chrome/app/resources/chromium_strings_sw.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium iko katika hali ya chini chini.</translation> <translation id="4987820182225656817">Walioalikwa wanaweza kutumia Chromium bila kuacha kitu chochote nyuma.</translation> <translation id="4994636714258228724">Jiongeze kwenye Chrome</translation> -<translation id="5037694917996535813">Umeingia ukitumia akaunti ya kazini. Ungependa kufungua Wasifu mpya wa Kikazi kwenye Chromium ili utenganishe data yako?</translation> <translation id="5224391634244552924">Hakuna manenosiri yaliyohifadhiwa. Chromium inaweza kukagua manenosiri yako ukiyahifadhi.</translation> <translation id="5277894862589591112">Ili utumie mabadiliko uliyofanya, fungua Chromium upya</translation> <translation id="5358375970380395591">Unaingia katika akaunti inayodhibitiwa na kumpa msimamizi wa akaunti hiyo udhibiti wa wasifu wako kwenye Chromium. Data yako ya Chromium, kama vile programu zako, alamisho, historia, manenosiri, na mipangilio miingine itahusishwa na <ph name="USER_NAME" /> kabisa. Utaweza kufuta data hii kupitia Dashibodi ya Akaunti za Google, lakini hutaweza kuunganisha data hii na akaunti nyingine. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ta.xtb b/chrome/app/resources/chromium_strings_ta.xtb index 2472091..9ff78552 100644 --- a/chrome/app/resources/chromium_strings_ta.xtb +++ b/chrome/app/resources/chromium_strings_ta.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium பின்புல பயன்முறையில் இயங்குகிறது.</translation> <translation id="4987820182225656817">எதையும் விட்டுசெல்லாமல் கெஸ்ட் பயனர்கள் Chromium ஐப் பயன்படுத்தலாம்.</translation> <translation id="4994636714258228724">உங்களை Chromium இல் சேர்க்கவும்</translation> -<translation id="5037694917996535813">பணிக் கணக்கின் மூலம் உள்நுழைந்துள்ளீர்கள். உங்கள் தரவைத் தனிப்பட்டதாக வைத்திருக்கும் வகையில் பணிக்கான புதிய Chromium சுயவிவரத்தை உருவாக்க விரும்புகிறீர்களா?</translation> <translation id="5224391634244552924">சேமித்த கடவுச்சொற்கள் எதுவுமில்லை. நீங்கள் அவற்றைச் சேமிக்கும்போது Chromium உலாவியால் உங்கள் கடவுச்சொற்களைச் சரிபார்க்க முடியும்.</translation> <translation id="5277894862589591112">உங்கள் மாற்றங்களைச் செயல்படுத்த, Chromiumமை மீண்டும் தொடங்கவும்</translation> <translation id="5358375970380395591">நீங்கள் நிர்வகிக்கப்படும் கணக்கு மூலம் உள்நுழைகிறீர்கள், மேலும் அதன் நிர்வாகிக்கு உங்கள் Chromium சுயவிவரத்தின் கட்டுப்பாட்டை வழங்குகிறீர்கள். உங்கள் ஆப்ஸ், புக்மார்க்குகள், வரலாறு, கடவுச்சொற்கள் போன்ற உங்கள் Chromium தரவு மற்றும் பிற அமைப்புகள் நிரந்தரமாக <ph name="USER_NAME" /> உடன் இணைக்கப்படும். இந்தத் தரவை Google கணக்குகளின் டாஷ்போர்டு வழியாக நீக்க முடியும், ஆனால் இந்தத் தரவை வேறொரு கணக்குடன் தொடர்புபடுத்த முடியாது. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_te.xtb b/chrome/app/resources/chromium_strings_te.xtb index 260e0532..63d5dca 100644 --- a/chrome/app/resources/chromium_strings_te.xtb +++ b/chrome/app/resources/chromium_strings_te.xtb
@@ -103,7 +103,6 @@ <translation id="4943838377383847465">Chromium నేపథ్య మోడ్లో ఉంది.</translation> <translation id="4987820182225656817">అతిథులు ఎటువంటి చరిత్రను వదలకుండానే Chromiumను ఉపయోగించవచ్చు.</translation> <translation id="4994636714258228724">Chromiumకు మిమ్మల్ని జోడించుకోండి</translation> -<translation id="5037694917996535813">మీ కార్యాలయ ఖాతాతో సైన్ ఇన్ చేశారు. కార్యాలయం కోసం మీ డేటాను విడిగా ఉంచడానికి కొత్త Chromium ప్రొఫైల్ను సృష్టించాలనుకొంటున్నారా?</translation> <translation id="5224391634244552924">సేవ్ చేసిన పాస్వర్డ్లు లేవు. మీరు మీ పాస్వర్డ్లను సేవ్ చేసినప్పుడు Chromium వాటిని చెక్ చేయగలదు.</translation> <translation id="5277894862589591112">మీ మార్పులను వర్తింపజేయడానికి, Chromiumని పునఃప్రారంభించండి</translation> <translation id="5358375970380395591">మీరు నిర్వహించబడే ఖాతాతో సైన్ ఇన్ చేస్తున్నారు. దీని నిర్వాహకునికి మీ Chromium ప్రొఫైల్పై నియంత్రణను అందిస్తున్నారు. మీ యాప్లు, బుక్మార్క్లు, చరిత్ర, పాస్వర్డ్లు, ఇతర సెట్టింగ్ల వంటి మీ Chromium డేటా శాశ్వతంగా <ph name="USER_NAME" />కు అనుబంధించబడుతుంది. మీరు Google ఖాతాల డాష్బోర్డ్ ద్వారా ఈ డేటాను తొలగించవచ్చు. కానీ ఈ డేటాను మరో ఖాతాతో అనుబంధించలేరు. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_th.xtb b/chrome/app/resources/chromium_strings_th.xtb index 44a40630..2212198 100644 --- a/chrome/app/resources/chromium_strings_th.xtb +++ b/chrome/app/resources/chromium_strings_th.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium กำลังอยู่ในโหมดทำงานในพื้นหลัง</translation> <translation id="4987820182225656817">ผู้เยี่ยมชมสามารถใช้ Chromium โดยไม่ทิ้งร่องรอยไว้</translation> <translation id="4994636714258228724">เพิ่มตัวคุณเองใน Chromium</translation> -<translation id="5037694917996535813">คุณลงชื่อเข้าใช้ด้วยบัญชีงาน ต้องการสร้างโปรไฟล์ Chromium สำหรับงานรายการใหม่เพื่อเก็บข้อมูลแยกไว้ต่างหากไหม</translation> <translation id="5224391634244552924">ไม่มีรหัสผ่านที่บันทึกไว้ Chromium จะตรวจสอบรหัสผ่านได้เมื่อคุณบันทึกรหัสผ่านไว้</translation> <translation id="5277894862589591112">เปิด Chromium ขึ้นมาใหม่เพื่อให้การเปลี่ยนแปลงมีผล</translation> <translation id="5358375970380395591">คุณกำลังลงชื่อเข้าใช้ด้วยบัญชีที่จัดการ และให้การควบคุมระดับผู้ดูแลระบบของบัญชีดังกล่าวเหนือโปรไฟล์ Chromium ของคุณ ข้อมูล Chromium เช่น แอป บุ๊กมาร์ก ประวัติการเข้าชม รหัสผ่าน และการตั้งค่าอื่นๆ จะเชื่อมโยงอย่างถาวรกับ <ph name="USER_NAME" /> คุณจะสามารถลบข้อมูลนี้ผ่านทางแผงควบคุมบัญชี Google แต่คุณจะไม่สามารถเชื่อมโยงข้อมูลนี้กับบัญชีอื่น <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_tr.xtb b/chrome/app/resources/chromium_strings_tr.xtb index 42fd000..dfb0d93 100644 --- a/chrome/app/resources/chromium_strings_tr.xtb +++ b/chrome/app/resources/chromium_strings_tr.xtb
@@ -103,7 +103,6 @@ <translation id="4943838377383847465">Chromium arka plan modunda.</translation> <translation id="4987820182225656817">Misafirler Chromium'u geride hiçbir şey bırakmadan kullanabilir.</translation> <translation id="4994636714258228724">Kendinizi Chromium'a ekleyin</translation> -<translation id="5037694917996535813">İş hesabıyla oturum açtınız. Verilerinizi ayrı tutmak için İş amaçlı yeni bir Chromium Profili oluşturmak ister misiniz?</translation> <translation id="5224391634244552924">Kaydedilen şifre yok. Chromium, kaydetmeniz halinde şifrelerinizi kontrol edebilir.</translation> <translation id="5277894862589591112">Yaptığınız değişiklikleri uygulamak için Chromium'u yeniden başlatın</translation> <translation id="5358375970380395591">Yönetilen bir hesapla oturum açıyor ve hesabın yöneticisine Chromium profilinizi denetleme izni veriyorsunuz. Uygulamalarınız, yer işaretleriniz, geçmişiniz, şifreleriniz ve diğer ayarlarınız gibi Chromium verileriniz kalıcı olarak <ph name="USER_NAME" /> ile bağlantılandırılacaktır. Google Hesapları Hesap Özeti'ni kullanarak bu verileri silebilecek, ancak bu verileri başka bir hesapla ilişkilendiremeyeceksiniz. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_uk.xtb b/chrome/app/resources/chromium_strings_uk.xtb index bc1fbfb..ef4a93c 100644 --- a/chrome/app/resources/chromium_strings_uk.xtb +++ b/chrome/app/resources/chromium_strings_uk.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium у фоновому режимі.</translation> <translation id="4987820182225656817">Гості можуть анонімно користуватися Chromium.</translation> <translation id="4994636714258228724">Додати себе в Chromium</translation> -<translation id="5037694917996535813">Ви ввійшли в корпоративний обліковий запис. Створити новий робочий профіль Chromium, щоб зберігати дані окремо?</translation> <translation id="5224391634244552924">Немає збережених паролів. Chromium зможе перевірити ваші паролі, коли ви їх збережете.</translation> <translation id="5277894862589591112">Щоб застосувати зміни, перезапустіть Chromium</translation> <translation id="5358375970380395591">Ви входите, використовуючи дані облікового запису, яким керує адміністратор. Адміністратор може контролювати ваш профіль Chromium. Ваші дані Chromium, як-от програми, закладки, історія, паролі й інші налаштування, буде назавжди пов’язано з обліковим записом <ph name="USER_NAME" />. Ці дані можна видалити на інформаційній панелі Облікових записів Google, але ви не зможете пов’язати їх з іншим обліковим записом. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_ur.xtb b/chrome/app/resources/chromium_strings_ur.xtb index 6860766..82a80a4 100644 --- a/chrome/app/resources/chromium_strings_ur.xtb +++ b/chrome/app/resources/chromium_strings_ur.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium پس منظر وضع میں ہے۔</translation> <translation id="4987820182225656817">مہمان کسی چیز کو پیچھے چھوڑے بغیر Chromium کو استعمال کر سکتے ہیں۔</translation> <translation id="4994636714258228724">خود کو Chromium میں شامل کریں</translation> -<translation id="5037694917996535813">آپ نے دفتری اکاؤنٹ کے ساتھ سائن ان کیا ہے۔ کیا آپ اپنے ڈیٹا کو الگ رکھنے کی خاطر دفتر کے لئے ایک نئی Chromium پروفائل تخلیق کرنا چاہیں گے؟</translation> <translation id="5224391634244552924">کوئی محفوظ کردہ پاس ورڈ نہیں۔ جب آپ پاس ورڈز کو محفوظ کرتے ہیں تو Chromium انہیں چیک کر سکتا ہے۔</translation> <translation id="5277894862589591112">اپنی تبدیلیوں کو لاگو کرنے کیلئے، Chromium کو دوبارہ شروع کریں</translation> <translation id="5358375970380395591">آپ زیر انتظام اکاؤنٹ سے سائن ان کر رہے ہیں اور اس کے منتظم کو اپنے Chromium پروفائل پر کنٹرول دے رہے ہیں. آپ کا Chromium کا ڈیٹا، جیسے آپ کی ایپس، بُک مارکس، سرگزشت، پاس ورڈز اور دیگر ترتیبات <ph name="USER_NAME" /> سے مستقل طور پر مربوط ہو جائیں گی۔ آپ Google اکاؤنٹس ڈیش بورڈ کے ذریعہ یا ڈیٹا حذف کر سکیں گے لیکن آپ اس ڈیٹا کو دوسرے اکاؤنٹ کے ساتھ وابستہ نہیں کر سکیں گے۔ <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_uz.xtb b/chrome/app/resources/chromium_strings_uz.xtb index 5d87ec6..37cfd1ee 100644 --- a/chrome/app/resources/chromium_strings_uz.xtb +++ b/chrome/app/resources/chromium_strings_uz.xtb
@@ -103,7 +103,6 @@ <translation id="4943838377383847465">Chromium orqa fon rejimida ishlamoqda.</translation> <translation id="4987820182225656817">Agar tashrif buyurgan saytlaringiz haqidagi ma’lumotlar saqlanmasligini xohlasangiz, Chromium mehmon rejimidan foydalaning.</translation> <translation id="4994636714258228724">Chromium foydalanuvchini qo‘shish</translation> -<translation id="5037694917996535813">Ishchi hisobingiz bilan kirgansiz. Maʼlumotlaringizni alohida saqlash uchun ish uchun yangi Chromium profilini yaratishni istaysizmi?</translation> <translation id="5224391634244552924">Hech qanday parol saqlanmagan. Chromium faqat saqlangan parollaringizni tekshira oladi.</translation> <translation id="5277894862589591112">O‘zgarishlarni tatbi qilish uchun Chromium qayta ishga tushirilishi zarur</translation> <translation id="5358375970380395591">Siz boshqaruvdagi hisobga kiryapsiz va uning administratoriga Chromium profilingizni boshqarishga ruxsat beryapsiz. Ilovalar, xatcho‘plar, brauzer tarixi, parollar va boshqa sozlamalar kabi barcha Chromium ma’lumotlaringiz <ph name="USER_NAME" /> hisobiga biriktiriladi. Siz bu ma’lumotlarni Google hisoblar shaxsiy kabinetidan o‘chirishingiz mumkin, lekin bu ma’lumotlarni boshqa hisob bilan bog‘lay olmaysiz. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_vi.xtb b/chrome/app/resources/chromium_strings_vi.xtb index 28dc379..4144e0f 100644 --- a/chrome/app/resources/chromium_strings_vi.xtb +++ b/chrome/app/resources/chromium_strings_vi.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium đang chạy trong nền.</translation> <translation id="4987820182225656817">Khách có thể sử dụng Chromium mà không phải thoát khỏi bất cứ nội dung nào.</translation> <translation id="4994636714258228724">Thêm chính bạn vào Chromium</translation> -<translation id="5037694917996535813">Bạn đang đăng nhập bằng tài khoản công việc. Bạn có muốn tạo Hồ sơ Chromium mới dành cho Công việc để lưu giữ dữ liệu riêng biệt không?</translation> <translation id="5224391634244552924">Bạn chưa lưu mật khẩu nào. Chromium có thể kiểm tra các mật khẩu của bạn khi bạn lưu các mật khẩu đó.</translation> <translation id="5277894862589591112">Để áp dụng các mục thay đổi của bạn, hãy chạy lại Chromium</translation> <translation id="5358375970380395591">Bạn đang đăng nhập bằng tài khoản được quản lý và cấp cho quản trị viên của tài khoản quyền kiểm soát cấu hình Chromium của bạn. Dữ liệu Chromium của bạn, chẳng hạn như ứng dụng, dấu trang, lịch sử, mật khẩu và các cài đặt khác sẽ vĩnh viễn được liên kết với <ph name="USER_NAME" />. Bạn có thể xóa dữ liệu này thông qua Trang tổng quan của tài khoản Google nhưng không thể liên kết dữ liệu này với tài khoản khác. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_zh-CN.xtb b/chrome/app/resources/chromium_strings_zh-CN.xtb index 8ba9cfe..f6727a5 100644 --- a/chrome/app/resources/chromium_strings_zh-CN.xtb +++ b/chrome/app/resources/chromium_strings_zh-CN.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium处于后台运行模式。</translation> <translation id="4987820182225656817">访客使用Chromium不会留下任何痕迹。</translation> <translation id="4994636714258228724">将您自己添加到Chromium</translation> -<translation id="5037694917996535813">您已使用工作帐号登录。想创建一份新的 Chromium 工作资料来单独保存您的数据吗?</translation> <translation id="5224391634244552924">尚未保存任何密码。您需要先保存密码才能使用 Chromium 的密码检查功能。</translation> <translation id="5277894862589591112">要想应用您的更改,请重新启动 Chromium</translation> <translation id="5358375970380395591">您目前登录的帐号是一个托管帐号,该帐号的管理员将能够控制您的 Chromium 个人资料。您的 Chromium 数据(例如您的应用、书签、历史记录、密码和其他设置)将永远与 <ph name="USER_NAME" /> 相关联。您可以通过 Google 帐号信息中心删除这些数据,但无法将这些数据与其他帐号相关联。<ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_zh-HK.xtb b/chrome/app/resources/chromium_strings_zh-HK.xtb index 79dfd06..cf397c3 100644 --- a/chrome/app/resources/chromium_strings_zh-HK.xtb +++ b/chrome/app/resources/chromium_strings_zh-HK.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">Chromium 正在背景模式中執行。</translation> <translation id="4987820182225656817">以訪客身分使用 Chromium 不會留下任何記錄。</translation> <translation id="4994636714258228724">新增為 Chromium 使用者</translation> -<translation id="5037694917996535813">您已使用公司帳戶登入。要建立新的公司 Chromium 設定檔以分開保留資料嗎?</translation> <translation id="5224391634244552924">沒有已儲存的密碼。儲存密碼時,Chromium 可檢查您的密碼。</translation> <translation id="5277894862589591112">如要套用變更,請重新啟動 Chromium</translation> <translation id="5358375970380395591">您已登入受管理的帳戶,並將管理控制權授予您的 Chromium 設定檔。您的 Chromium 數據 (例如應用程式、書籤、記錄、密碼和其他設定) 均將永久與 <ph name="USER_NAME" /> 建立關聯。您可以透過 Google 帳戶資訊主頁刪除這些數據,但您無法將這些數據與其他帳戶建立關聯。<ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_zh-TW.xtb b/chrome/app/resources/chromium_strings_zh-TW.xtb index 7d00e99..551fbc5 100644 --- a/chrome/app/resources/chromium_strings_zh-TW.xtb +++ b/chrome/app/resources/chromium_strings_zh-TW.xtb
@@ -105,7 +105,6 @@ <translation id="4943838377383847465">Chromium 正在背景模式中執行。</translation> <translation id="4987820182225656817">以訪客身分使用 Chromium 不會留下任何記錄。</translation> <translation id="4994636714258228724">新增為 Chromium 使用者</translation> -<translation id="5037694917996535813">你已使用公司帳戶登入。要建立新的工作用 Chromium 設定檔以分開保留資料嗎?</translation> <translation id="5224391634244552924">未儲存任何密碼。你必須先儲存密碼,才能使用 Chromium 的密碼檢查功能。</translation> <translation id="5277894862589591112">如要套用變更,請重新啟動 Chromium</translation> <translation id="5358375970380395591">你已登入管理化環境下的帳戶,並將管理控制權授予你的 Chromium 設定檔。你的 Chromium 資料 (例如應用程式、書籤、記錄、密碼和其他設定) 均將永久與 <ph name="USER_NAME" /> 建立關聯。你可以透過 Google 帳戶資訊主頁刪除這些資料,但你無法將這些資料與其他帳戶建立關聯。<ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/chromium_strings_zu.xtb b/chrome/app/resources/chromium_strings_zu.xtb index b50ed39e..48bd729 100644 --- a/chrome/app/resources/chromium_strings_zu.xtb +++ b/chrome/app/resources/chromium_strings_zu.xtb
@@ -107,7 +107,6 @@ <translation id="4943838377383847465">I-Chromium kumodi yasemuva.</translation> <translation id="4987820182225656817">Izihambeli zingasebenzisa i-Chromium ngaphandle kokushiya noma yini ngemuva.</translation> <translation id="4994636714258228724">Zingeze ngokwakho ku-Chromium</translation> -<translation id="5037694917996535813">Ungene ngemvume nge-akhawunti yomsebenzi. Ingabe ungathanda ukudala Iphrofayela Yomsebenzi ye-Chromium entsha ukugcina idatha yakho yehlukile?</translation> <translation id="5224391634244552924">Awekho amaphasiwedi alondoloziwe. I-Chromium ingahlola amaphasiwedi akho lapho uwalondoloza khona.</translation> <translation id="5277894862589591112">Ukuze ufake izinguquko zakho, qalisa kabusha i-Chromium</translation> <translation id="5358375970380395591">Ungena ngemvume nge-akhawunti ephethwe futhi unikeza umlawuli wayo ukulawula okungaphezulu kwephrofayela yakho ye-Chromium. Idatha yakho ye-Chromium, efana nezinhlelo zakho zokusebenza, amabhukhimakhi, umlando, amaphasiwedi, nezinye izilungiselelo zizoboshezelwa unaphakade ku-<ph name="USER_NAME" />. Uzokwazi ukususa le datha nge-Ideshibhodi yama-Akhawunti we-Google, kodwa ngeke uze ukwazi ukuhlobanisa le datha nenye i-akhawunti. <ph name="LEARN_MORE" /></translation>
diff --git a/chrome/app/resources/generated_resources_af.xtb b/chrome/app/resources/generated_resources_af.xtb index 8429e9f9..f578de4 100644 --- a/chrome/app/resources/generated_resources_af.xtb +++ b/chrome/app/resources/generated_resources_af.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Gee 'n fout aan</translation> <translation id="3752582316358263300">OK …</translation> <translation id="3752673729237782832">My toestelle</translation> -<translation id="3752757212511661046">Skep werkprofiel?</translation> <translation id="3753033997400164841">Berg een keer. Gebruik oral</translation> <translation id="3755411799582650620">Jou <ph name="PHONE_NAME" /> kan nou ook hierdie <ph name="DEVICE_TYPE" /> ontsluit.</translation> <translation id="375636864092143889">Werf gebruik tans jou mikrofoon</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Wys PIN-nommers</translation> <translation id="3873915545594852654">Iets was fout met ARC++.</translation> <translation id="3874164307099183178">Skakel Google Assistent aan</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" is gedeaktiveer omdat dit wanware bevat.</translation> <translation id="3879748587602334249">Aflaaibestuurder</translation> <translation id="3881478300875776315">Wys minder reëls</translation> <translation id="3882165008614329320">Bestaande video van kamera of lêer af</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Voeg vingerafdruk by</translation> <translation id="4562494484721939086">Geen diens nie</translation> <translation id="4563210852471260509">Aanvanklike invoertaal is Chinees</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Vinger 3</translation> <translation id="4565377596337484307">Versteek wagwoord</translation> <translation id="4565917129334815774">Berg stelselloglêers</translation>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb index ebca1312..6b2da61 100644 --- a/chrome/app/resources/generated_resources_am.xtb +++ b/chrome/app/resources/generated_resources_am.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">ስህተት ሪፖርት አድርግ</translation> <translation id="3752582316358263300">እሺ...</translation> <translation id="3752673729237782832">የእኔ መሣሪያዎች</translation> -<translation id="3752757212511661046">የሥራ መገለጫ ይፈጠር?</translation> <translation id="3753033997400164841">አንድ ጊዜ አከማች። በሁሉም ቦታ ተጠቀም</translation> <translation id="3755411799582650620">የእርስዎ <ph name="PHONE_NAME" /> አሁን ይህን <ph name="DEVICE_TYPE" /> ጭምር መክፈት ይችላል።</translation> <translation id="375636864092143889">ጣቢያ የእርስዎን ማይክሮፎን እየተጠቀመ ነው</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">ፒኖችን አሳይ</translation> <translation id="3873915545594852654">በARC++ ላይ ችግር አጋጥሟል።</translation> <translation id="3874164307099183178">Google ረዳትን ያብሩ</translation> -<translation id="387531380970557479">«<ph name="EXTENSION_NAME" />» ተንኮል-አዘል ዌር ስለያዘ ተሰናክሏል።</translation> <translation id="3879748587602334249">የማውረድ አቀናባሪ</translation> <translation id="3881478300875776315">ያነሱ መስመሮችን አሳይ</translation> <translation id="3882165008614329320">ከካሜራ ወይም ፋይል ላይ ያለ ቪዲዮ</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">የጣት አሻራን አክል</translation> <translation id="4562494484721939086">ምንም አገልግሎት የለም</translation> <translation id="4563210852471260509">የመጀመሪያው የግቤት ቋንቋ ቻይንኛ ነው</translation> -<translation id="4563404051166505887">1 ፎቶ</translation> <translation id="4563880231729913339">ጣት 3</translation> <translation id="4565377596337484307">የይለፍ ቃል ደብቅ</translation> <translation id="4565917129334815774">የስርዓት ምዝግቦችን ያከማቹ</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb index 1a84463..dc51d46 100644 --- a/chrome/app/resources/generated_resources_ar.xtb +++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">الإبلاغ عن خطأ</translation> <translation id="3752582316358263300">حسنًا...</translation> <translation id="3752673729237782832">أجهزتي</translation> -<translation id="3752757212511661046">إنشاء ملف شخصي للعمل</translation> <translation id="3753033997400164841">حفظ كلمة المرور مرة واحدة وإتاحتها على جميع الأجهزة</translation> <translation id="3755411799582650620">بإمكان هاتفك <ph name="PHONE_NAME" /> أن يلغي قفل جهاز<ph name="DEVICE_TYPE" /> أيضًا.</translation> <translation id="375636864092143889">يستخدم الموقع الإلكتروني الميكروفون.</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">إظهار أرقام التعريف الشخصية</translation> <translation id="3873915545594852654">حدثت مشكلة في "وقت تشغيل التطبيقات في Chrome (ARC++)".</translation> <translation id="3874164307099183178">تفعيل خدمة "مساعد Google"</translation> -<translation id="387531380970557479">تم إيقاف الإضافة "<ph name="EXTENSION_NAME" />" لأنها تحتوي على برامج ضارة.</translation> <translation id="3879748587602334249">تطبيق إدارة التنزيل</translation> <translation id="3881478300875776315">عرض أسطر أقل</translation> <translation id="3882165008614329320">الفيديو الحالي من الكاميرا أو الملف</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">إضافة بصمة إصبع</translation> <translation id="4562494484721939086">لا تتوفر أي خدمة.</translation> <translation id="4563210852471260509">لغة الإدخال الأولية هي الصينية</translation> -<translation id="4563404051166505887">صورة واحدة</translation> <translation id="4563880231729913339">إصبع 3</translation> <translation id="4565377596337484307">إخفاء كلمة المرور</translation> <translation id="4565917129334815774">تخزين سجلّات النظام</translation>
diff --git a/chrome/app/resources/generated_resources_as.xtb b/chrome/app/resources/generated_resources_as.xtb index e7e919ca..9c940ce 100644 --- a/chrome/app/resources/generated_resources_as.xtb +++ b/chrome/app/resources/generated_resources_as.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">এটা বাগৰ অভিযোগ দিয়ক</translation> <translation id="3752582316358263300">ঠিক আছে...</translation> <translation id="3752673729237782832">মোৰ ডিভাইচবোৰ</translation> -<translation id="3752757212511661046">কৰ্মস্থানৰ প্ৰ’ফাইল সৃষ্টি কৰিবনে?</translation> <translation id="3753033997400164841">এবাৰ ষ্ট’ৰ কৰক। সকলোতে ব্যৱহাৰ কৰক</translation> <translation id="3755411799582650620">আপোনাৰ <ph name="PHONE_NAME" />এ এতিয়া <ph name="DEVICE_TYPE" />ও আনলক কৰিব পাৰে।</translation> <translation id="375636864092143889">ছাইটটোৱে আপোনাৰ মাইক্ৰ’ফ’ম ব্যৱহাৰ কৰি আছে</translation> @@ -2382,7 +2381,6 @@ <translation id="3873423927483480833">পিনসমূহ দেখুৱাওক</translation> <translation id="3873915545594852654">ARC++ৰ ক্ষেত্ৰত এটা সমস্যাই দেখা দিছে।</translation> <translation id="3874164307099183178">Google Assistant অন কৰক</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />"ত মালৱেৰ থকাৰ বাবে এইটো অক্ষম কৰা হৈছে।</translation> <translation id="3879748587602334249">ডাউনল’ড মেনেজাৰ</translation> <translation id="3881478300875776315">শাৰী কমকৈ দেখুৱাওক</translation> <translation id="3882165008614329320">কেমেৰা অথবা ফাইলৰ পৰা ইতিমধ্যে থকা ভিডিঅ’</translation> @@ -2897,7 +2895,6 @@ <translation id="4562155214028662640">ফিংগাৰপ্ৰিণ্ট যোগ কৰক</translation> <translation id="4562494484721939086">কোনো সেৱা নাই</translation> <translation id="4563210852471260509">আৰম্ভণিৰ ইনপুটৰ ভাষা হৈছে চীনা</translation> -<translation id="4563404051166505887">১ খন ফট’</translation> <translation id="4563880231729913339">আঙুলি ৩</translation> <translation id="4565377596337484307">পাছৱৰ্ড লুকুৱাওক</translation> <translation id="4565917129334815774">ছিষ্টেম লগসমূহ ষ্ট’ৰ কৰক</translation>
diff --git a/chrome/app/resources/generated_resources_az.xtb b/chrome/app/resources/generated_resources_az.xtb index 9757782..e4e67cdd 100644 --- a/chrome/app/resources/generated_resources_az.xtb +++ b/chrome/app/resources/generated_resources_az.xtb
@@ -2259,7 +2259,6 @@ <translation id="3748706263662799310">Baqı şikayət edin</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Cihazlarım</translation> -<translation id="3752757212511661046">İş Profili yaradılsın?</translation> <translation id="3753033997400164841">Bir dəfə saxlayın. Hər yerdə istifadə edin</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> telefonunuz indi bu <ph name="DEVICE_TYPE" /> cihazında kilidi aça bilər.</translation> <translation id="375636864092143889">Sayt mikrofondan istifadə edir</translation> @@ -2380,7 +2379,6 @@ <translation id="3873423927483480833">PIN-ləri göstərin</translation> <translation id="3873915545594852654">ARC++ ilə bağlı problem yarandı.</translation> <translation id="3874164307099183178">Google Assistenti aktiv edin</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" zərərli tətbiq ehtiva etdiyinə görə deaktiv edilib.</translation> <translation id="3879748587602334249">Endirmə meneceri</translation> <translation id="3881478300875776315">Daha az sətir göstərin</translation> <translation id="3882165008614329320">Kamera və ya fayldan mövcud video</translation> @@ -2897,7 +2895,6 @@ <translation id="4562155214028662640">Barmaq İzi əlavə edin</translation> <translation id="4562494484721939086">Xidmət yoxdur</translation> <translation id="4563210852471260509">İlkin daxiletmə dili Çin dilidir</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Barmaq 3</translation> <translation id="4565377596337484307">Parolu gizlədin</translation> <translation id="4565917129334815774">Sistem loqlarını saxlayın</translation>
diff --git a/chrome/app/resources/generated_resources_be.xtb b/chrome/app/resources/generated_resources_be.xtb index c0e17b2a..c26723ab 100644 --- a/chrome/app/resources/generated_resources_be.xtb +++ b/chrome/app/resources/generated_resources_be.xtb
@@ -2258,7 +2258,6 @@ <translation id="3748706263662799310">Паведаміць пра памылку</translation> <translation id="3752582316358263300">ОК...</translation> <translation id="3752673729237782832">Мае прылады</translation> -<translation id="3752757212511661046">Стварыць працоўны профіль?</translation> <translation id="3753033997400164841">Захоўвайце адзін раз – выкарыстоўвайце ўсюды</translation> <translation id="3755411799582650620">Зараз прыладу <ph name="DEVICE_TYPE" /> можна разблакіраваць таксама з тэлефона <ph name="PHONE_NAME" />.</translation> <translation id="375636864092143889">Сайт выкарыстоўвае мікрафон</translation> @@ -2379,7 +2378,6 @@ <translation id="3873423927483480833">Паказваць PIN-коды</translation> <translation id="3873915545594852654">Узнікла праблема з ARC++.</translation> <translation id="3874164307099183178">Уключыць Памочніка Google</translation> -<translation id="387531380970557479">Пашырэнне "<ph name="EXTENSION_NAME" />" выключана, бо яно змяшчае шкоднае змесціва.</translation> <translation id="3879748587602334249">Менеджар спамповак</translation> <translation id="3881478300875776315">Паказваць менш радкоў</translation> <translation id="3882165008614329320">Існуючае відэа з камеры або файла</translation> @@ -2897,7 +2895,6 @@ <translation id="4562155214028662640">Дадаць адбітак пальца</translation> <translation id="4562494484721939086">Не абслугоўваецца</translation> <translation id="4563210852471260509">Пачатковая мова ўводу – кітайская</translation> -<translation id="4563404051166505887">1 фота</translation> <translation id="4563880231729913339">Палец 3</translation> <translation id="4565377596337484307">Схаваць пароль</translation> <translation id="4565917129334815774">Захаваць сістэмныя журналы</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb index 362510ea..4d147ff 100644 --- a/chrome/app/resources/generated_resources_bg.xtb +++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -2262,7 +2262,6 @@ <translation id="3748706263662799310">Подаване на сигнал за програмна грешка</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Моите устройства</translation> -<translation id="3752757212511661046">Да се създаде ли служебен потребителски профил?</translation> <translation id="3753033997400164841">Съхранете веднъж. Използвайте навсякъде</translation> <translation id="3755411799582650620">Телефонът ви <ph name="PHONE_NAME" /> вече може да отключва и този <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Сайтът използва микрофона ви</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">Показване на ПИН кодовете</translation> <translation id="3873915545594852654">Възникна проблем със СИПС++.</translation> <translation id="3874164307099183178">Включване на Google Асистент</translation> -<translation id="387531380970557479">Разширението <ph name="EXTENSION_NAME" /> е деактивирано, защото съдържа злонамерен софтуер.</translation> <translation id="3879748587602334249">Мениджър на изтеглянията</translation> <translation id="3881478300875776315">Показване на по-малко редове</translation> <translation id="3882165008614329320">Съществуващ видеоклип от камерата или от файл</translation> @@ -2903,7 +2901,6 @@ <translation id="4562155214028662640">Добавяне на отпечатък</translation> <translation id="4562494484721939086">Няма покритие</translation> <translation id="4563210852471260509">Първоначалният език за въвеждане да бъде китайски</translation> -<translation id="4563404051166505887">1 снимка</translation> <translation id="4563880231729913339">Пръст 3</translation> <translation id="4565377596337484307">Скриване на паролата</translation> <translation id="4565917129334815774">Съхраняване на системните регистрационни файлове</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb index 0bf988b..c2102ed 100644 --- a/chrome/app/resources/generated_resources_bn.xtb +++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">একটি বাগ রিপোর্ট করুন</translation> <translation id="3752582316358263300">ঠিক আছে...</translation> <translation id="3752673729237782832">আমার ডিভাইসগুলি</translation> -<translation id="3752757212511661046">অফিসের প্রোফাইল তৈরি করবেন?</translation> <translation id="3753033997400164841">একবার সেভ করুন। সব জায়গায় ব্যবহার করুন</translation> <translation id="3755411799582650620">এছাড়াও আপনার <ph name="PHONE_NAME" /> এখন এই <ph name="DEVICE_TYPE" /> আনলক করতে পারে৷</translation> <translation id="375636864092143889">সাইটটি আপনার মাইক্রোফোন ব্যবহার করছে</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">পিন দেখুন</translation> <translation id="3873915545594852654">ARC++ নিয়ে একটি সমস্যা হয়েছে।</translation> <translation id="3874164307099183178">Google Assistant অ্যাপ চালু করুন</translation> -<translation id="387531380970557479">ম্যালওয়্যার থাকার জন্য "<ph name="EXTENSION_NAME" />" বন্ধ করে দেওয়া হয়েছে।</translation> <translation id="3879748587602334249">ডাউনলোড ম্যানেজার</translation> <translation id="3881478300875776315">কম লাইন দেখুন</translation> <translation id="3882165008614329320">ক্যামেরা বা ফাইলে আগে থেকে থাকা ভিডিও</translation> @@ -2902,7 +2900,6 @@ <translation id="4562155214028662640">আঙ্গুলের ছাপ যোগ করুন</translation> <translation id="4562494484721939086">কোনও পরিষেবা নেই</translation> <translation id="4563210852471260509">প্রাথমিক ইনপুট ভাষা চীনা</translation> -<translation id="4563404051166505887">১টি ফটো</translation> <translation id="4563880231729913339">আঙ্গুল ৩</translation> <translation id="4565377596337484307">পাসওয়ার্ড লুকান</translation> <translation id="4565917129334815774">সিস্টেম লগ সেভ করুন</translation>
diff --git a/chrome/app/resources/generated_resources_bs.xtb b/chrome/app/resources/generated_resources_bs.xtb index 074c4f0..56511943 100644 --- a/chrome/app/resources/generated_resources_bs.xtb +++ b/chrome/app/resources/generated_resources_bs.xtb
@@ -2280,7 +2280,6 @@ <translation id="3748706263662799310">Prijava programske pogreške</translation> <translation id="3752582316358263300">Uredu...</translation> <translation id="3752673729237782832">Moji uređaji</translation> -<translation id="3752757212511661046">Kreirati radni profil?</translation> <translation id="3753033997400164841">Pohranite jednom. Koristite svugdje</translation> <translation id="3755411799582650620">Vaš telefon <ph name="PHONE_NAME" /> sada može otključati i ovaj uređaj <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Web lokacija koristi vaš mikrofon</translation> @@ -2402,7 +2401,6 @@ <translation id="3873423927483480833">Prikaži PIN-ove</translation> <translation id="3873915545594852654">Došlo je do problema koji se odnosi na ARC++.</translation> <translation id="3874164307099183178">Uključite Google Asistenta</translation> -<translation id="387531380970557479">Ekstenzija "<ph name="EXTENSION_NAME" />" je onemogućena jer sadrži zlonamjerni softver.</translation> <translation id="3879748587602334249">Upravitelj za preuzimanja</translation> <translation id="3881478300875776315">Prikaži manje redova</translation> <translation id="3882165008614329320">Postojeći videozapis s kamere ili fajla</translation> @@ -2923,7 +2921,6 @@ <translation id="4562155214028662640">Dodajte otisak prsta</translation> <translation id="4562494484721939086">Nema usluge</translation> <translation id="4563210852471260509">Početni jezik unosa je kineski</translation> -<translation id="4563404051166505887">1 fotografija</translation> <translation id="4563880231729913339">3. prst</translation> <translation id="4565377596337484307">Sakrij lozinku</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{<ph name="DOMAIN" /> traži da izradite sigurnosnu kopiju svojih podataka i danas vratite ovaj uređaj <ph name="DEVICE_TYPE" />.}one{<ph name="DOMAIN" /> traži da izradite sigurnosnu kopiju svojih podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> prije roka.}few{<ph name="DOMAIN" /> traži da izradite sigurnosnu kopiju svojih podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> prije roka.}other{<ph name="DOMAIN" /> traži da izradite sigurnosnu kopiju svojih podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> prije roka.}}</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb index 9114a67..b5483b1 100644 --- a/chrome/app/resources/generated_resources_ca.xtb +++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">Informa d'un error</translation> <translation id="3752582316358263300">D'acord...</translation> <translation id="3752673729237782832">Els meus dispositius</translation> -<translation id="3752757212511661046">Vols crear un perfil de treball?</translation> <translation id="3753033997400164841">Desa-la una vegada. Fes-la servir a tot arreu.</translation> <translation id="3755411799582650620">També podeu desbloquejar aquest <ph name="DEVICE_TYPE" /> mitjançant <ph name="PHONE_NAME" />.</translation> <translation id="375636864092143889">El lloc web està utilitzant el micròfon</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">Mostra els PIN</translation> <translation id="3873915545594852654">S'ha produït un problema amb ARC++.</translation> <translation id="3874164307099183178">Activa l'Assistent de Google</translation> -<translation id="387531380970557479"><ph name="EXTENSION_NAME" /> s'ha desactivat perquè conté programari maliciós.</translation> <translation id="3879748587602334249">Gestor de baixades</translation> <translation id="3881478300875776315">Mostra menys línies</translation> <translation id="3882165008614329320">Vídeo existent de la càmera o d'un fitxer</translation> @@ -2902,7 +2900,6 @@ <translation id="4562155214028662640">Afegeix una empremta digital</translation> <translation id="4562494484721939086">Sense servei</translation> <translation id="4563210852471260509">L'idioma inicial d'entrada és el xinès</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Dit 3</translation> <translation id="4565377596337484307">Oculta la contrasenya</translation> <translation id="4565917129334815774">Emmagatzema els registres del sistema</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb index 03d70ac..b3f1a20 100644 --- a/chrome/app/resources/generated_resources_cs.xtb +++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">Nahlásit chybu</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Má zařízení</translation> -<translation id="3752757212511661046">Vytvořit pracovní profil?</translation> <translation id="3753033997400164841">Uložte jednou. Používejte všude</translation> <translation id="3755411799582650620">Toto zařízení <ph name="DEVICE_TYPE" /> můžete odemknout také pomocí telefonu <ph name="PHONE_NAME" />.</translation> <translation id="375636864092143889">Web používá mikrofon</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">Zobrazit kódy PIN</translation> <translation id="3873915545594852654">Došlo k problému s ARC++.</translation> <translation id="3874164307099183178">Zapnout Asistenta Google</translation> -<translation id="387531380970557479">Rozšíření <ph name="EXTENSION_NAME" /> bylo zakázáno, protože obsahuje malware.</translation> <translation id="3879748587602334249">Správce stahování</translation> <translation id="3881478300875776315">Zobrazit méně řádků</translation> <translation id="3882165008614329320">Existující video z fotoaparátu nebo soubor</translation> @@ -2902,7 +2900,6 @@ <translation id="4562155214028662640">Přidat otisk prstu</translation> <translation id="4562494484721939086">Žádný signál</translation> <translation id="4563210852471260509">Výchozí jazyk zadávání je čínština</translation> -<translation id="4563404051166505887">1 fotka</translation> <translation id="4563880231729913339">Prst 3</translation> <translation id="4565377596337484307">Skrýt heslo</translation> <translation id="4565917129334815774">Ukládat systémové protokoly</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb index 3240ccbc..e7f25ec8 100644 --- a/chrome/app/resources/generated_resources_da.xtb +++ b/chrome/app/resources/generated_resources_da.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Rapporter en fejl</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Mine enheder</translation> -<translation id="3752757212511661046">Vil du oprette en arbejdsprofil?</translation> <translation id="3753033997400164841">Gem én gang. Brug overalt.</translation> <translation id="3755411799582650620">Din <ph name="PHONE_NAME" /> kan nu også låse denne <ph name="DEVICE_TYPE" /> op.</translation> <translation id="375636864092143889">Websitet anvender din mikrofon</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Vis pinkoder</translation> <translation id="3873915545594852654">Der opstod et problem med ARC++.</translation> <translation id="3874164307099183178">Slå Google Assistent til</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" er blevet deaktiveret, da den indeholder malware.</translation> <translation id="3879748587602334249">Downloadadministrator</translation> <translation id="3881478300875776315">Vis færre linjer</translation> <translation id="3882165008614329320">Eksisterende video fra kamera eller fil</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Tilføj fingeraftryk</translation> <translation id="4562494484721939086">Ingen dækning</translation> <translation id="4563210852471260509">Det oprindelige indtastningssprog er kinesisk</translation> -<translation id="4563404051166505887">1 billede</translation> <translation id="4563880231729913339">Finger 3</translation> <translation id="4565377596337484307">Skjul adgangskode</translation> <translation id="4565917129334815774">Gem systemlogs</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb index 04f7ebb0..105641cf 100644 --- a/chrome/app/resources/generated_resources_de.xtb +++ b/chrome/app/resources/generated_resources_de.xtb
@@ -2260,7 +2260,6 @@ <translation id="3748706263662799310">Programmfehler melden</translation> <translation id="3752582316358263300">Ok</translation> <translation id="3752673729237782832">Meine Geräte</translation> -<translation id="3752757212511661046">Arbeitsprofil erstellen?</translation> <translation id="3753033997400164841">Einmal speichern. Überall verwenden.</translation> <translation id="3755411799582650620">Sie können mit Ihrem <ph name="PHONE_NAME" /> jetzt Ihr <ph name="DEVICE_TYPE" /> entsperren.</translation> <translation id="375636864092143889">Die Website verwendet Ihr Mikrofon</translation> @@ -2381,7 +2380,6 @@ <translation id="3873423927483480833">PINs anzeigen</translation> <translation id="3873915545594852654">Ein Problem mit ARC++ ist aufgetreten.</translation> <translation id="3874164307099183178">Google Assistant einschalten</translation> -<translation id="387531380970557479">Die Erweiterung "<ph name="EXTENSION_NAME" />" wurde deaktiviert, weil sie Malware enthält</translation> <translation id="3879748587602334249">Download-Manager</translation> <translation id="3881478300875776315">Weniger Zeilen anzeigen</translation> <translation id="3882165008614329320">Vorhandenes Video von der Kamera oder als Datei</translation> @@ -2900,7 +2898,6 @@ <translation id="4562155214028662640">Fingerabdruck hinzufügen</translation> <translation id="4562494484721939086">Dienst nicht verfügbar</translation> <translation id="4563210852471260509">Anfängliche Eingabesprache ist Chinesisch.</translation> -<translation id="4563404051166505887">1 Foto</translation> <translation id="4563880231729913339">Finger 3</translation> <translation id="4565377596337484307">Passwort ausblenden</translation> <translation id="4565917129334815774">Systemprotokolle speichern</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb index 82f7fc41..2f04b3d5 100644 --- a/chrome/app/resources/generated_resources_el.xtb +++ b/chrome/app/resources/generated_resources_el.xtb
@@ -2280,7 +2280,6 @@ <translation id="3748706263662799310">Αναφορά σφάλματος</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Οι συσκευές μου</translation> -<translation id="3752757212511661046">Δημιουργία προφίλ εργασίας;</translation> <translation id="3753033997400164841">Αποθηκεύστε μία φορά. Χρησιμοποιήστε παντού.</translation> <translation id="3755411799582650620">Το τηλέφωνό σας <ph name="PHONE_NAME" /> μπορεί πλέον να απενεργοποιήσει και αυτή τη συσκευή <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Ο ιστότοπος χρησιμοποιεί το μικρόφωνό σας</translation> @@ -2402,7 +2401,6 @@ <translation id="3873423927483480833">Εμφάνιση PIN</translation> <translation id="3873915545594852654">Παρουσιάστηκε ένα πρόβλημα με το ARC++.</translation> <translation id="3874164307099183178">Ενεργοποίηση Βοηθού Google.</translation> -<translation id="387531380970557479">Το στοιχείο "<ph name="EXTENSION_NAME" />" απενεργοποιήθηκε επειδή περιέχει κακόβουλο πρόγραμμα.</translation> <translation id="3879748587602334249">Διαχείριση λήψεων</translation> <translation id="3881478300875776315">Εμφάνιση λιγότερων γραμμών</translation> <translation id="3882165008614329320">Υπάρχον βίντεο από την κάμερα ή από αρχείο</translation> @@ -2923,7 +2921,6 @@ <translation id="4562155214028662640">Προσθήκη δακτυλικού αποτυπώματος</translation> <translation id="4562494484721939086">Εκτός υπηρεσίας</translation> <translation id="4563210852471260509">Η αρχική γλώσσα εισόδου είναι τα Κινέζικα</translation> -<translation id="4563404051166505887">1 φωτογραφία</translation> <translation id="4563880231729913339">Δάκτυλο 3</translation> <translation id="4565377596337484307">Απόκρυψη κωδικού πρόσβασης</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{Ο τομέας <ph name="DOMAIN" /> απαιτεί τη δημιουργία αντιγράφων ασφαλείας για τα δεδομένα σας και την επιστροφή αυτής της συσκευής (<ph name="DEVICE_TYPE" />) σήμερα.}other{Ο τομέας <ph name="DOMAIN" /> απαιτεί τη δημιουργία αντιγράφων ασφαλείας για τα δεδομένα σας και την επιστροφή αυτής της συσκευής (<ph name="DEVICE_TYPE" />) πριν από τη λήξη της προθεσμίας.}}</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb index 9820623..273b693c 100644 --- a/chrome/app/resources/generated_resources_en-GB.xtb +++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -2280,7 +2280,6 @@ <translation id="3748706263662799310">Report a bug</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">My devices</translation> -<translation id="3752757212511661046">Create work profile?</translation> <translation id="3753033997400164841">Store once. Use everywhere</translation> <translation id="3755411799582650620">Your <ph name="PHONE_NAME" /> can now unlock this <ph name="DEVICE_TYPE" /> too.</translation> <translation id="375636864092143889">Site is using your microphone</translation> @@ -2402,7 +2401,6 @@ <translation id="3873423927483480833">Show PINs</translation> <translation id="3873915545594852654">A problem with ARC++ occurred.</translation> <translation id="3874164307099183178">Turn on Google Assistant</translation> -<translation id="387531380970557479">'<ph name="EXTENSION_NAME" />' has been disabled because it contains malware.</translation> <translation id="3879748587602334249">Download manager</translation> <translation id="3881478300875776315">Show fewer lines</translation> <translation id="3882165008614329320">Existing video from camera or file</translation> @@ -2923,7 +2921,6 @@ <translation id="4562155214028662640">Add Fingerprint</translation> <translation id="4562494484721939086">No service</translation> <translation id="4563210852471260509">Initial input language is Chinese</translation> -<translation id="4563404051166505887">1 photo</translation> <translation id="4563880231729913339">Finger 3</translation> <translation id="4565377596337484307">Hide password</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{<ph name="DOMAIN" /> requires you to back up your data and return this <ph name="DEVICE_TYPE" /> today.}other{<ph name="DOMAIN" /> requires you to back up your data and return this <ph name="DEVICE_TYPE" /> before the deadline.}}</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb index b6e1d4b..3830cb0 100644 --- a/chrome/app/resources/generated_resources_es-419.xtb +++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">Informar un error</translation> <translation id="3752582316358263300">Aceptar</translation> <translation id="3752673729237782832">Mis dispositivos</translation> -<translation id="3752757212511661046">¿Quieres crear un perfil de trabajo?</translation> <translation id="3753033997400164841">Almacena las contraseñas una vez y úsalas en todas partes</translation> <translation id="3755411799582650620">El <ph name="PHONE_NAME" /> ahora también puede desbloquear este dispositivo <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">El sitio está usando el micrófono</translation> @@ -2382,7 +2381,6 @@ <translation id="3873423927483480833">Muestra los PIN</translation> <translation id="3873915545594852654">Hubo un problema con ARC++.</translation> <translation id="3874164307099183178">Activar el Asistente de Google</translation> -<translation id="387531380970557479">Se inhabilitó la extensión "<ph name="EXTENSION_NAME" />" porque contiene software malicioso.</translation> <translation id="3879748587602334249">Administrador de descargas</translation> <translation id="3881478300875776315">Mostrar menos líneas</translation> <translation id="3882165008614329320">Video existente de la cámara o archivo</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">Agregar huella digital</translation> <translation id="4562494484721939086">Sin servicio</translation> <translation id="4563210852471260509">El idioma inicial de entrada es chino</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Dedo 3</translation> <translation id="4565377596337484307">Ocultar contraseña</translation> <translation id="4565917129334815774">Almacenar los registros del sistema</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb index 59d3c75..0f9152a 100644 --- a/chrome/app/resources/generated_resources_es.xtb +++ b/chrome/app/resources/generated_resources_es.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Notifica un error</translation> <translation id="3752582316358263300">Aceptar...</translation> <translation id="3752673729237782832">Mis dispositivos</translation> -<translation id="3752757212511661046">¿Crear perfil de trabajo?</translation> <translation id="3753033997400164841">Guárdalas una vez. Úsalas en todos sitios.</translation> <translation id="3755411799582650620">Tu <ph name="PHONE_NAME" /> ya puede desbloquear este <ph name="DEVICE_TYPE" /> también.</translation> <translation id="375636864092143889">El sitio web está usando tu micrófono</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Mostrar PINs</translation> <translation id="3873915545594852654">Ha habido un problema con ARC++.</translation> <translation id="3874164307099183178">Activar Asistente de Google</translation> -<translation id="387531380970557479">Se ha inhabilitado <ph name="EXTENSION_NAME" /> porque contiene software malicioso.</translation> <translation id="3879748587602334249">Administrador de descargas</translation> <translation id="3881478300875776315">Mostrar menos líneas</translation> <translation id="3882165008614329320">Vídeo de la cámara o un archivo</translation> @@ -2903,7 +2901,6 @@ <translation id="4562155214028662640">Añadir huella digital</translation> <translation id="4562494484721939086">Sin servicio</translation> <translation id="4563210852471260509">El lenguaje de entrada inicial es el chino.</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Dedo 3</translation> <translation id="4565377596337484307">Ocultar contraseña</translation> <translation id="4565917129334815774">Almacenar registros del sistema</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb index 103b1e0..ed78a1c 100644 --- a/chrome/app/resources/generated_resources_et.xtb +++ b/chrome/app/resources/generated_resources_et.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Teatage veast</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Minu seadmed</translation> -<translation id="3752757212511661046">Kas luua tööprofiil?</translation> <translation id="3753033997400164841">Salvestage üks kord. Kasutage kõikjal.</translation> <translation id="3755411799582650620">Teie telefon <ph name="PHONE_NAME" /> saab nüüd avada ka seadme <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Sait kasutab teie mikrofoni</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">PIN-koodide kuvamine</translation> <translation id="3873915545594852654">Ilmnes ARC++ probleem.</translation> <translation id="3874164307099183178">Google'i assistendi sisselülitamine</translation> -<translation id="387531380970557479">Laiendus „<ph name="EXTENSION_NAME" />” keelati, kuna see sisaldab pahavara.</translation> <translation id="3879748587602334249">Allalaadimishaldur</translation> <translation id="3881478300875776315">Kuva vähem ridu</translation> <translation id="3882165008614329320">Olemasolev video kaamerast või failist</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Lisa sõrmejälg</translation> <translation id="4562494484721939086">Levi puudub</translation> <translation id="4563210852471260509">Esialgne sisestuskeel on hiina keel</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">3. sõrm</translation> <translation id="4565377596337484307">Peida parool</translation> <translation id="4565917129334815774">Salvesta süsteemilogid</translation>
diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb index cff2915..778b15e 100644 --- a/chrome/app/resources/generated_resources_eu.xtb +++ b/chrome/app/resources/generated_resources_eu.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Eman akats baten berri</translation> <translation id="3752582316358263300">Ados…</translation> <translation id="3752673729237782832">Nire gailuak</translation> -<translation id="3752757212511661046">Laneko profila sortu nahi duzu?</translation> <translation id="3753033997400164841">Gorde behin. Erabili edonon.</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> telefonoak <ph name="DEVICE_TYPE" /> ere desblokea dezake.</translation> <translation id="375636864092143889">Webgunea zure mikrofonoa erabiltzen ari da</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Erakutsi PIN kodeak</translation> <translation id="3873915545594852654">Arazo bat izan da ARC++ eginbidearekin.</translation> <translation id="3874164307099183178">Aktibatu Google-ren Laguntzailea</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" desgaitu egin da malwarea daukalako.</translation> <translation id="3879748587602334249">Deskargen kudeatzailea</translation> <translation id="3881478300875776315">Erakutsi lerro gutxiago</translation> <translation id="3882165008614329320">Kamerako bideo bat edo bideo-fitxategi bat (lehendik duzuna)</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Gehitu hatz-marka</translation> <translation id="4562494484721939086">Zerbitzurik ez</translation> <translation id="4563210852471260509">Hasierako idazteko hizkuntza txinera da</translation> -<translation id="4563404051166505887">1 argazki</translation> <translation id="4563880231729913339">3. hatz-marka</translation> <translation id="4565377596337484307">Ezkutatu pasahitza</translation> <translation id="4565917129334815774">Gorde sistemaren erregistroak</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb index 9abc2785..09ac3e8 100644 --- a/chrome/app/resources/generated_resources_fa.xtb +++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">گزارش یک اشکال</translation> <translation id="3752582316358263300">تأیید...</translation> <translation id="3752673729237782832">دستگاههای من</translation> -<translation id="3752757212511661046">نمایه کاری ایجاد شود؟</translation> <translation id="3753033997400164841">یکبار ذخیره کنید. همهجا استفاده کنید</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> شما اکنون میتواند قفل این <ph name="DEVICE_TYPE" /> را نیز باز کند.</translation> <translation id="375636864092143889">سایت درحال استفاده از میکروفون شما است</translation> @@ -2382,7 +2381,6 @@ <translation id="3873423927483480833">نمایش پینها</translation> <translation id="3873915545594852654">در رابطه با ++ARC مشکلی پیش آمد.</translation> <translation id="3874164307099183178">روشن کردن «دستیار Google»</translation> -<translation id="387531380970557479">«<ph name="EXTENSION_NAME" />» بهدلیل داشتن بدافزار غیرفعال شده است.</translation> <translation id="3879748587602334249">مدیریت بارگیری</translation> <translation id="3881478300875776315">نمایش خطوط کمتر</translation> <translation id="3882165008614329320">ویدیوی موجود از دوربین یا فایل</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">افزودن اثر انگشت</translation> <translation id="4562494484721939086">بدون سرویس</translation> <translation id="4563210852471260509">زبان ورودی اولیه چینی است</translation> -<translation id="4563404051166505887">۱ عکس</translation> <translation id="4563880231729913339">انگشت ۳</translation> <translation id="4565377596337484307">عدم نمایش گذرواژه</translation> <translation id="4565917129334815774">ذخیره گزارشهای سیستم</translation>
diff --git a/chrome/app/resources/generated_resources_fi.xtb b/chrome/app/resources/generated_resources_fi.xtb index 2f8938d4..119ee45b 100644 --- a/chrome/app/resources/generated_resources_fi.xtb +++ b/chrome/app/resources/generated_resources_fi.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Ilmoita virheestä</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Omat laitteet</translation> -<translation id="3752757212511661046">Luodaanko työprofiili?</translation> <translation id="3753033997400164841">Tallenna kerran. Käytä kaikkialla.</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> voi nyt avata myös tämän <ph name="DEVICE_TYPE" />-laitteen.</translation> <translation id="375636864092143889">Sivusto käyttää mikrofoniasi</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Näytä PIN-koodit</translation> <translation id="3873915545594852654">ARC++:n kanssa tapahtui ongelma.</translation> <translation id="3874164307099183178">Laita Google Assistant päälle</translation> -<translation id="387531380970557479"><ph name="EXTENSION_NAME" /> on poistettu käytöstä, koska se sisältää haittaohjelmia.</translation> <translation id="3879748587602334249">Latausten hallinta</translation> <translation id="3881478300875776315">Näytä vähemmän rivejä</translation> <translation id="3882165008614329320">Olemassa oleva video kamerasta tai tiedostosta</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">Lisää sormenjälki</translation> <translation id="4562494484721939086">Ei yhteyttä</translation> <translation id="4563210852471260509">Alkuperäinen syöttökieli on kiina</translation> -<translation id="4563404051166505887">1 kuva</translation> <translation id="4563880231729913339">Sormi 3</translation> <translation id="4565377596337484307">Piilota salasana</translation> <translation id="4565917129334815774">Tallenna järjestelmälokit</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb index 745d9e0..091b04c 100644 --- a/chrome/app/resources/generated_resources_fil.xtb +++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Mag-ulat ng bug</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Aking mga device</translation> -<translation id="3752757212511661046">Gumawa ng Profile sa Trabaho?</translation> <translation id="3753033997400164841">I-store nang isang beses. Gamitin kahit saan</translation> <translation id="3755411799582650620">Maaari na rin ngayong i-unlock ng iyong <ph name="PHONE_NAME" /> ang <ph name="DEVICE_TYPE" /> na ito.</translation> <translation id="375636864092143889">Ginagamit ng site ang iyong mikropono</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Ipakita ang Mga PIN</translation> <translation id="3873915545594852654">Nagkaproblema sa ARC++.</translation> <translation id="3874164307099183178">I-on ang Google Assistant</translation> -<translation id="387531380970557479">Na-disable ang "<ph name="EXTENSION_NAME" />" dahil may malware ito.</translation> <translation id="3879748587602334249">Download manager</translation> <translation id="3881478300875776315">Magpakita ng mas kaunting linya</translation> <translation id="3882165008614329320">Kasalukuyang video mula sa camera o file</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Magdagdag ng Fingerprint</translation> <translation id="4562494484721939086">Walang serbisyo</translation> <translation id="4563210852471260509">Ang paunang wika sa pag-input ay Chinese</translation> -<translation id="4563404051166505887">1 larawan</translation> <translation id="4563880231729913339">Daliri 3</translation> <translation id="4565377596337484307">Itago ang password</translation> <translation id="4565917129334815774">I-store ang mga log ng system</translation>
diff --git a/chrome/app/resources/generated_resources_fr-CA.xtb b/chrome/app/resources/generated_resources_fr-CA.xtb index 52a52e6f..fa73cf8 100644 --- a/chrome/app/resources/generated_resources_fr-CA.xtb +++ b/chrome/app/resources/generated_resources_fr-CA.xtb
@@ -2265,7 +2265,6 @@ <translation id="3748706263662799310">Signaler un bogue</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Mes appareils</translation> -<translation id="3752757212511661046">Créer un profil professionnel?</translation> <translation id="3753033997400164841">Stocker une fois. Utiliser partout</translation> <translation id="3755411799582650620">Votre téléphone <ph name="PHONE_NAME" /> peut désormais aussi déverrouiller ce <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Le site utilise votre microphone</translation> @@ -2386,7 +2385,6 @@ <translation id="3873423927483480833">Afficher les NIP</translation> <translation id="3873915545594852654">Un problème avec ARC++ s'est produit.</translation> <translation id="3874164307099183178">Activer l'Assistant Google</translation> -<translation id="387531380970557479">L'extension « <ph name="EXTENSION_NAME" /> » a été désactivée parce qu'elle contient des logiciels malveillants</translation> <translation id="3879748587602334249">Gestionnaire de téléchargement</translation> <translation id="3881478300875776315">Afficher moins de lignes</translation> <translation id="3882165008614329320">Vidéo existante de la caméra ou du fichier</translation> @@ -2905,7 +2903,6 @@ <translation id="4562155214028662640">Ajouter une empreinte digitale</translation> <translation id="4562494484721939086">Aucun service</translation> <translation id="4563210852471260509">Le chinois est la langue d'entrée initiale</translation> -<translation id="4563404051166505887">1 photo</translation> <translation id="4563880231729913339">Doigt 3</translation> <translation id="4565377596337484307">Masquer le mot de passe</translation> <translation id="4565917129334815774">Stocker les journaux système</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb index 5bc46d78..1eba9fc9 100644 --- a/chrome/app/resources/generated_resources_fr.xtb +++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Signaler un bug</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Mes appareils</translation> -<translation id="3752757212511661046">Créer un profil professionnel ?</translation> <translation id="3753033997400164841">Enregistrez-les une fois pour toutes. Utilisez-les partout</translation> <translation id="3755411799582650620">Votre <ph name="PHONE_NAME" /> peut désormais également déverrouiller ce <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Le site utilise votre micro</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Afficher les codes</translation> <translation id="3873915545594852654">Un problème est survenu avec ARC++.</translation> <translation id="3874164307099183178">Activer l'Assistant Google</translation> -<translation id="387531380970557479">L'extension "<ph name="EXTENSION_NAME" />" a été désactivée, car elle contient un logiciel malveillant.</translation> <translation id="3879748587602334249">Gestionnaire de téléchargement</translation> <translation id="3881478300875776315">Afficher moins de lignes</translation> <translation id="3882165008614329320">Vidéo existante filmée avec la caméra ou lue à partir d'un fichier</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Ajouter empreinte digitale</translation> <translation id="4562494484721939086">Aucun service</translation> <translation id="4563210852471260509">Le chinois est la langue de saisie initiale</translation> -<translation id="4563404051166505887">1 photo</translation> <translation id="4563880231729913339">Doigt 3</translation> <translation id="4565377596337484307">Masquer le mot de passe</translation> <translation id="4565917129334815774">Stocker les journaux système</translation>
diff --git a/chrome/app/resources/generated_resources_gl.xtb b/chrome/app/resources/generated_resources_gl.xtb index 44ff3c7..b9e35498 100644 --- a/chrome/app/resources/generated_resources_gl.xtb +++ b/chrome/app/resources/generated_resources_gl.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">Informar dun erro</translation> <translation id="3752582316358263300">Aceptar...</translation> <translation id="3752673729237782832">Os meus dispositivos</translation> -<translation id="3752757212511661046">Queres crear un perfil de traballo?</translation> <translation id="3753033997400164841">Garda os contrasinais unha vez e utilízaos en todas partes</translation> <translation id="3755411799582650620">Agora o teu dispositivo <ph name="PHONE_NAME" /> tamén pode desbloquear este dispositivo <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">O sitio está usando o teu micrófono</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">Mostrar PIN</translation> <translation id="3873915545594852654">Produciuse un problema con ARC++.</translation> <translation id="3874164307099183178">Activar Asistente de Google</translation> -<translation id="387531380970557479">Desactivouse "<ph name="EXTENSION_NAME" />" porque contén software malicioso.</translation> <translation id="3879748587602334249">Administrador de descargas</translation> <translation id="3881478300875776315">Mostrar menos liñas</translation> <translation id="3882165008614329320">Vídeo existente da cámara ou do ficheiro</translation> @@ -2903,7 +2901,6 @@ <translation id="4562155214028662640">Engadir impresión dixital</translation> <translation id="4562494484721939086">Sen servizo</translation> <translation id="4563210852471260509">O idioma inicial de introdución de texto é o chinés</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Dedo 3</translation> <translation id="4565377596337484307">Ocultar contrasinal</translation> <translation id="4565917129334815774">Almacenar rexistros do sistema</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb index 42a8400..b5a7f75 100644 --- a/chrome/app/resources/generated_resources_gu.xtb +++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -2260,7 +2260,6 @@ <translation id="3748706263662799310">બગની જાણ કરો</translation> <translation id="3752582316358263300">બરાબર, સમજાઇ ગયું...</translation> <translation id="3752673729237782832">મારા ઉપકરણો</translation> -<translation id="3752757212511661046">ઑફિસની પ્રોફાઇલ બનાવીએ?</translation> <translation id="3753033997400164841">એકવાર સ્ટોર કરો. ગમે ત્યાં ઉપયોગ કરો</translation> <translation id="3755411799582650620">તમારો <ph name="PHONE_NAME" /> હવે આ <ph name="DEVICE_TYPE" /> ને પણ અનલૉક કરી શકે છે.</translation> <translation id="375636864092143889">સાઇટ તમારા માઇક્રોફોનનો ઉપયોગ કરી રહી છે</translation> @@ -2381,7 +2380,6 @@ <translation id="3873423927483480833">પિન બતાવો</translation> <translation id="3873915545594852654">ARC++માં સમસ્યા આવી.</translation> <translation id="3874164307099183178">Google Assistant ચાલુ કરો</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />"ને બંધ કરવામાં આવ્યું છે કારણ કે તે માલવેર ધરાવે છે.</translation> <translation id="3879748587602334249">ડાઉનલોડ મેનેજર</translation> <translation id="3881478300875776315">ઓછી પંક્તિઓ બતાવો</translation> <translation id="3882165008614329320">કૅમેરા અથવા ફાઇલમાંથી અસ્તિત્વમાં છે તે વીડિયો</translation> @@ -2900,7 +2898,6 @@ <translation id="4562155214028662640">ફિંગરપ્રિન્ટ ઉમેરો</translation> <translation id="4562494484721939086">કોઈ સેવા નથી</translation> <translation id="4563210852471260509">પ્રારંભિક ઇનપુટ ભાષા ચીની છે</translation> -<translation id="4563404051166505887">1 ફોટો</translation> <translation id="4563880231729913339">આંગળી 3</translation> <translation id="4565377596337484307">પાસવર્ડ છુપાવો</translation> <translation id="4565917129334815774">સિસ્ટમ લૉગને સ્ટોર કરો</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb index 674d85b5..2f5b3bb 100644 --- a/chrome/app/resources/generated_resources_hi.xtb +++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">बग की रिपोर्ट करें</translation> <translation id="3752582316358263300">ठीक है...</translation> <translation id="3752673729237782832">मेरे डिवाइस</translation> -<translation id="3752757212511661046">क्या आप वर्क प्रोफ़ाइल बनाना चाहते हैं?</translation> <translation id="3753033997400164841">एक बार सेव करें. हर जगह इस्तेमाल करें</translation> <translation id="3755411799582650620">आपका <ph name="PHONE_NAME" /> अब इस <ph name="DEVICE_TYPE" /> को भी अनलॉक कर सकता है.</translation> <translation id="375636864092143889">साइट आपका माइक्रोफ़ोन इस्तेमाल कर रही है</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">पिन दिखाएं</translation> <translation id="3873915545594852654">एआरसी++ के साथ कोई समस्या हुई.</translation> <translation id="3874164307099183178">Google Assistant चालू करें</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" को बंद कर दिया गया है, क्योंकि इसमें मैलवेयर है.</translation> <translation id="3879748587602334249">डाउनलोड मैनेजर</translation> <translation id="3881478300875776315">कम लाइनें दिखाएं</translation> <translation id="3882165008614329320">कैमरा या फ़ाइल से मौजूदा वीडियो</translation> @@ -2903,7 +2901,6 @@ <translation id="4562155214028662640">फ़िंगरप्रिंट जोड़ें</translation> <translation id="4562494484721939086">कोई सेवा नहीं</translation> <translation id="4563210852471260509">आरंभिक इनपुट भाषा चीनी है</translation> -<translation id="4563404051166505887">1 फ़ोटो</translation> <translation id="4563880231729913339">उंगली तीन</translation> <translation id="4565377596337484307">पासवर्ड छिपाएं</translation> <translation id="4565917129334815774">सिस्टम लॉग सेव करें</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb index b65e035..a55d4ae2e 100644 --- a/chrome/app/resources/generated_resources_hr.xtb +++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -2280,7 +2280,6 @@ <translation id="3748706263662799310">Prijava programske pogreške</translation> <translation id="3752582316358263300">U redu...</translation> <translation id="3752673729237782832">Moji uređaji</translation> -<translation id="3752757212511661046">Izraditi poslovni profil?</translation> <translation id="3753033997400164841">Pohranite jedanput. Upotrebljavajte svugdje</translation> <translation id="3755411799582650620">Vaš <ph name="PHONE_NAME" /> sada može otključati i taj <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Web-lokacija upotrebljava vaš mikrofon</translation> @@ -2402,7 +2401,6 @@ <translation id="3873423927483480833">Prikaz PIN-ova</translation> <translation id="3873915545594852654">Pojavio se problem koji se odnosi na ARC++.</translation> <translation id="3874164307099183178">Uključivanje Google asistenta</translation> -<translation id="387531380970557479">Proširenje "<ph name="EXTENSION_NAME" />" je onemogućeno jer sadrži zlonamjerni softver.</translation> <translation id="3879748587602334249">Upravitelj preuzimanja</translation> <translation id="3881478300875776315">Prikaži manje redaka</translation> <translation id="3882165008614329320">Postojeći videozapis s kamere ili iz datoteke</translation> @@ -2923,7 +2921,6 @@ <translation id="4562155214028662640">Dodajte otisak prsta</translation> <translation id="4562494484721939086">Nema usluge</translation> <translation id="4563210852471260509">Početni jezik unosa je kineski</translation> -<translation id="4563404051166505887">1 fotografija</translation> <translation id="4563880231729913339">Treći prst</translation> <translation id="4565377596337484307">Sakrij zaporku</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{<ph name="DOMAIN" /> traži da izradite sigurnosnu kopiju svojih podataka i danas vratite ovaj uređaj <ph name="DEVICE_TYPE" />.}one{<ph name="DOMAIN" /> traži da izradite sigurnosnu kopiju svojih podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> prije roka.}few{<ph name="DOMAIN" /> traži da izradite sigurnosnu kopiju svojih podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> prije roka.}other{<ph name="DOMAIN" /> traži da izradite sigurnosnu kopiju svojih podataka i vratite ovaj uređaj <ph name="DEVICE_TYPE" /> prije roka.}}</translation>
diff --git a/chrome/app/resources/generated_resources_hu.xtb b/chrome/app/resources/generated_resources_hu.xtb index 07b8bf50..b8162bc 100644 --- a/chrome/app/resources/generated_resources_hu.xtb +++ b/chrome/app/resources/generated_resources_hu.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Programhiba bejelentése</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Saját eszközök</translation> -<translation id="3752757212511661046">Szeretne létrehozni munkaprofilt?</translation> <translation id="3753033997400164841">Elég egyszer menteni, utána bárhol használhatja</translation> <translation id="3755411799582650620">Az Ön <ph name="PHONE_NAME" /> eszköze most már a(z) <ph name="DEVICE_TYPE" /> lezárását is fel tudja oldani.</translation> <translation id="375636864092143889">A webhely használja a mikrofonját</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">PIN-kódok megjelenítése</translation> <translation id="3873915545594852654">ARC++-hiba történt.</translation> <translation id="3874164307099183178">A Google Segéd bekapcsolása</translation> -<translation id="387531380970557479">A(z) „<ph name="EXTENSION_NAME" />” bővítményt letiltottuk, mert rosszindulatú programot tartalmaz.</translation> <translation id="3879748587602334249">Letöltéskezelő</translation> <translation id="3881478300875776315">Kevesebb sor megjelenítése</translation> <translation id="3882165008614329320">Meglévő videó a fényképezőgépről vagy fájlból</translation> @@ -2903,7 +2901,6 @@ <translation id="4562155214028662640">Ujjlenyomat hozzáadása</translation> <translation id="4562494484721939086">Nincs szolgáltatás</translation> <translation id="4563210852471260509">Az alapértelmezett beviteli nyelv a kínai</translation> -<translation id="4563404051166505887">1 fotó</translation> <translation id="4563880231729913339">3. ujj</translation> <translation id="4565377596337484307">Jelszó elrejtése</translation> <translation id="4565917129334815774">Rendszernaplók eltárolása</translation>
diff --git a/chrome/app/resources/generated_resources_hy.xtb b/chrome/app/resources/generated_resources_hy.xtb index 342dc91..d701020 100644 --- a/chrome/app/resources/generated_resources_hy.xtb +++ b/chrome/app/resources/generated_resources_hy.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Հաղորդել վրիպակի մասին</translation> <translation id="3752582316358263300">Եղավ…</translation> <translation id="3752673729237782832">Իմ սարքերը</translation> -<translation id="3752757212511661046">Ստեղծե՞լ աշխատանքային պրոֆիլ</translation> <translation id="3753033997400164841">Պահեք մեկ անգամ և օգտագործեք ամենուրեք</translation> <translation id="3755411799582650620">Ձեր <ph name="PHONE_NAME" /> հեռախոսն այժմ կարող է ապակողպել նաև այս <ph name="DEVICE_TYPE" /> սարքը:</translation> <translation id="375636864092143889">Կայքն օգտագործում է ձեր խոսափողը</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Ցուցադրել PIN կոդերը</translation> <translation id="3873915545594852654">Չհաջողվեց գործարկել ARC++ը։</translation> <translation id="3874164307099183178">Միացնել Google Օգնականը</translation> -<translation id="387531380970557479">«<ph name="EXTENSION_NAME" />» ընդլայնումն անջատվել է, քանի որ վնասաբեր ծրագիր է պարունակում։</translation> <translation id="3879748587602334249">Ներբեռնման կառավարիչ</translation> <translation id="3881478300875776315">Ցուցադրել ավելի քիչ տողեր</translation> <translation id="3882165008614329320">Տեսանյութ տեսախցիկից կամ ֆայլից</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Ավելացնել մատնահետք</translation> <translation id="4562494484721939086">Ցանցը չի գտնվել</translation> <translation id="4563210852471260509">Ներածման նախնական լեզուն չինարենն է</translation> -<translation id="4563404051166505887">1 լուսանկար</translation> <translation id="4563880231729913339">Մատ 3</translation> <translation id="4565377596337484307">Թաքցնել գաղտնաբառը</translation> <translation id="4565917129334815774">Պահել համակարգի մատյանները</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb index 5a9eb69..9f061d6 100644 --- a/chrome/app/resources/generated_resources_id.xtb +++ b/chrome/app/resources/generated_resources_id.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Laporkan bug</translation> <translation id="3752582316358263300">Oke...</translation> <translation id="3752673729237782832">Perangkat saya</translation> -<translation id="3752757212511661046">Buat Profil Kerja?</translation> <translation id="3753033997400164841">Simpan sekali. Gunakan di mana saja</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> Anda sekarang dapat membuka kunci <ph name="DEVICE_TYPE" /> ini juga.</translation> <translation id="375636864092143889">Situs sedang menggunakan mikrofon</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Tampilkan PIN</translation> <translation id="3873915545594852654">Terjadi masalah dengan ARC++.</translation> <translation id="3874164307099183178">Aktifkan Asisten Google</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" telah dinonaktifkan karena berisi malware.</translation> <translation id="3879748587602334249">Pengelola download</translation> <translation id="3881478300875776315">Tampilkan lebih sedikit baris</translation> <translation id="3882165008614329320">Video yang sudah ada dari kamera atau file</translation> @@ -2904,12 +2902,11 @@ <translation id="4562155214028662640">Tambahkan Sidik Jari</translation> <translation id="4562494484721939086">Tidak ada layanan</translation> <translation id="4563210852471260509">Bahasa masukan awal adalah Aksara China</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Jari 3</translation> <translation id="4565377596337484307">Sembunyikan sandi</translation> <translation id="4565917129334815774">Simpan log sistem</translation> <translation id="456717285308019641">Bahasa halaman yang akan diterjemahkan</translation> -<translation id="4567533462991917415">Anda dapat menambahkan lebih banyak pengguna kapan saja setelah penyiapan selesai. Setiap pengguna dapat mempersonalisasi akun mereka dan menjaga privasi datanya.</translation> +<translation id="4567533462991917415">Anda dapat menambahkan lebih banyak pengguna kapan saja setelah penyiapan selesai. Setiap pengguna dapat mempersonalisasi akunnya dan menjaga privasi datanya.</translation> <translation id="4567772783389002344">Tambahkan kata</translation> <translation id="4568025708905928793">Kunci keamanan diminta</translation> <translation id="4568213207643490790">Maaf, akun Google tidak diizinkan di perangkat ini.</translation> @@ -3627,7 +3624,7 @@ <translation id="5495597166260341369">Biarkan layar tetap menyala</translation> <translation id="5496587651328244253">Atur</translation> <translation id="5497251278400702716">File ini</translation> -<translation id="5498967291577176373">Tulis lebih cepat dengan saran yang ditampilkan sejajar untuk nama, alamat, atau nomor telepon Anda</translation> +<translation id="5498967291577176373">Tulis lebih cepat dengan saran yang ditampilkan pada baris yang sama untuk nama, alamat, atau nomor telepon Anda</translation> <translation id="5499313591153584299">File ini mungkin berbahaya untuk komputer Anda.</translation> <translation id="5499453227627332024">Upgrade tersedia untuk Container Linux Anda. Anda juga dapat mengupgrade nanti di aplikasi Setelan.</translation> <translation id="5500709606820808700">Pemeriksaan keselamatan berjalan hari ini</translation> @@ -6024,7 +6021,7 @@ <translation id="8481187309597259238">Konfirmasi Izin USB</translation> <translation id="8483248364096924578">Alamat IP</translation> <translation id="8487678622945914333">Perbesar</translation> -<translation id="8489156414266187072">Saran pengguna hanya ditampilkan di akun Anda</translation> +<translation id="8489156414266187072">Saran pribadi hanya ditampilkan di akun Anda</translation> <translation id="8490896350101740396">Aplikasi kios "<ph name="UPDATED_APPS" />" berikut telah diperbarui. Booting ulang perangkat untuk menyelesaikan proses pembaruan.</translation> <translation id="8493236660459102203">Mikrofon:</translation> <translation id="8496717697661868878">Jalankan Plugin Ini</translation>
diff --git a/chrome/app/resources/generated_resources_is.xtb b/chrome/app/resources/generated_resources_is.xtb index 7c975e2..20e829f 100644 --- a/chrome/app/resources/generated_resources_is.xtb +++ b/chrome/app/resources/generated_resources_is.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Tilkynna villu</translation> <translation id="3752582316358263300">Í lagi...</translation> <translation id="3752673729237782832">Tækin mín</translation> -<translation id="3752757212511661046">Búa til vinnusnið?</translation> <translation id="3753033997400164841">Vista einu sinni. Nota hvar sem er</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> getur nú einnig tekið þetta <ph name="DEVICE_TYPE" /> tæki úr lás.</translation> <translation id="375636864092143889">Vefsvæði er að nota hljóðnemann þinn</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Sýna PIN-númer</translation> <translation id="3873915545594852654">Vandamál með ARC++ kom upp.</translation> <translation id="3874164307099183178">Kveikja á Google hjálpara</translation> -<translation id="387531380970557479">Slökkt var á „<ph name="EXTENSION_NAME" />“ vegna þess að það inniheldur spilliforrit.</translation> <translation id="3879748587602334249">Niðurhalsstjórnun</translation> <translation id="3881478300875776315">Sýna færri línur</translation> <translation id="3882165008614329320">Fyrirliggjandi myndskeið úr myndavél eða skrá</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Bæta fingrafari við</translation> <translation id="4562494484721939086">Ekkert símasamband</translation> <translation id="4563210852471260509">Inntakstungumál er í upphafi kínverska</translation> -<translation id="4563404051166505887">1 mynd</translation> <translation id="4563880231729913339">Fingur 3</translation> <translation id="4565377596337484307">Fela aðgangsorð</translation> <translation id="4565917129334815774">Geyma kerfisannála</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb index acc8c0b..f00b107 100644 --- a/chrome/app/resources/generated_resources_it.xtb +++ b/chrome/app/resources/generated_resources_it.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">Segnala un bug</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">I miei dispositivi</translation> -<translation id="3752757212511661046">Creare profilo di lavoro?</translation> <translation id="3753033997400164841">Memorizza una volta, usa ovunque</translation> <translation id="3755411799582650620">Ora con il tuo <ph name="PHONE_NAME" /> puoi sbloccare anche questo dispositivo <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Il sito sta usando il microfono</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">Mostra i codici PIN</translation> <translation id="3873915545594852654">Si è verificato un problema con ARC++.</translation> <translation id="3874164307099183178">Attivare l'Assistente Google</translation> -<translation id="387531380970557479">L'estensione "<ph name="EXTENSION_NAME" />" è stata disattivata perché contiene malware.</translation> <translation id="3879748587602334249">Gestione dei download</translation> <translation id="3881478300875776315">Mostra meno righe</translation> <translation id="3882165008614329320">Video esistente da fotocamera o file</translation> @@ -2903,7 +2901,6 @@ <translation id="4562155214028662640">Aggiungi impronta digitale</translation> <translation id="4562494484721939086">Nessun servizio</translation> <translation id="4563210852471260509">La lingua di input iniziale è il cinese</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Dito 3</translation> <translation id="4565377596337484307">Nascondi password</translation> <translation id="4565917129334815774">Archivia log di sistema</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb index 51da3ffb..73107fc 100644 --- a/chrome/app/resources/generated_resources_iw.xtb +++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -2262,7 +2262,6 @@ <translation id="3748706263662799310">דיווח על באג</translation> <translation id="3752582316358263300">אישור...</translation> <translation id="3752673729237782832">המכשירים שלי</translation> -<translation id="3752757212511661046">האם ליצור פרופיל עבודה?</translation> <translation id="3753033997400164841">מאחסנים סיסמה פעם אחת. משתמשים בה בכל מקום.</translation> <translation id="3755411799582650620">ה-<ph name="PHONE_NAME" /> יכול כעת לבטל גם את הנעילה של <ph name="DEVICE_TYPE" /> זה.</translation> <translation id="375636864092143889">האתר משתמש במיקרופון</translation> @@ -2383,7 +2382,6 @@ <translation id="3873423927483480833">הצגת קודי אימות</translation> <translation id="3873915545594852654">התרחשה בעיה הקשורה ל-ARC++.</translation> <translation id="3874164307099183178">הפעלת Google Assistant</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" הושבת כי הוא מכיל תוכנה זדונית.</translation> <translation id="3879748587602334249">מנהל ההורדות</translation> <translation id="3881478300875776315">אני רוצה לראות פחות שורות</translation> <translation id="3882165008614329320">סרטון קיים ממצלמה או מקובץ</translation> @@ -2902,7 +2900,6 @@ <translation id="4562155214028662640">הוסף טביעת אצבע</translation> <translation id="4562494484721939086">אין שירות</translation> <translation id="4563210852471260509">שפת הקלט הראשונית היא סינית</translation> -<translation id="4563404051166505887">תמונה אחת</translation> <translation id="4563880231729913339">אצבע שלישית</translation> <translation id="4565377596337484307">הסתר סיסמה</translation> <translation id="4565917129334815774">אחסון יומני מערכת</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb index 13c328b0..1498c34a 100644 --- a/chrome/app/resources/generated_resources_ja.xtb +++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">バグを報告</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">マイ デバイス</translation> -<translation id="3752757212511661046">仕事用プロフィールを作成しますか?</translation> <translation id="3753033997400164841">一度保存すればどこでも使用可能</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> でもこの <ph name="DEVICE_TYPE" /> のロックを解除できるようになりました。</translation> <translation id="375636864092143889">サイトでマイクが使用されています</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">PIN を表示</translation> <translation id="3873915545594852654">ARC++ で問題が発生しました。</translation> <translation id="3874164307099183178">Google アシスタントをオンにする</translation> -<translation id="387531380970557479">「<ph name="EXTENSION_NAME" />」はマルウェアが含まれるため無効になっています。</translation> <translation id="3879748587602334249">ダウンロード マネージャ</translation> <translation id="3881478300875776315">表示する行数を減らす</translation> <translation id="3882165008614329320">カメラやファイルに保存されている動画</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">指紋を追加</translation> <translation id="4562494484721939086">サービスなし</translation> <translation id="4563210852471260509">初期の入力言語を中国語にする</translation> -<translation id="4563404051166505887">1 枚の写真</translation> <translation id="4563880231729913339">指 3</translation> <translation id="4565377596337484307">パスワードを表示しない</translation> <translation id="4565917129334815774">システムログを保存</translation>
diff --git a/chrome/app/resources/generated_resources_ka.xtb b/chrome/app/resources/generated_resources_ka.xtb index fc2a363..09c1f99 100644 --- a/chrome/app/resources/generated_resources_ka.xtb +++ b/chrome/app/resources/generated_resources_ka.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">ხარვეზის შესახებ შეტყობინება</translation> <translation id="3752582316358263300">კარგი...</translation> <translation id="3752673729237782832">ჩემი მოწყობილობები</translation> -<translation id="3752757212511661046">გსურთ სამსახურის პროფილის შექმნა?</translation> <translation id="3753033997400164841">შეინახეთ ერთხელ. გამოიყენეთ ყველგან</translation> <translation id="3755411799582650620">თქვენს <ph name="PHONE_NAME" /> მოწყობილობას ახლა შეუძლია განბლოკოს ეს <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">საიტი იყენებს თქვენს მიკროფონს</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">PIN-კოდების ჩვენება</translation> <translation id="3873915545594852654">წარმოიქმნა ARC++-თან დაკავშირებული პრობლემა.</translation> <translation id="3874164307099183178">Google ასისტენტის ჩართვა</translation> -<translation id="387531380970557479">„<ph name="EXTENSION_NAME" />“ გათიშულია, რადგან მავნე პროგრამას შეიცავს.</translation> <translation id="3879748587602334249">ჩამოტვირთვის მენეჯერი</translation> <translation id="3881478300875776315">ნაკლები ხაზის ჩვენება</translation> <translation id="3882165008614329320">არსებული ვიდეო კამერიდან ან ფაილიდან</translation> @@ -2903,7 +2901,6 @@ <translation id="4562155214028662640">თითის ანაბეჭდის დამატება</translation> <translation id="4562494484721939086">მომსახურება არ არის</translation> <translation id="4563210852471260509">საწყისი შეტანის ენაა ჩინური</translation> -<translation id="4563404051166505887">1 ფოტო</translation> <translation id="4563880231729913339">თითის ანაბეჭდი 3</translation> <translation id="4565377596337484307">პაროლის დამალვა</translation> <translation id="4565917129334815774">სისტემის ჟურნალების შენახვა</translation>
diff --git a/chrome/app/resources/generated_resources_kk.xtb b/chrome/app/resources/generated_resources_kk.xtb index 6f2a292..7b6c3ff 100644 --- a/chrome/app/resources/generated_resources_kk.xtb +++ b/chrome/app/resources/generated_resources_kk.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">Қате туралы хабарлау</translation> <translation id="3752582316358263300">Жарайды…</translation> <translation id="3752673729237782832">Құрылғыларым</translation> -<translation id="3752757212511661046">Жұмыс профилін жасайсыз ба?</translation> <translation id="3753033997400164841">Бір рет сақтаңыз. Кез келген құрылғыда пайдаланыңыз</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> телефоныңыз енді осы <ph name="DEVICE_TYPE" /> құрылғысын да құлыптан аша алады.</translation> <translation id="375636864092143889">Сайт микрофонды пайдалануда</translation> @@ -2382,7 +2381,6 @@ <translation id="3873423927483480833">PIN кодтарын көрсету</translation> <translation id="3873915545594852654">ARC++ ақауы орын алды.</translation> <translation id="3874164307099183178">Google Assistant қолданбасын қосу</translation> -<translation id="387531380970557479">Құрамында зиянды бағдарлама болғандықтан, "<ph name="EXTENSION_NAME" />" өшірілді.</translation> <translation id="3879748587602334249">Жүктеп алу менеджері</translation> <translation id="3881478300875776315">Жолдарды азырақ көрсету</translation> <translation id="3882165008614329320">Камерадан немесе файлдан алынған бейне</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">Саусақ ізін қосу</translation> <translation id="4562494484721939086">Қызмет жоқ</translation> <translation id="4563210852471260509">Қытай тіліндегі бастапқы енгізу тілі</translation> -<translation id="4563404051166505887">1 фотосурет</translation> <translation id="4563880231729913339">3-ші саусақ</translation> <translation id="4565377596337484307">Құпия сөзді жасыру</translation> <translation id="4565917129334815774">Жүйе журналдарын сақтау</translation>
diff --git a/chrome/app/resources/generated_resources_km.xtb b/chrome/app/resources/generated_resources_km.xtb index b0771ddd..27190210 100644 --- a/chrome/app/resources/generated_resources_km.xtb +++ b/chrome/app/resources/generated_resources_km.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">រាយការណ៍អំពីបញ្ហា</translation> <translation id="3752582316358263300">យល់ព្រម...</translation> <translation id="3752673729237782832">ឧបករណ៍របស់ខ្ញុំ</translation> -<translation id="3752757212511661046">បង្កើតកម្រងព័ត៌មានការងារឬ?</translation> <translation id="3753033997400164841">រក្សាទុកម្ដង ប្រើបានគ្រប់ទីកន្លែង។</translation> <translation id="3755411799582650620">ឥឡូវនេះ <ph name="PHONE_NAME" /> របស់អ្នកអាចដោះសោ <ph name="DEVICE_TYPE" /> នេះដែរ។</translation> <translation id="375636864092143889">ទំព័រកំពុងប្រើមីក្រូហ្វូនរបស់អ្នក</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">បង្ហាញកូដ PIN</translation> <translation id="3873915545594852654">ARC++ មានបញ្ហា។</translation> <translation id="3874164307099183178">បើក Google ជំនួយការ</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" ត្រូវបានបិទ ដោយសារវាមានកម្មវិធីគ្រោះថ្នាក់។</translation> <translation id="3879748587602334249">កម្មវិធីគ្រប់គ្រងការទាញយក</translation> <translation id="3881478300875776315">បង្ហាញបន្ទាត់តិចជាងនេះ</translation> <translation id="3882165008614329320">វីដេអូដែលមានស្រាប់ពីកាមេរ៉ា ឬឯកសារ</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">បញ្ចូលស្នាមម្រាមដៃ</translation> <translation id="4562494484721939086">គ្មានសេវាទេ</translation> <translation id="4563210852471260509">ភាសាបញ្ចូលដើមគឺភាសាចិន</translation> -<translation id="4563404051166505887">រូបថត 1 សន្លឹក</translation> <translation id="4563880231729913339">ម្រាមដៃទី 3</translation> <translation id="4565377596337484307">លាក់ពាក្យសម្ងាត់</translation> <translation id="4565917129334815774">រក្សាទុកកំណត់ហេតុប្រព័ន្ធ</translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb index 9354094..0fedec9c 100644 --- a/chrome/app/resources/generated_resources_kn.xtb +++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">ಬಗ್ ವರದಿ ಮಾಡಿ</translation> <translation id="3752582316358263300">ಸರಿ...</translation> <translation id="3752673729237782832">ನನ್ನ ಸಾಧನಗಳು</translation> -<translation id="3752757212511661046">ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ರಚಿಸುವುದೇ?</translation> <translation id="3753033997400164841">ಒಮ್ಮೆ ಸಂಗ್ರಹಿಸಿ. ಎಲ್ಲೆಡೆ ಬಳಸಿ</translation> <translation id="3755411799582650620">ನಿಮ್ಮ <ph name="PHONE_NAME" /> ಫೋನ್ ಈ <ph name="DEVICE_TYPE" /> ವನ್ನು ಸಹ ಅನ್ಲಾಕ್ ಮಾಡಬಹುದು.</translation> <translation id="375636864092143889">ನಿಮ್ಮ ಮೈಕ್ರೊಫೋನ್ ಅನ್ನು ಸೈಟ್ ಬಳಸುತ್ತಿದೆ</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">ಪಿನ್ಗಳನ್ನು ತೋರಿಸಿ</translation> <translation id="3873915545594852654">ARC++ ನಲ್ಲಿ ಸಮಸ್ಯೆ ಸಂಭವಿಸಿದೆ.</translation> <translation id="3874164307099183178">Google Assistant ಆನ್ ಮಾಡಿ</translation> -<translation id="387531380970557479">ಮಾಲ್ವೇರ್ ಅನ್ನು "<ph name="EXTENSION_NAME" />" ಒಳಗೊಂಡಿರುವುದರಿಂದ, ಅದನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ</translation> <translation id="3879748587602334249">ಡೌನ್ಲೋಡ್ ನಿರ್ವಾಹಕ</translation> <translation id="3881478300875776315">ಕೆಲವೇ ಸಾಲುಗಳನ್ನು ತೋರಿಸಿ</translation> <translation id="3882165008614329320">ಕ್ಯಾಮರಾ ಅಥವಾ ಫೈಲ್ನಲ್ಲಿರುವ ಪ್ರಸ್ತುತ ವೀಡಿಯೊ</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">ಫಿಂಗರ್ಫ್ರಿಂಟ್ ಸೇರಿಸಿ</translation> <translation id="4562494484721939086">ಸೇವೆ ಲಭ್ಯವಿಲ್ಲ</translation> <translation id="4563210852471260509">ಚೈನೀಸ್ನ ಆರಂಭದ ಇನ್ಪುಟ್ ಭಾಷೆ</translation> -<translation id="4563404051166505887">1 ಫೋಟೋ</translation> <translation id="4563880231729913339">ಬೆರಳು 3</translation> <translation id="4565377596337484307">ಪಾಸ್ವರ್ಡ್ ಮರೆಮಾಡಿ</translation> <translation id="4565917129334815774">ಸಿಸ್ಟಂ ಲಾಗ್ಗಳನ್ನು ಸಂಗ್ರಹಿಸಿ</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb index 9395804..ba244c46 100644 --- a/chrome/app/resources/generated_resources_ko.xtb +++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">버그 신고</translation> <translation id="3752582316358263300">확인...</translation> <translation id="3752673729237782832">내 기기</translation> -<translation id="3752757212511661046">직장 프로필을 만드시겠습니까?</translation> <translation id="3753033997400164841">한 번만 저장하고 어디서나 사용하세요</translation> <translation id="3755411799582650620">이제 <ph name="PHONE_NAME" />에서도 이 <ph name="DEVICE_TYPE" />을(를) 잠금 해제할 수 있습니다.</translation> <translation id="375636864092143889">사이트에서 마이크를 사용하고 있습니다.</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">PIN 표시</translation> <translation id="3873915545594852654">ARC++에 문제가 발생했습니다.</translation> <translation id="3874164307099183178">Google 어시스턴트 사용 설정</translation> -<translation id="387531380970557479">‘<ph name="EXTENSION_NAME" />’ 확장 프로그램에 멀웨어가 포함되어 있어 사용 중지되었습니다.</translation> <translation id="3879748587602334249">다운로드 관리자</translation> <translation id="3881478300875776315">자막 접기</translation> <translation id="3882165008614329320">카메라 또는 파일의 기존 동영상</translation> @@ -2902,7 +2900,6 @@ <translation id="4562155214028662640">지문 추가</translation> <translation id="4562494484721939086">서비스 불가</translation> <translation id="4563210852471260509">중국어를 초기 입력 언어로 설정</translation> -<translation id="4563404051166505887">사진 1장</translation> <translation id="4563880231729913339">손가락 3</translation> <translation id="4565377596337484307">비밀번호 숨김</translation> <translation id="4565917129334815774">시스템 로그 저장</translation>
diff --git a/chrome/app/resources/generated_resources_ky.xtb b/chrome/app/resources/generated_resources_ky.xtb index 5be4736..f376b45 100644 --- a/chrome/app/resources/generated_resources_ky.xtb +++ b/chrome/app/resources/generated_resources_ky.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Мүчүлүштүк жөнүндө кабарлаңыз</translation> <translation id="3752582316358263300">OK…</translation> <translation id="3752673729237782832">Менин түзмөктөрүм</translation> -<translation id="3752757212511661046">Жумуш профилин түзөсүзбү?</translation> <translation id="3753033997400164841">Бир жолу сактайсыз. Бардык жерде колдоносуз</translation> <translation id="3755411799582650620">Эми сиздин <ph name="PHONE_NAME" /> бул <ph name="DEVICE_TYPE" /> түзмөктүн да кулпусун ача алат.</translation> <translation id="375636864092143889">Сайт микрофонуңузду колдонууда</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">PIN-коддорду көрсөтүү</translation> <translation id="3873915545594852654">Төмөнкүнү иштетүүдө ката кетти: ARC++.</translation> <translation id="3874164307099183178">Google Жардамчыны күйгүзүү</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" кеңейтүүсүндө кесепеттүү программа бар болгондуктан ал өчүрүлдү.</translation> <translation id="3879748587602334249">Жүктөп алгыч</translation> <translation id="3881478300875776315">Азыраак көрсөтүү</translation> <translation id="3882165008614329320">Камерадагы же файлдагы учурдагы видео</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Манжа изин кошуу</translation> <translation id="4562494484721939086">Тейленбейт</translation> <translation id="4563210852471260509">Баштапкы киргизүү тили – кытайча</translation> -<translation id="4563404051166505887">1 сүрөт</translation> <translation id="4563880231729913339">3-манжа</translation> <translation id="4565377596337484307">Сырсөздү жашыруу</translation> <translation id="4565917129334815774">Тутумдун таржымалдарын сактоо</translation>
diff --git a/chrome/app/resources/generated_resources_lo.xtb b/chrome/app/resources/generated_resources_lo.xtb index 4fcc2a21..d6ddcaf 100644 --- a/chrome/app/resources/generated_resources_lo.xtb +++ b/chrome/app/resources/generated_resources_lo.xtb
@@ -2278,7 +2278,6 @@ <translation id="3748706263662799310">ລາຍງານຂໍ້ຜິດພາດ</translation> <translation id="3752582316358263300">ຕົກລົງ...</translation> <translation id="3752673729237782832">ອຸປະກອນຂອງຂ້ອຍ</translation> -<translation id="3752757212511661046">ສ້າງໂປຣໄຟລ໌ບ່ອນເຮັດວຽກບໍ?</translation> <translation id="3753033997400164841">ເກັບໄວ້ເທື່ອດຽວ. ໃຊ້ຢູ່ທຸກບ່ອນ</translation> <translation id="3755411799582650620">ດຽວນີ້ <ph name="PHONE_NAME" /> ຂອງທ່ານສາມາດປົດລັອກ <ph name="DEVICE_TYPE" /> ອັນນີ້ໄດ້ຄືກັນ.</translation> <translation id="375636864092143889">ເວັບໄຊກຳລັງໃຊ້ໄມໂຄຣໂຟນຂອງທ່ານ</translation> @@ -2400,7 +2399,6 @@ <translation id="3873423927483480833">ສະແດງ PIN</translation> <translation id="3873915545594852654">ເກີດບັນຫາກັບ ARC++.</translation> <translation id="3874164307099183178">ເປີດຜູ້ຊ່ວຍ Google</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" ໄດ້ຖືກປິດການນຳໃຊ້ແລ້ວ ເພາະວ່າມັນປະກອບມີເມົາແວ.</translation> <translation id="3879748587602334249">ຕົວຈັດການການດາວໂຫລດ</translation> <translation id="3881478300875776315">ສະແດງແຖວໜ້ອຍລົງ</translation> <translation id="3882165008614329320">ວິດີໂອທີ່ມີຢູ່ແລ້ວຈາກກ້ອງຖ່າຍຮູບ ຫຼື ໄຟລ໌</translation> @@ -2921,7 +2919,6 @@ <translation id="4562155214028662640">ເພີ່ມລາຍນິ້ວມື</translation> <translation id="4562494484721939086">ບໍ່ມີການບໍລິການ</translation> <translation id="4563210852471260509">ພາສາປ້ອນເຂົ້າເບື້ອງຕົ້ນແມ່ນພາສາຈີນ</translation> -<translation id="4563404051166505887">1 ຮູບ</translation> <translation id="4563880231729913339">ນິ້ວ 3</translation> <translation id="4565377596337484307">ເຊື່ອງລະຫັດຜ່ານ</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{<ph name="DOMAIN" /> ກຳນົດໃຫ້ທ່ານສຳຮອງຂໍ້ມູນຂອງທ່ານໄວ້ ແລະ ສົ່ງ <ph name="DEVICE_TYPE" /> ນີ້ຄືນໃນມື້ນີ້.}other{<ph name="DOMAIN" /> ກຳນົດໃຫ້ທ່ານສຳຮອງຂໍ້ມູນຂອງທ່ານໄວ້ ແລະ ສົ່ງ <ph name="DEVICE_TYPE" /> ນີ້ຄືນກ່ອນເວລາທີ່ກຳນົດໄວ້.}}</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb index 70fcb407..a5dd58c 100644 --- a/chrome/app/resources/generated_resources_lt.xtb +++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -2280,7 +2280,6 @@ <translation id="3748706263662799310">Pateikti ataskaitą apie triktį</translation> <translation id="3752582316358263300">Gerai...</translation> <translation id="3752673729237782832">Mano įrenginiai</translation> -<translation id="3752757212511661046">Sukurti darbo profilį?</translation> <translation id="3753033997400164841">Išsaugokite vieną kartą. Naudokite visur</translation> <translation id="3755411799582650620">„<ph name="PHONE_NAME" />“ taip pat gali atrakinti šį „<ph name="DEVICE_TYPE" />“ įrenginį.</translation> <translation id="375636864092143889">Svetainė naudoja jūsų mikrofoną</translation> @@ -2402,7 +2401,6 @@ <translation id="3873423927483480833">Rodyti PIN kodus</translation> <translation id="3873915545594852654">Iškilo su ARC++ susijusi problema.</translation> <translation id="3874164307099183178">Įjungti „Google“ padėjėją</translation> -<translation id="387531380970557479">Plėtinys „<ph name="EXTENSION_NAME" />“ išjungtas, nes jame yra kenkėjiška programa.</translation> <translation id="3879748587602334249">Atsisiuntimų tvarkytuvė</translation> <translation id="3881478300875776315">Rodyti mažiau eilučių</translation> <translation id="3882165008614329320">Esamas vaizdo įrašas iš kameros ar failo</translation> @@ -2923,7 +2921,6 @@ <translation id="4562155214028662640">Pridėti piršto antspaudą</translation> <translation id="4562494484721939086">Nėra paslaugos</translation> <translation id="4563210852471260509">Pagrindinė įvesties kalba – kinų k.</translation> -<translation id="4563404051166505887">1 nuotrauka</translation> <translation id="4563880231729913339">Trečias pirštas</translation> <translation id="4565377596337484307">Slėpti slaptažodį</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{Domene <ph name="DOMAIN" /> reikalaujama, kad sukurtumėte atsarginę duomenų kopiją ir grąžintumėte šį „<ph name="DEVICE_TYPE" />“ įrenginį šiandien.}one{Domene <ph name="DOMAIN" /> reikalaujama, kad sukurtumėte atsarginę duomenų kopiją ir grąžintumėte šį „<ph name="DEVICE_TYPE" />“ įrenginį iki nurodyto termino.}few{Domene <ph name="DOMAIN" /> reikalaujama, kad sukurtumėte atsarginę duomenų kopiją ir grąžintumėte šį „<ph name="DEVICE_TYPE" />“ įrenginį iki nurodyto termino.}many{Domene <ph name="DOMAIN" /> reikalaujama, kad sukurtumėte atsarginę duomenų kopiją ir grąžintumėte šį „<ph name="DEVICE_TYPE" />“ įrenginį iki nurodyto termino.}other{Domene <ph name="DOMAIN" /> reikalaujama, kad sukurtumėte atsarginę duomenų kopiją ir grąžintumėte šį „<ph name="DEVICE_TYPE" />“ įrenginį iki nurodyto termino.}}</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb index 77b2c7ea..3de3ed0 100644 --- a/chrome/app/resources/generated_resources_lv.xtb +++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Ziņot par blusu</translation> <translation id="3752582316358263300">Labi...</translation> <translation id="3752673729237782832">Manas ierīces</translation> -<translation id="3752757212511661046">Vai izveidot darba profilu?</translation> <translation id="3753033997400164841">Saglabājiet vienreiz, izmantojiet it visur</translation> <translation id="3755411799582650620">Ar jūsu tālruni <ph name="PHONE_NAME" /> tagad var atbloķēt arī šo <ph name="DEVICE_TYPE" /> ierīci.</translation> <translation id="375636864092143889">Vietne izmanto jūsu mikrofonu.</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Rādīt PIN kodus</translation> <translation id="3873915545594852654">Radās problēma ar ARC++.</translation> <translation id="3874164307099183178">Google asistenta ieslēgšana</translation> -<translation id="387531380970557479">Paplašinājums <ph name="EXTENSION_NAME" /> ir atspējots, jo tajā ir ļaunprogrammatūra.</translation> <translation id="3879748587602334249">Lejupielāžu pārvaldnieks</translation> <translation id="3881478300875776315">Rādīt mazāk rindu</translation> <translation id="3882165008614329320">Esošs videoklips no kameras vai faila</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Pievienot pirksta nospiedumu</translation> <translation id="4562494484721939086">Nav pakalpojuma</translation> <translation id="4563210852471260509">Sākotnējā ievades valoda ir ķīniešu valoda</translation> -<translation id="4563404051166505887">1 fotoattēls</translation> <translation id="4563880231729913339">3. pirksts</translation> <translation id="4565377596337484307">Slēpt paroli</translation> <translation id="4565917129334815774">Glabāt sistēmas žurnālus</translation>
diff --git a/chrome/app/resources/generated_resources_mk.xtb b/chrome/app/resources/generated_resources_mk.xtb index c73f9c4a..88db82a0 100644 --- a/chrome/app/resources/generated_resources_mk.xtb +++ b/chrome/app/resources/generated_resources_mk.xtb
@@ -2280,7 +2280,6 @@ <translation id="3748706263662799310">Пријавете грешка</translation> <translation id="3752582316358263300">Во ред...</translation> <translation id="3752673729237782832">Мои уреди</translation> -<translation id="3752757212511661046">Да се создаде работен профил?</translation> <translation id="3753033997400164841">Складирајте еднаш. Користете насекаде</translation> <translation id="3755411799582650620">Вашиот <ph name="PHONE_NAME" /> сега исто така може да го отклучи и овој <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Сајтот го користи микрофонот</translation> @@ -2402,7 +2401,6 @@ <translation id="3873423927483480833">Прикажете ги PIN-кодовите</translation> <translation id="3873915545594852654">Настана проблем со ARC++.</translation> <translation id="3874164307099183178">Вклучување на „Помошникот на Google“</translation> -<translation id="387531380970557479">„<ph name="EXTENSION_NAME" />“ е оневозможена бидејќи содржи злонамерен софтвер.</translation> <translation id="3879748587602334249">Управник со преземања</translation> <translation id="3881478300875776315">Прикажи помалку редови</translation> <translation id="3882165008614329320">Постојно видео од камера или датотека</translation> @@ -2923,7 +2921,6 @@ <translation id="4562155214028662640">Додај отпечаток</translation> <translation id="4562494484721939086">Нема услуга</translation> <translation id="4563210852471260509">Првичниот јазик на внесување е кинески</translation> -<translation id="4563404051166505887">1 фотографија</translation> <translation id="4563880231729913339">Прст 3</translation> <translation id="4565377596337484307">Сокриј ја лозинката</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{<ph name="DOMAIN" /> бара да направите бекап на вашите податоци и да го вратите овој <ph name="DEVICE_TYPE" /> денес.}one{<ph name="DOMAIN" /> бара да направите бекап на вашите податоци и да го вратите овој <ph name="DEVICE_TYPE" /> пред крајниот рок.}other{<ph name="DOMAIN" /> бара да направите бекап на вашите податоци и да го вратите овој <ph name="DEVICE_TYPE" /> пред крајниот рок.}}</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb index 91a0cc0..1858fa7 100644 --- a/chrome/app/resources/generated_resources_ml.xtb +++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">ഒരു ബഗ് റിപ്പോര്ട്ടുചെയ്യുക</translation> <translation id="3752582316358263300">ശരി...</translation> <translation id="3752673729237782832">എന്റെ ഉപകരണങ്ങൾ</translation> -<translation id="3752757212511661046">ഔദ്യോഗിക പ്രൊഫൈൽ സൃഷ്ടിക്കണോ?</translation> <translation id="3753033997400164841">ഒരു തവണ സംഭരിക്കൂ. എല്ലായിടത്തും ഉപയോഗിക്കൂ</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> എന്നതിന് ഇപ്പോൾ <ph name="DEVICE_TYPE" /> എന്നതും അൺലോക്ക് ചെയ്യാനാവും.</translation> <translation id="375636864092143889">സൈറ്റ് നിങ്ങളുടെ മൈക്രോഫോൺ ഉപയോഗിക്കുന്നു</translation> @@ -2382,7 +2381,6 @@ <translation id="3873423927483480833">പിന്നുകൾ കാണിക്കുക</translation> <translation id="3873915545594852654">ARC++ എന്നതിൽ ഒരു പ്രശ്നമുണ്ടായി.</translation> <translation id="3874164307099183178">Google Assistant ഓണാക്കുക</translation> -<translation id="387531380970557479">മാൽവേർ അടങ്ങിയിരിക്കുന്നതിനാൽ "<ph name="EXTENSION_NAME" />" എന്നതിനെ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു.</translation> <translation id="3879748587602334249">ഡൗൺലോഡ് മാനേജർ</translation> <translation id="3881478300875776315">കുറച്ച് വരികൾ മാത്രം കാണിക്കുക</translation> <translation id="3882165008614329320">ക്യാമറയിൽ നിന്നോ ഫയലിൽ നിന്നോ ഉള്ള നിലവിലെ വീഡിയോ</translation> @@ -2900,7 +2898,6 @@ <translation id="4562155214028662640">വിരലടയാളം ചേർക്കുക</translation> <translation id="4562494484721939086">സേവനമില്ല</translation> <translation id="4563210852471260509">പ്രാരംഭ ഇന്പുട്ട് ഭാഷ ചൈനീസ് ആണ്</translation> -<translation id="4563404051166505887">ഒരു ഫോട്ടോ</translation> <translation id="4563880231729913339">വിരൽ 3</translation> <translation id="4565377596337484307">പാസ്വേഡ് മറയ്ക്കുക</translation> <translation id="4565917129334815774">സിസ്റ്റം ലോഗുകൾ സംഭരിക്കുക</translation>
diff --git a/chrome/app/resources/generated_resources_mn.xtb b/chrome/app/resources/generated_resources_mn.xtb index b24f95f..63b3c74b6 100644 --- a/chrome/app/resources/generated_resources_mn.xtb +++ b/chrome/app/resources/generated_resources_mn.xtb
@@ -2259,7 +2259,6 @@ <translation id="3748706263662799310">Алдааг мэдээлэх</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Миний төхөөрөмжүүд</translation> -<translation id="3752757212511661046">Ажлын профайл үүсгэх үү?</translation> <translation id="3753033997400164841">Нэг удаа хадгалаад. Хүссэн газраа ашиглаарай</translation> <translation id="3755411799582650620">Таны <ph name="PHONE_NAME" /> одоо энэ <ph name="DEVICE_TYPE" /> -ийн түгжээг бас тайлж чадна.</translation> <translation id="375636864092143889">Сайт таны микрофоныг ашиглаж байна</translation> @@ -2380,7 +2379,6 @@ <translation id="3873423927483480833">ПИН харуулах</translation> <translation id="3873915545594852654">ARC++-д асуудал гарлаа.</translation> <translation id="3874164307099183178">Google Туслахыг асаах</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" хортой код агуулдаг тул үүнийг идэвхгүй болгосон.</translation> <translation id="3879748587602334249">Таталтын менежер</translation> <translation id="3881478300875776315">Арай цөөн мөр харуулах</translation> <translation id="3882165008614329320">Камер эсвэл файлд байгаа видео</translation> @@ -2898,7 +2896,6 @@ <translation id="4562155214028662640">Хурууны хээ нэмэх</translation> <translation id="4562494484721939086">Үйлчилгээ байхгүй</translation> <translation id="4563210852471260509">Эхний оролтын хэл бол Хятад хэл юм.</translation> -<translation id="4563404051166505887">1 зураг</translation> <translation id="4563880231729913339">Хуруу 3</translation> <translation id="4565377596337484307">Нууц үгийг нуух</translation> <translation id="4565917129334815774">Системийн логуудыг хадгалах</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb index 1b1af428..8fc84ae 100644 --- a/chrome/app/resources/generated_resources_mr.xtb +++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">एक दोष नोंदवा</translation> <translation id="3752582316358263300">ठीक आहे...</translation> <translation id="3752673729237782832">माझी डिव्हाइसेस</translation> -<translation id="3752757212511661046">कार्य प्रोफाइल तयार करायची का?</translation> <translation id="3753033997400164841">एकदा स्टोअर करा. कुठेही वापरा</translation> <translation id="3755411799582650620">तुमचा <ph name="PHONE_NAME" /> आता हे <ph name="DEVICE_TYPE" /> देखील अनलॉॅक करू शकतो.</translation> <translation id="375636864092143889">साइट तुमचा मायक्रोफोन वापरत आहे</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">पिन दाखवा</translation> <translation id="3873915545594852654">ARC++ ला समस्या आली.</translation> <translation id="3874164307099183178">Google Assistant सुरू करा</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" मध्ये मालवेअर असल्यामुळे ते बंद केले गेले आहे.</translation> <translation id="3879748587602334249">डाउनलोड व्यवस्थापक</translation> <translation id="3881478300875776315">कमी रेषा दाखवा</translation> <translation id="3882165008614329320">कॅमेरा किंवा फाइलवरून सद्य व्हिडिओ</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">फिंगरप्रिंट जोडा</translation> <translation id="4562494484721939086">सेवा नाही</translation> <translation id="4563210852471260509">चीनी आरंभिक इनपुट भाषा आहे</translation> -<translation id="4563404051166505887">एक फोटो</translation> <translation id="4563880231729913339">तिसरे बोट</translation> <translation id="4565377596337484307">पासवर्ड लपवा</translation> <translation id="4565917129334815774">सिस्टम लॉग स्टोअर करा</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb index ee8cfa2..93441ee 100644 --- a/chrome/app/resources/generated_resources_ms.xtb +++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Laporkan pepijat</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Peranti saya</translation> -<translation id="3752757212511661046">Buat Profil Kerja?</translation> <translation id="3753033997400164841">Simpan sekali. Gunakan di mana-mana</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> anda kini boleh membuka kunci <ph name="DEVICE_TYPE" /> ini juga.</translation> <translation id="375636864092143889">Tapak sedang menggunakan mikrofon anda</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Tunjukkan PIN</translation> <translation id="3873915545594852654">Masalah berkaitan ARC++ telah berlaku.</translation> <translation id="3874164307099183178">Hidupkan Google Assistant</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" telah dilumpuhkan kerana mengandungi perisian hasad.</translation> <translation id="3879748587602334249">Pengurus muat turun</translation> <translation id="3881478300875776315">Tunjukkan kurang baris</translation> <translation id="3882165008614329320">Video sedia ada daripada kamera atau fail</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Tambahkan Cap Jari</translation> <translation id="4562494484721939086">Tiada perkhidmatan</translation> <translation id="4563210852471260509">Bahasa input permulaan adalah bahasa Cina</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Jari 3</translation> <translation id="4565377596337484307">Sembunyikan kata laluan</translation> <translation id="4565917129334815774">Simpan log sistem</translation>
diff --git a/chrome/app/resources/generated_resources_my.xtb b/chrome/app/resources/generated_resources_my.xtb index 44b96d4..9db099e 100644 --- a/chrome/app/resources/generated_resources_my.xtb +++ b/chrome/app/resources/generated_resources_my.xtb
@@ -63,7 +63,7 @@ <translation id="1067048845568873861">ပြုလုပ်ပြီးပါပြီ</translation> <translation id="1067291318998134776">Linux (စမ်းသပ်ဆော့ဖ်ဝဲ)</translation> <translation id="1067922213147265141">အခြား Google ဝန်ဆောင်မှုများ</translation> -<translation id="1068961867683064946">သင့်ကလေးအတွက် Google အကောင့်ဖွင့်ပါ</translation> +<translation id="1068961867683064946">သင့်ကလေးအတွက် Google Account ဖွင့်ပါ</translation> <translation id="1070066693520972135">WEP</translation> <translation id="1070377999570795893">သင့်ကွန်ပျူတာသို့ Chrome အလုပ်လုပ်ပုံပြောင်းလဲစေမည့် ပရိုဂရမ်အဆက်တစ်ခုကို အခြားပရိုဂရမ်တစ်ခုမှ ပေါင်းတည့်ခဲ့ပါသည်။ @@ -1095,7 +1095,7 @@ <translation id="2307462900900812319">ကွန်ရက် ပြုပြင်ရန်</translation> <translation id="230927227160767054">ဤစာမျက်နှာသည် ဝန်ဆောင်မှု ကိုင်တွယ်ကိရိယာအား ထည့်သွင်းလိုသည်။</translation> <translation id="2309620859903500144">သင်၏လှုပ်ရှားမှု သို့မဟုတ် အလင်းရောင် အာရုံခံကိရိယာ အသုံးပြုခွင့်ကို ဤဝဘ်ဆိုက်အတွက် ပိတ်ထားပါသည်။</translation> -<translation id="2314873619957287124">သင့်ကလေး လေ့လာခြင်း၊ ကစားရာခြင်းနှင့် စူးစမ်းရှာဖွေခြင်းတို့တွင် ကူညီရန် အခြေခံဒစ်ဂျစ်တယ် စည်းမျဉ်းများ သတ်မှတ်ပါ</translation> +<translation id="2314873619957287124">သင့်ကလေး လေ့လာခြင်း၊ ကစားခြင်းနှင့် စူးစမ်းရှာဖွေခြင်းတို့တွင် ကူညီရန် အခြေခံဒစ်ဂျစ်တယ် စည်းမျဉ်းများ သတ်မှတ်ပါ</translation> <translation id="2315414688463285945">Linux ဖိုင်များကို စီစဉ်သတ်မှတ်ရာတွင် အမှားအယွင်းရှိနေသည်။ ထပ်စမ်းကြည့်ပါ။</translation> <translation id="2315587498123194634">လင့်ခ်ကို <ph name="DEVICE_NAME" /> သို့ ပို့ရန်</translation> <translation id="2316129865977710310">မလိုပါ</translation> @@ -1107,7 +1107,7 @@ <translation id="2322318151094136999">ဝဘ်ဆိုက်က အစဉ်လိုက်ပို့တ်များကို အသုံးပြုလိုသည့်အခါ ခွင့်တောင်းရန် (အကြံပြုထားသည်)</translation> <translation id="2323018538045954000">သိမ်းထားသော Wi-Fi ကွန်ရက်များ</translation> <translation id="2325444234681128157">စကားဝှက်ကို မှတ်ထားရန်</translation> -<translation id="2326160999284776503">သင့်ကလေး၏ 'Google အကောင့်' ဖြင့် လက်မှတ်ထိုးဝင်ပါ</translation> +<translation id="2326160999284776503">သင့်ကလေး၏ Google Account ဖြင့် လက်မှတ်ထိုးဝင်ပါ</translation> <translation id="2326188115274135041">အလိုအလျောက်ဖွင့်ရန်ကို ဖွင့်ရန် ပင်နံပါတ်ကို အတည်ပြုပါ</translation> <translation id="2326931316514688470">အက်ပ်ကို ပြန်စရန်</translation> <translation id="2327492829706409234">အက်ပ်ကို ဖွင့်ထားရန်</translation> @@ -2281,7 +2281,6 @@ <translation id="3748706263662799310">ချွတ်ယွင်းမှုကို တိုင်ကြားရန်</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">ကျွန်ုပ်၏ စက်ပစ္စည်းများ</translation> -<translation id="3752757212511661046">အလုပ်ပရိုဖိုင်ကို ဖန်တီးမလား။</translation> <translation id="3753033997400164841">တစ်ကြိမ် သိမ်းပါ။ နေရာတိုင်းတွင် အသုံးပြုပါ</translation> <translation id="3755411799582650620">သင်သည် ယခုတော့ သင်၏ <ph name="PHONE_NAME" /> ဖြင့် ဒီကိရိယာ <ph name="DEVICE_TYPE" />ကိုပါ သော့ဖွင့်ပေးနိုင်ပြီ။</translation> <translation id="375636864092143889">ဝဘ်ဆိုက်က သင့်မိုက်ခရိုဖုန်းကို အသုံးပြုနေသည်</translation> @@ -2403,7 +2402,6 @@ <translation id="3873423927483480833">ပင်နံပါတ်များ ပြရန်</translation> <translation id="3873915545594852654">ARC++ နှင့်ပက်သတ်၍ ပြဿနာရှိနေသည်။</translation> <translation id="3874164307099183178">Google Assistant ဖွင့်ရန်</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" တွင် မဲလ်ဝဲပါဝင်သည့်အတွက် ၎င်းကို ပိတ်လိုက်သည်။</translation> <translation id="3879748587602334249">ဒေါင်းလုဒ်မန်နေဂျာ</translation> <translation id="3881478300875776315">စာကြောင်းလျှော့၍ပြရန်</translation> <translation id="3882165008614329320">ကင်မရာ သို့မဟုတ် ဖိုင်မှ လက်ရှိဗီဒီယို</translation> @@ -2923,7 +2921,6 @@ <translation id="4562155214028662640">လက်ဗွေထည့်ရန်</translation> <translation id="4562494484721939086">ဝန်ဆောင်မှု မရှိပါ</translation> <translation id="4563210852471260509">အဦးဆုံးထည့်သွင်းရန် နည်းလမ်းမှာ တရုတ်ဖြစ်</translation> -<translation id="4563404051166505887">ဓာတ်ပုံ 1 ပုံ</translation> <translation id="4563880231729913339">လက်ချောင်း ၃</translation> <translation id="4565377596337484307">စကားဝှက်ကို ဖျောက်ရန်</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{သင့်ဒေတာများ အရန်သိမ်းပြီး ဤ <ph name="DEVICE_TYPE" /> ကို ယနေ့ပြန်ပို့ရန် <ph name="DOMAIN" /> က သတ်မှတ်ထားသည်။}other{သင့်ဒေတာများ အရန်သိမ်းပြီး ဤ <ph name="DEVICE_TYPE" /> ကို နောက်ဆုံးသတ်မှတ်ရက်မတိုင်မီ ပြန်ပို့ရန် <ph name="DOMAIN" /> က သတ်မှတ်ထားသည်။}}</translation>
diff --git a/chrome/app/resources/generated_resources_ne.xtb b/chrome/app/resources/generated_resources_ne.xtb index d8bf6a0..668b3d7 100644 --- a/chrome/app/resources/generated_resources_ne.xtb +++ b/chrome/app/resources/generated_resources_ne.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">बगका बारेमा रिपोर्ट गर्नुहोस्</translation> <translation id="3752582316358263300">ठिक छ...</translation> <translation id="3752673729237782832">मेरा यन्त्रहरू</translation> -<translation id="3752757212511661046">कार्य प्रोफाइल सिर्जना गर्ने हो?</translation> <translation id="3753033997400164841">एक पटक भण्डारण गर्नुहोस्। सबैतिर प्रयोग गर्नुहोस्</translation> <translation id="3755411799582650620">तपाईंको <ph name="PHONE_NAME" />ले अब यो<ph name="DEVICE_TYPE" /> पनि अनलक गर्न सक्छ।</translation> <translation id="375636864092143889">साइटले तपाईंको माइक्रोफोन प्रयोग गर्दै छ</translation> @@ -2382,7 +2381,6 @@ <translation id="3873423927483480833">PIN हरू देखाउनुहोस्</translation> <translation id="3873915545594852654">ARC++ सम्बन्धी कुनै समस्या भयो।</translation> <translation id="3874164307099183178">Google सहायक सक्रिय गर्नुहोस्</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" मा मालवेयर भएका कारण यो एक्सटेन्सनलाई असक्षम पारिएको छ।</translation> <translation id="3879748587602334249">डाउनलोड म्यानेजर</translation> <translation id="3881478300875776315">कम हरफ देखाउनुहोस्</translation> <translation id="3882165008614329320">क्यामेरा वा फाइलको विद्यमान भिडियो</translation> @@ -2900,7 +2898,6 @@ <translation id="4562155214028662640">फिंगरप्रिन्ट थप्नुहोस्</translation> <translation id="4562494484721939086">कुनै पनि सेवा छैन</translation> <translation id="4563210852471260509">प्रारम्भिक आगत भाषा चिनियाँ हो</translation> -<translation id="4563404051166505887">१ फोटो</translation> <translation id="4563880231729913339">औँला ३</translation> <translation id="4565377596337484307">पासवर्ड लुकाउनुहोस्</translation> <translation id="4565917129334815774">प्रणालीका लगहरू भण्डारण गर्नुहोस्</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb index d70f6541..3c438474 100644 --- a/chrome/app/resources/generated_resources_nl.xtb +++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Een fout melden</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Mijn apparaten</translation> -<translation id="3752757212511661046">Werkprofiel maken?</translation> <translation id="3753033997400164841">Eén keer opslaan, Overal gebruiken</translation> <translation id="3755411799582650620">Je <ph name="PHONE_NAME" /> kan deze <ph name="DEVICE_TYPE" /> nu ook ontgrendelen.</translation> <translation id="375636864092143889">Site gebruikt je microfoon</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Pincodes weergeven</translation> <translation id="3873915545594852654">Er is een probleem opgetreden met ARC++.</translation> <translation id="3874164307099183178">De Google Assistent inschakelen</translation> -<translation id="387531380970557479"><ph name="EXTENSION_NAME" /> is uitgeschakeld omdat deze extensie malware bevat</translation> <translation id="3879748587602334249">Downloadbeheer</translation> <translation id="3881478300875776315">Minder regels weergeven</translation> <translation id="3882165008614329320">Bestaande video van camera of uit bestand</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Vingerafdruk toevoegen</translation> <translation id="4562494484721939086">Geen service</translation> <translation id="4563210852471260509">Standaard invoertaal is Chinees</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Vinger 3</translation> <translation id="4565377596337484307">Wachtwoord verbergen</translation> <translation id="4565917129334815774">Systeemlogboeken opslaan</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb index c02ef32..5ec78a4 100644 --- a/chrome/app/resources/generated_resources_no.xtb +++ b/chrome/app/resources/generated_resources_no.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">Rapporter feil</translation> <translation id="3752582316358263300">OK</translation> <translation id="3752673729237782832">Mine enheter</translation> -<translation id="3752757212511661046">Vil du opprette en jobbprofil?</translation> <translation id="3753033997400164841">Lagre én gang. Bruk overalt</translation> <translation id="3755411799582650620">Du kan nå også låse opp <ph name="DEVICE_TYPE" /> med <ph name="PHONE_NAME" />.</translation> <translation id="375636864092143889">Nettstedet bruker mikrofonen din</translation> @@ -2382,7 +2381,6 @@ <translation id="3873423927483480833">Vis PIN-koder</translation> <translation id="3873915545594852654">Det oppsto et problem med ARC++.</translation> <translation id="3874164307099183178">Slå på Google-assistenten</translation> -<translation id="387531380970557479">«<ph name="EXTENSION_NAME" />» er deaktivert fordi den inneholder skadelig programvare.</translation> <translation id="3879748587602334249">Nedlastingsbehandling</translation> <translation id="3881478300875776315">Vis færre linjer</translation> <translation id="3882165008614329320">Eksisterende video fra kamera eller fil</translation> @@ -2899,7 +2897,6 @@ <translation id="4562155214028662640">Legg til fingeravtrykk</translation> <translation id="4562494484721939086">Ingen tjeneste</translation> <translation id="4563210852471260509">Det opprinnelige inndataspråket er kinesisk</translation> -<translation id="4563404051166505887">1 bilde</translation> <translation id="4563880231729913339">Finger 3</translation> <translation id="4565377596337484307">Skjul passord</translation> <translation id="4565917129334815774">Lagre systemlogger</translation>
diff --git a/chrome/app/resources/generated_resources_or.xtb b/chrome/app/resources/generated_resources_or.xtb index 3c65485..57d218e7 100644 --- a/chrome/app/resources/generated_resources_or.xtb +++ b/chrome/app/resources/generated_resources_or.xtb
@@ -2257,7 +2257,6 @@ <translation id="3748706263662799310">ଏକ ବଗ୍ ବିଷୟରେ ରିପୋର୍ଟ କରନ୍ତୁ</translation> <translation id="3752582316358263300">ଠିକ୍ ଅଛି...</translation> <translation id="3752673729237782832">ମୋ ଡିଭାଇସ୍</translation> -<translation id="3752757212511661046">ୱାର୍କ ପ୍ରୋଫାଇଲ୍ ତିଆରି କରିବେ?</translation> <translation id="3753033997400164841">ଥରେ ଷ୍ଟୋର୍ କରନ୍ତୁ। ସର୍ବତ୍ର ବ୍ୟବହାର କରନ୍ତୁ</translation> <translation id="3755411799582650620">ଆପଣଙ୍କର <ph name="PHONE_NAME" /> ବର୍ତ୍ତମାନ ଏହାକୁ <ph name="DEVICE_TYPE" /> ମଧ୍ୟ ଅନ୍ଲକ୍ କରିପାରିବ।</translation> <translation id="375636864092143889">ସାଇଟ୍ ଆପଣଙ୍କର ମାଇକ୍ରୋଫୋନ୍ ବ୍ୟବହାର କରୁଛି</translation> @@ -2378,7 +2377,6 @@ <translation id="3873423927483480833">PIN ଦେଖାନ୍ତୁ</translation> <translation id="3873915545594852654">ARC++ ସହିତ ଏକ ସମସ୍ୟା ହୋଇଛି।</translation> <translation id="3874164307099183178">Google Assistant ଚାଲୁ କରନ୍ତୁ</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />"ରେ ମାଲୱେର୍ ଥିବା ଯୋଗୁଁ ଏହା ଅକ୍ଷମ ହୋଇଯାଇଛି।</translation> <translation id="3879748587602334249">ଡାଉନ୍ଲୋଡ୍ ପରିଚାଳକ</translation> <translation id="3881478300875776315">କମ୍ ଲାଇନ୍ ଦେଖାନ୍ତୁ</translation> <translation id="3882165008614329320">କ୍ୟାମେରା କିମ୍ବା ଫାଇଲ୍ରେ ପୂର୍ବରୁ ଥିବା ଭିଡିଓ</translation> @@ -2896,7 +2894,6 @@ <translation id="4562155214028662640">ଟିପଚିହ୍ନ ଯୋଗ କରନ୍ତୁ</translation> <translation id="4562494484721939086">କୌଣସି ସେବା ନାହିଁ</translation> <translation id="4563210852471260509">ପ୍ରାରମ୍ଭିକ ଇନପୁଟ୍ ଭାଷା ଚାଇନିଜ୍ ଅଟେ</translation> -<translation id="4563404051166505887">1ଟି ଫଟୋ</translation> <translation id="4563880231729913339">ଟିପଚିହ୍ନ 3</translation> <translation id="4565377596337484307">ପାସୱାର୍ଡ୍ ଲୁଚାନ୍ତୁ</translation> <translation id="4565917129334815774">ସିଷ୍ଟମ୍ ଲଗଗୁଡ଼ିକ ଷ୍ଟୋର୍ କରନ୍ତୁ</translation>
diff --git a/chrome/app/resources/generated_resources_pa.xtb b/chrome/app/resources/generated_resources_pa.xtb index f424b26..73951b7 100644 --- a/chrome/app/resources/generated_resources_pa.xtb +++ b/chrome/app/resources/generated_resources_pa.xtb
@@ -2262,7 +2262,6 @@ <translation id="3748706263662799310">ਬੱਗ ਦੀ ਰਿਪੋਰਟ ਕਰੋ</translation> <translation id="3752582316358263300">ਠੀਕ...</translation> <translation id="3752673729237782832">ਮੇਰੀਆਂ ਡਿਵਾਈਸਾਂ</translation> -<translation id="3752757212511661046">ਕੀ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਬਣਾਉਣਾ ਹੈ?</translation> <translation id="3753033997400164841">ਇੱਕ ਵਾਰ ਸਟੋਰ ਕਰੋ। ਹਰ ਜਗ੍ਹਾ ਵਰਤੋ</translation> <translation id="3755411799582650620">ਤੁਹਾਡਾ <ph name="PHONE_NAME" /> ਵੀ ਹੁਣ ਇਸ <ph name="DEVICE_TYPE" /> ਨੂੰ ਅਣਲਾਕ ਕਰ ਸਕਦੀ ਹੈ।</translation> <translation id="375636864092143889">ਸਾਈਟ ਤੁਹਾਡੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀ ਹੈ</translation> @@ -2383,7 +2382,6 @@ <translation id="3873423927483480833">ਪਿੰਨਾਂ ਦਿਖਾਓ</translation> <translation id="3873915545594852654">ARC++ ਵਿੱਚ ਕੋਈ ਸਮੱਸਿਆ ਆਈ।</translation> <translation id="3874164307099183178">Google Assistant ਨੂੰ ਚਾਲੂ ਕਰੋ</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ ਹੈ ਕਿਉਂਕਿ ਇਸ ਵਿੱਚ ਮਾਲਵੇਅਰ ਹੈ।</translation> <translation id="3879748587602334249">ਡਾਊਨਲੋਡ ਪ੍ਰਬੰਧਕ</translation> <translation id="3881478300875776315">ਘੱਟ ਲਾਈਨਾਂ ਦਿਖਾਓ</translation> <translation id="3882165008614329320">ਕੈਮਰੇ ਜਾਂ ਫ਼ਾਈਲ ਤੋਂ ਮੌਜੂਦਾ ਵੀਡੀਓ</translation> @@ -2902,7 +2900,6 @@ <translation id="4562155214028662640">ਫਿੰਗਰਪ੍ਰਿੰਟ ਸ਼ਾਮਲ ਕਰੋ</translation> <translation id="4562494484721939086">ਕੋਈ ਸੇਵਾ ਨਹੀਂ</translation> <translation id="4563210852471260509">ਅਰੰਭਿਕ ਇਨਪੁਟ ਭਾਸ਼ਾ ਚੀਨੀ ਹੈ</translation> -<translation id="4563404051166505887">1 ਫ਼ੋਟੋ</translation> <translation id="4563880231729913339">ਉਂਗਲ 3</translation> <translation id="4565377596337484307">ਪਾਸਵਰਡ ਲੁਕਾਓ</translation> <translation id="4565917129334815774">ਸਿਸਟਮ ਲੌਗਾਂ ਨੂੰ ਸਟੋਰ ਕਰੋ</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb index b928fede..345bcb53 100644 --- a/chrome/app/resources/generated_resources_pl.xtb +++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -2260,7 +2260,6 @@ <translation id="3748706263662799310">Zgłoś błąd</translation> <translation id="3752582316358263300">OK</translation> <translation id="3752673729237782832">Moje urządzenia</translation> -<translation id="3752757212511661046">Utworzyć profil służbowy?</translation> <translation id="3753033997400164841">Zapisz raz – używaj w dowolnym miejscu</translation> <translation id="3755411799582650620">Telefon <ph name="PHONE_NAME" /> może teraz odblokowywać też urządzenie <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Strona używa mikrofonu</translation> @@ -2381,7 +2380,6 @@ <translation id="3873423927483480833">Pokaż kody PIN</translation> <translation id="3873915545594852654">Wystąpił problem z ARC++.</translation> <translation id="3874164307099183178">Włącz Asystenta Google</translation> -<translation id="387531380970557479">Rozszerzenie „<ph name="EXTENSION_NAME" />” zostało wyłączone, bo zawiera złośliwe oprogramowanie.</translation> <translation id="3879748587602334249">Menedżer pobierania</translation> <translation id="3881478300875776315">Pokaż mniej wierszy</translation> <translation id="3882165008614329320">Istniejący film z aparatu lub pliku</translation> @@ -2900,7 +2898,6 @@ <translation id="4562155214028662640">Dodaj odcisk palca</translation> <translation id="4562494484721939086">Brak usługi</translation> <translation id="4563210852471260509">Początkowy język wprowadzania: chiński</translation> -<translation id="4563404051166505887">1 zdjęcie</translation> <translation id="4563880231729913339">Palec 3</translation> <translation id="4565377596337484307">Ukryj hasło</translation> <translation id="4565917129334815774">Przechowuj dzienniki systemowe</translation>
diff --git a/chrome/app/resources/generated_resources_pt-BR.xtb b/chrome/app/resources/generated_resources_pt-BR.xtb index 9d8d64d6..8520e003 100644 --- a/chrome/app/resources/generated_resources_pt-BR.xtb +++ b/chrome/app/resources/generated_resources_pt-BR.xtb
@@ -2281,7 +2281,6 @@ <translation id="3748706263662799310">Informar um bug</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Meus dispositivos</translation> -<translation id="3752757212511661046">Criar perfil de trabalho?</translation> <translation id="3753033997400164841">Salve uma vez. Use em qualquer lugar</translation> <translation id="3755411799582650620">Seu <ph name="PHONE_NAME" /> agora pode desbloquear este <ph name="DEVICE_TYPE" /> também.</translation> <translation id="375636864092143889">O site está usando seu microfone</translation> @@ -2403,7 +2402,6 @@ <translation id="3873423927483480833">Mostrar PINs</translation> <translation id="3873915545594852654">Ocorreu um problema com o ARC++.</translation> <translation id="3874164307099183178">Ativar o Google Assistente</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" foi desativada porque contém malware.</translation> <translation id="3879748587602334249">Gerenciador de downloads</translation> <translation id="3881478300875776315">Mostrar menos linhas</translation> <translation id="3882165008614329320">Vídeo existente de uma câmera ou de um arquivo</translation> @@ -2924,7 +2922,6 @@ <translation id="4562155214028662640">Adicionar impressão digital</translation> <translation id="4562494484721939086">Sem serviço</translation> <translation id="4563210852471260509">O idioma de entrada inicial é o chinês</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Dedo 3</translation> <translation id="4565377596337484307">Ocultar senha</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{<ph name="DOMAIN" /> precisa que você faça backup dos seus dados e devolva este <ph name="DEVICE_TYPE" /> hoje.}one{<ph name="DOMAIN" /> precisa que você faça backup dos seus dados e devolva este <ph name="DEVICE_TYPE" /> antes do fim do prazo.}other{<ph name="DOMAIN" /> precisa que você faça backup dos seus dados e devolva este <ph name="DEVICE_TYPE" /> antes do fim do prazo.}}</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb index 981e6b0..501be59 100644 --- a/chrome/app/resources/generated_resources_pt-PT.xtb +++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Comunicar um erro</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Os meus dispositivos</translation> -<translation id="3752757212511661046">Pretende criar um perfil de trabalho?</translation> <translation id="3753033997400164841">Armazene uma vez. Utilize em todas as plataformas.</translation> <translation id="3755411799582650620">O seu <ph name="PHONE_NAME" /> pode agora desbloquear também este <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">O site está a utilizar o microfone.</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Mostrar PINs</translation> <translation id="3873915545594852654">Ocorreu um problema com o ARC++.</translation> <translation id="3874164307099183178">Ativar Assistente Google</translation> -<translation id="387531380970557479">A extensão "<ph name="EXTENSION_NAME" />" foi desativada porque contém software malicioso.</translation> <translation id="3879748587602334249">Gestor de transferências</translation> <translation id="3881478300875776315">Mostrar menos linhas</translation> <translation id="3882165008614329320">Vídeo existente da câmara ou do ficheiro</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Adicionar impressão digital</translation> <translation id="4562494484721939086">Sem serviço</translation> <translation id="4563210852471260509">O idioma de introdução inicial é chinês</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Dedo 3</translation> <translation id="4565377596337484307">Ocultar palavra-passe</translation> <translation id="4565917129334815774">Armazenar registos do sistema</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb index e3d29273..a3f736b 100644 --- a/chrome/app/resources/generated_resources_ro.xtb +++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Raportați o eroare</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Dispozitivele mele</translation> -<translation id="3752757212511661046">Creezi un profil de serviciu?</translation> <translation id="3753033997400164841">Stocheaz-o o singură dată. Folosește-o peste tot</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> poate debloca acum și acest <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Site-ul folosește microfonul</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Afișează codurile PIN</translation> <translation id="3873915545594852654">A apărut o eroare la ARC++.</translation> <translation id="3874164307099183178">Activează Asistentul Google</translation> -<translation id="387531380970557479">„<ph name="EXTENSION_NAME" />” a fost dezactivată, deoarece conține programe malware.</translation> <translation id="3879748587602334249">Manager de descărcări</translation> <translation id="3881478300875776315">Afișează mai puține rânduri</translation> <translation id="3882165008614329320">Videoclip existent din camera foto sau din fișier</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Adaugă o amprentă</translation> <translation id="4562494484721939086">Fără semnal</translation> <translation id="4563210852471260509">Limba inițială de introducere este chineza</translation> -<translation id="4563404051166505887">O fotografie</translation> <translation id="4563880231729913339">Deget 3</translation> <translation id="4565377596337484307">Ascunde parola</translation> <translation id="4565917129334815774">Stochează jurnalele de sistem</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb index 3cd3387b..7e2e68e 100644 --- a/chrome/app/resources/generated_resources_ru.xtb +++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -2262,7 +2262,6 @@ <translation id="3748706263662799310">Сообщить об ошибке</translation> <translation id="3752582316358263300">ОК...</translation> <translation id="3752673729237782832">Мои устройства</translation> -<translation id="3752757212511661046">Создать рабочий профиль?</translation> <translation id="3753033997400164841">Автозаполнение паролей</translation> <translation id="3755411799582650620">Теперь <ph name="PHONE_NAME" /> может разблокировать <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Сайт использует микрофон</translation> @@ -2383,7 +2382,6 @@ <translation id="3873423927483480833">Показать PIN-коды</translation> <translation id="3873915545594852654">Не удалось запустить ARC++.</translation> <translation id="3874164307099183178">Включить Google Ассистента</translation> -<translation id="387531380970557479">Расширение "<ph name="EXTENSION_NAME" />" отключено, поскольку оно содержит вредоносное ПО.</translation> <translation id="3879748587602334249">Диспетчер загрузки</translation> <translation id="3881478300875776315">Показать меньше строк</translation> <translation id="3882165008614329320">Видео с камеры или из файла</translation> @@ -2902,7 +2900,6 @@ <translation id="4562155214028662640">Добавить отпечаток пальца</translation> <translation id="4562494484721939086">Сеть не найдена</translation> <translation id="4563210852471260509">Первоначальный язык ввода – китайский</translation> -<translation id="4563404051166505887">1 фото</translation> <translation id="4563880231729913339">3-й палец</translation> <translation id="4565377596337484307">Скрыть пароль</translation> <translation id="4565917129334815774">Сохранить системные журналы</translation>
diff --git a/chrome/app/resources/generated_resources_si.xtb b/chrome/app/resources/generated_resources_si.xtb index 17ac526..b495d35 100644 --- a/chrome/app/resources/generated_resources_si.xtb +++ b/chrome/app/resources/generated_resources_si.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">දෝෂයක් වාර්තා කරන්න</translation> <translation id="3752582316358263300">හරි...</translation> <translation id="3752673729237782832">මගේ උපාංග</translation> -<translation id="3752757212511661046">කාර්යාල පැතිකඩ සාදන්න</translation> <translation id="3753033997400164841">එක් වරක් ගබඩා කරන්න. සැම තැනම භාවිත කරන්න</translation> <translation id="3755411799582650620">ඔබගේ <ph name="PHONE_NAME" /> හට දැන් මෙම <ph name="DEVICE_TYPE" /> ද අගුළු හැරීමට හැකිය.</translation> <translation id="375636864092143889">අඩවිය ඔබේ මයික්රෆෝනය භාවිත කරමින්</translation> @@ -2383,7 +2382,6 @@ <translation id="3873423927483480833">රහස් අංක පෙන්වන්න</translation> <translation id="3873915545594852654">ARC++ සමඟ ගැටලුවක් ඇති විය.</translation> <translation id="3874164307099183178">Google සහකරු සක්රීය කරන්න</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" තුළ අනිෂ්ට මෘදුකාංගය ඇති බැවින් එය අබල කර ඇත.</translation> <translation id="3879748587602334249">බාගැනීමේ කළමනාකරු</translation> <translation id="3881478300875776315">පේළි අඩුවෙන් පෙන්වන්න</translation> <translation id="3882165008614329320">කැමරාවෙන් හෝ ගොනුවෙන් පවතින වීඩියෝව</translation> @@ -2902,7 +2900,6 @@ <translation id="4562155214028662640">ඇඟිලි සලකුණ එක් කරන්න</translation> <translation id="4562494484721939086">සේවාව නැත</translation> <translation id="4563210852471260509">ආරම්භක ආදාන භාශාව චීන</translation> -<translation id="4563404051166505887">ඡායාරූප 1ක්</translation> <translation id="4563880231729913339">ඇඟිල්ල 3</translation> <translation id="4565377596337484307">මුරපදය සඟවන්න</translation> <translation id="4565917129334815774">පද්ධති ලොග ගබඩා කරන්න</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb index d83606c7..623ec019 100644 --- a/chrome/app/resources/generated_resources_sk.xtb +++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">Nahlásiť chybu</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Moje zariadenia</translation> -<translation id="3752757212511661046">Chcete vytvoriť pracovný profil?</translation> <translation id="3753033997400164841">Raz uložte. Používajte všade.</translation> <translation id="3755411799582650620">Váš telefón <ph name="PHONE_NAME" /> teraz dokáže odomknúť aj toto zariadenie <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Web používa váš mikrofón</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">Zobraziť kódy PIN</translation> <translation id="3873915545594852654">Vyskytol sa problém s ARC++.</translation> <translation id="3874164307099183178">Zapnúť Asistenta Google</translation> -<translation id="387531380970557479">Rozšírenie <ph name="EXTENSION_NAME" /> bolo zakázané, pretože obsahuje malvér.</translation> <translation id="3879748587602334249">Správca sťahovania</translation> <translation id="3881478300875776315">Zobraziť menej riadkov</translation> <translation id="3882165008614329320">Existujúce video z fotoaparátu alebo súboru</translation> @@ -2903,7 +2901,6 @@ <translation id="4562155214028662640">Pridať odtlačok</translation> <translation id="4562494484721939086">Žiadny signál</translation> <translation id="4563210852471260509">Úvodný jazyk vstupu: čínština</translation> -<translation id="4563404051166505887">1 fotka</translation> <translation id="4563880231729913339">3. prst</translation> <translation id="4565377596337484307">Skryť heslo</translation> <translation id="4565917129334815774">Ukladať denníky systému</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb index 85b5c5d..3eab721 100644 --- a/chrome/app/resources/generated_resources_sl.xtb +++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -2280,7 +2280,6 @@ <translation id="3748706263662799310">Obvestite nas o napaki</translation> <translation id="3752582316358263300">V redu ...</translation> <translation id="3752673729237782832">Moje naprave</translation> -<translation id="3752757212511661046">Želite ustvariti delovni profil?</translation> <translation id="3753033997400164841">Shranite enkrat. Uporabite kjer koli</translation> <translation id="3755411799582650620">Vaš telefon <ph name="PHONE_NAME" /> lahko zdaj odklene tudi to napravo <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Spletno mesto uporablja vaš mikrofon</translation> @@ -2402,7 +2401,6 @@ <translation id="3873423927483480833">Prikaz kod PIN</translation> <translation id="3873915545594852654">Prišlo je do težave s tehnologijo ARC++.</translation> <translation id="3874164307099183178">Vklop Pomočnika Google</translation> -<translation id="387531380970557479">Razširitev »<ph name="EXTENSION_NAME" />« je onemogočena, ker vsebuje zlonamerno programsko opremo.</translation> <translation id="3879748587602334249">Upravitelj prenosov</translation> <translation id="3881478300875776315">Pokaži manj vrstic</translation> <translation id="3882165008614329320">Obstoječi videoposnetek iz fotoaparata ali datoteke</translation> @@ -2923,7 +2921,6 @@ <translation id="4562155214028662640">Dodaj prstni odtis</translation> <translation id="4562494484721939086">Ni storitve</translation> <translation id="4563210852471260509">Prvotni jezik vnosa je kitajščina</translation> -<translation id="4563404051166505887">1 fotografija</translation> <translation id="4563880231729913339">Prst 3</translation> <translation id="4565377596337484307">Skrij geslo</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{Domena <ph name="DOMAIN" /> zahteva, da varnostno kopirate podatke in vrnete to napravo <ph name="DEVICE_TYPE" /> še danes.}one{<ph name="DOMAIN" /> zahteva, da naredite varnostno kopijo podatkov in vrnete to napravo <ph name="DEVICE_TYPE" /> pred rokom.}two{<ph name="DOMAIN" /> zahteva, da naredite varnostno kopijo podatkov in vrnete to napravo <ph name="DEVICE_TYPE" /> pred rokom.}few{<ph name="DOMAIN" /> zahteva, da naredite varnostno kopijo podatkov in vrnete to napravo <ph name="DEVICE_TYPE" /> pred rokom.}other{<ph name="DOMAIN" /> zahteva, da naredite varnostno kopijo podatkov in vrnete to napravo <ph name="DEVICE_TYPE" /> pred rokom.}}</translation>
diff --git a/chrome/app/resources/generated_resources_sq.xtb b/chrome/app/resources/generated_resources_sq.xtb index 043ec77..2e389e7e 100644 --- a/chrome/app/resources/generated_resources_sq.xtb +++ b/chrome/app/resources/generated_resources_sq.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">Raporto një defekt në kod</translation> <translation id="3752582316358263300">Në rregull...</translation> <translation id="3752673729237782832">Pajisjet e mia</translation> -<translation id="3752757212511661046">Të krijohet profili i punës?</translation> <translation id="3753033997400164841">Ruaji një herë. Përdori kudo</translation> <translation id="3755411799582650620">Telefoni yt <ph name="PHONE_NAME" /> mund ta shkyçë tani edhe këtë <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Sajti po përdor mikrofonin tënd</translation> @@ -2382,7 +2381,6 @@ <translation id="3873423927483480833">Shfaq kodet PIN</translation> <translation id="3873915545594852654">Ndodhi një problem me ARC++.</translation> <translation id="3874164307099183178">Aktivizo "Asistentin e Google"</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" është çaktivizuar sepse përmban softuer keqdashës.</translation> <translation id="3879748587602334249">Menaxheri i shkarkimeve</translation> <translation id="3881478300875776315">Shfaq më pak rreshta</translation> <translation id="3882165008614329320">Video ekzistuese nga kamera ose skedari</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">Shto një gjurmë gishti</translation> <translation id="4562494484721939086">Nuk ka shërbim</translation> <translation id="4563210852471260509">Gjuha fillestare e hyrjes është kinezishtja</translation> -<translation id="4563404051166505887">1 fotografi</translation> <translation id="4563880231729913339">Gishti 3</translation> <translation id="4565377596337484307">Fshih fjalëkalimin</translation> <translation id="4565917129334815774">Ruaj evidencat e sistemit</translation>
diff --git a/chrome/app/resources/generated_resources_sr-Latn.xtb b/chrome/app/resources/generated_resources_sr-Latn.xtb index f541ba0..c6a22ce 100644 --- a/chrome/app/resources/generated_resources_sr-Latn.xtb +++ b/chrome/app/resources/generated_resources_sr-Latn.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">Prijavite grešku</translation> <translation id="3752582316358263300">Potvrdi...</translation> <translation id="3752673729237782832">Moji uređaji</translation> -<translation id="3752757212511661046">Želite da napravite poslovni profil?</translation> <translation id="3753033997400164841">Sačuvajte jednom. Koristite svuda</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> telefon sada može da otključava i ovaj <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Sajt koristi mikrofon</translation> @@ -2382,7 +2381,6 @@ <translation id="3873423927483480833">Prikazuje PIN-ove</translation> <translation id="3873915545594852654">Došlo je do problema koji se odnosi na ARC++.</translation> <translation id="3874164307099183178">Uključite Google pomoćnik</translation> -<translation id="387531380970557479">Dodatak <ph name="EXTENSION_NAME" /> je onemogućen jer sadrži malver.</translation> <translation id="3879748587602334249">Menadžer preuzimanja</translation> <translation id="3881478300875776315">Prikaži manje redova</translation> <translation id="3882165008614329320">Postojeći video iz kamere ili datoteke</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">Dodaj digitalni otisak</translation> <translation id="4562494484721939086">Mobilna mreža nije dostupna</translation> <translation id="4563210852471260509">Početni jezik za unos je kineski</translation> -<translation id="4563404051166505887">1 slika</translation> <translation id="4563880231729913339">Prst 3</translation> <translation id="4565377596337484307">Sakrij lozinku</translation> <translation id="4565917129334815774">Skladišti evidencije sistema</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb index 8c4d21fbb..89f7500 100644 --- a/chrome/app/resources/generated_resources_sr.xtb +++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -2261,7 +2261,6 @@ <translation id="3748706263662799310">Пријавите грешку</translation> <translation id="3752582316358263300">Потврди...</translation> <translation id="3752673729237782832">Моји уређаји</translation> -<translation id="3752757212511661046">Желите да направите пословни профил?</translation> <translation id="3753033997400164841">Сачувајте једном. Користите свуда</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> телефон сада може да откључава и овај <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Сајт користи микрофон</translation> @@ -2382,7 +2381,6 @@ <translation id="3873423927483480833">Приказује PIN-ове</translation> <translation id="3873915545594852654">Дошло је до проблема који се односи на ARC++.</translation> <translation id="3874164307099183178">Укључите Google помоћник</translation> -<translation id="387531380970557479">Додатак <ph name="EXTENSION_NAME" /> је онемогућен јер садржи малвер.</translation> <translation id="3879748587602334249">Менаџер преузимања</translation> <translation id="3881478300875776315">Прикажи мање редова</translation> <translation id="3882165008614329320">Постојећи видео из камере или датотеке</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">Додај дигитални отисак</translation> <translation id="4562494484721939086">Мобилна мрежа није доступна</translation> <translation id="4563210852471260509">Почетни језик за унос је кинески</translation> -<translation id="4563404051166505887">1 слика</translation> <translation id="4563880231729913339">Прст 3</translation> <translation id="4565377596337484307">Сакриј лозинку</translation> <translation id="4565917129334815774">Складишти евиденције система</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb index 83198b1..d347b0a9 100644 --- a/chrome/app/resources/generated_resources_sv.xtb +++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Rapportera ett fel</translation> <translation id="3752582316358263300">OK ...</translation> <translation id="3752673729237782832">Mina enheter</translation> -<translation id="3752757212511661046">Vill du skapa en jobbprofil?</translation> <translation id="3753033997400164841">Spara dem en gång. Använd dem överallt</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> kan nu även låsa upp <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Webbplatsen använder din mikrofon</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Visa pinkoder</translation> <translation id="3873915545594852654">Ett problem med ARC++ uppstod.</translation> <translation id="3874164307099183178">Aktivera Google Assistent</translation> -<translation id="387531380970557479"><ph name="EXTENSION_NAME" /> har inaktiverats eftersom det innehåller skadlig programvara.</translation> <translation id="3879748587602334249">Nedladdningshanterare</translation> <translation id="3881478300875776315">Visa färre rader</translation> <translation id="3882165008614329320">Befintlig video från kamera eller fil</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Lägg till fingeravtryck</translation> <translation id="4562494484721939086">Ingen täckning</translation> <translation id="4563210852471260509">Det ursprungliga inmatningsspråket är kinesiska</translation> -<translation id="4563404051166505887">1 foto</translation> <translation id="4563880231729913339">Finger 3</translation> <translation id="4565377596337484307">Dölj lösenord</translation> <translation id="4565917129334815774">Spara systemloggar</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb index 14419b6..1da9970 100644 --- a/chrome/app/resources/generated_resources_sw.xtb +++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -2277,7 +2277,6 @@ <translation id="3748706263662799310">Ripoti hitilafu</translation> <translation id="3752582316358263300">Sawa...</translation> <translation id="3752673729237782832">Vifaa vyangu</translation> -<translation id="3752757212511661046">Ungependa kufungua Wasifu Mpya wa Kazini?</translation> <translation id="3753033997400164841">Hifadhi mara moja. Tumia kila mahali</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> yako sasa inaweza kufungua <ph name="DEVICE_TYPE" /> hii pia.</translation> <translation id="375636864092143889">Tovuti inatumia maikrofoni yako</translation> @@ -2399,7 +2398,6 @@ <translation id="3873423927483480833">Onyesha PIN</translation> <translation id="3873915545594852654">Hitilafu imetokea kwenye ARC++.</translation> <translation id="3874164307099183178">Washa programu ya Mratibu wa Google</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" kimezimwa kwa kuwa kina programu hasidi.</translation> <translation id="3879748587602334249">Kidhibiti cha vipakuliwa</translation> <translation id="3881478300875776315">Onyesha mistari michache</translation> <translation id="3882165008614329320">Video iliyopo kutoka kwenye kamera au faili</translation> @@ -2918,7 +2916,6 @@ <translation id="4562155214028662640">Ongeza Alama ya Kidole</translation> <translation id="4562494484721939086">Hakuna huduma</translation> <translation id="4563210852471260509">Lugha ingizo ya kwanza ni Kichina</translation> -<translation id="4563404051166505887">Picha moja</translation> <translation id="4563880231729913339">Kidole cha 3</translation> <translation id="4565377596337484307">Ficha nenosiri</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{<ph name="DOMAIN" /> inahitaji uhifadhi nakala ya data yako na urudishe <ph name="DEVICE_TYPE" /> leo.}other{<ph name="DOMAIN" /> inahitaji uhifadhi nakala ya data yako na urudishe <ph name="DEVICE_TYPE" /> kabla ya tarehe ya mwisho.}}</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb index efee2a6ca..540733f9 100644 --- a/chrome/app/resources/generated_resources_ta.xtb +++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">பிழையைப் புகாரளி</translation> <translation id="3752582316358263300">சரி...</translation> <translation id="3752673729237782832">எனது சாதனங்கள்</translation> -<translation id="3752757212511661046">பணிக் கணக்கை உருவாக்கவா?</translation> <translation id="3753033997400164841">ஒரு முறை சேமித்து. எங்கும் பயன்படுத்தலாம்</translation> <translation id="3755411799582650620">உங்கள் <ph name="PHONE_NAME" /> இப்போது <ph name="DEVICE_TYPE" /> ஐயும் தடைநீக்க முடியும்.</translation> <translation id="375636864092143889">தளமானது உங்கள் மைக்ரோஃபோனைப் பயன்படுத்துகிறது</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">பின்களைக் காட்டும்</translation> <translation id="3873915545594852654">ARC++ல் ஒரு சிக்கல் ஏற்பட்டது.</translation> <translation id="3874164307099183178">Google Assistantடை இயக்கு</translation> -<translation id="387531380970557479">மால்வேர் இருப்பதால் "<ph name="EXTENSION_NAME" />" முடக்கப்பட்டது.</translation> <translation id="3879748587602334249">பதிவிறக்க நிர்வாகி</translation> <translation id="3881478300875776315">குறைவான வரிகளைக் காட்டும்</translation> <translation id="3882165008614329320">கேமரா அல்லது கோப்பிலிருக்கும் வீடியோ</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">கைரேகையைச் சேர்</translation> <translation id="4562494484721939086">சேவை இல்லை</translation> <translation id="4563210852471260509">தொடக்க உள்ளீட்டு மொழி சீனம்</translation> -<translation id="4563404051166505887">1 படம்</translation> <translation id="4563880231729913339">விரல் 3</translation> <translation id="4565377596337484307">கடவுச்சொல்லை மறைக்கும்</translation> <translation id="4565917129334815774">சிஸ்டம் தொடர்பான பதிவுகளைச் சேமி</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb index b42d4b1..1b39447 100644 --- a/chrome/app/resources/generated_resources_te.xtb +++ b/chrome/app/resources/generated_resources_te.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">ఒక బగ్ను నివేదించండి</translation> <translation id="3752582316358263300">సరే...</translation> <translation id="3752673729237782832">నా పరికరాలు</translation> -<translation id="3752757212511661046">కార్యాలయ ప్రొఫైల్ను సృష్టించాలా?</translation> <translation id="3753033997400164841">ఒకసారి సేవ్ చేయండి. ప్రతి చోటా ఉపయోగించండి</translation> <translation id="3755411799582650620">మీ <ph name="PHONE_NAME" /> ఇప్పుడు ఈ <ph name="DEVICE_TYPE" />ని కూడా అన్లాక్ చేయగలదు.</translation> <translation id="375636864092143889">సైట్ మీ మైక్రోఫోన్ను ఉపయోగిస్తోంది</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">పిన్లను చూపుతుంది</translation> <translation id="3873915545594852654">ARC++కి సంబంధించి ఒక సమస్య సంభవించింది.</translation> <translation id="3874164307099183178">Google Assistantను ఆన్ చేయండి</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />"లో మాల్వేర్ ఉంది అందువల్లే డిజేబుల్ చేయబడింది.</translation> <translation id="3879748587602334249">డౌన్లోడ్ మేనేజర్</translation> <translation id="3881478300875776315">కొన్ని వరుసలను మాత్రమే చూపించు</translation> <translation id="3882165008614329320">కెమెరా లేదా ఫైల్లో ఇప్పటికే ఉన్న వీడియో</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">వేలిముద్రను జోడించు</translation> <translation id="4562494484721939086">సేవ లేదు</translation> <translation id="4563210852471260509">ప్రారంభ ఇన్పుట్ భాష చైనీస్</translation> -<translation id="4563404051166505887">1 ఫోటో</translation> <translation id="4563880231729913339">మూడో వేలు</translation> <translation id="4565377596337484307">పాస్వర్డ్ను దాచిపెట్టు</translation> <translation id="4565917129334815774">సిస్టమ్ లాగ్లను స్టోర్ చేయి</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb index ac6b183..0eb2280a 100644 --- a/chrome/app/resources/generated_resources_th.xtb +++ b/chrome/app/resources/generated_resources_th.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">รายงานข้อบกพร่อง</translation> <translation id="3752582316358263300">ตกลง...</translation> <translation id="3752673729237782832">อุปกรณ์ของฉัน</translation> -<translation id="3752757212511661046">สร้างโปรไฟล์งานไหม</translation> <translation id="3753033997400164841">บันทึกครั้งเดียว แล้วใช้ได้ทุกที่</translation> <translation id="3755411799582650620">ขณะนี้ <ph name="PHONE_NAME" /> สามารถปลดล็อก <ph name="DEVICE_TYPE" /> ได้เช่นกัน</translation> <translation id="375636864092143889">เว็บไซต์กำลังใช้ไมโครโฟนของคุณ</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">แสดง PIN</translation> <translation id="3873915545594852654">เกิดปัญหาเกี่ยวกับ ARC++</translation> <translation id="3874164307099183178">เปิด Google Assistant</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" ได้ถูกปิดใช้เนื่องจากมีมัลแวร์</translation> <translation id="3879748587602334249">Download Manager</translation> <translation id="3881478300875776315">แสดงบรรทัดน้อยลง</translation> <translation id="3882165008614329320">วิดีโอที่มีอยู่จากกล้องหรือไฟล์</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">เพิ่มลายนิ้วมือ</translation> <translation id="4562494484721939086">ไม่มีบริการ</translation> <translation id="4563210852471260509">ภาษาป้อนข้อมูลเบื้องต้นคือจีน</translation> -<translation id="4563404051166505887">1 ภาพ</translation> <translation id="4563880231729913339">นิ้วที่ 3</translation> <translation id="4565377596337484307">ซ่อนรหัสผ่าน</translation> <translation id="4565917129334815774">จัดเก็บบันทึกระบบ</translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb index c64ff35..99b9f9b 100644 --- a/chrome/app/resources/generated_resources_tr.xtb +++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Hata bildir</translation> <translation id="3752582316358263300">Tamam...</translation> <translation id="3752673729237782832">Cihazlarım</translation> -<translation id="3752757212511661046">İş Profili oluşturulsun mu?</translation> <translation id="3753033997400164841">Bir kere depolayın. Her yerde kullanın</translation> <translation id="3755411799582650620"><ph name="PHONE_NAME" /> cihazınız bu <ph name="DEVICE_TYPE" /> cihazın kilidini de açabilir.</translation> <translation id="375636864092143889">Site, mikrofonunuzu kullanıyor</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">PIN numaralarını göster</translation> <translation id="3873915545594852654">ARC++ ile ilgili bir sorun oluştu.</translation> <translation id="3874164307099183178">Google Asistan'ı aç</translation> -<translation id="387531380970557479">Kötü amaçlı yazılım içerdiğinden "<ph name="EXTENSION_NAME" />" uzantısı devre dışı bırakıldı.</translation> <translation id="3879748587602334249">İndirme yöneticisi</translation> <translation id="3881478300875776315">Daha az satır göster</translation> <translation id="3882165008614329320">Kameradan veya dosyadan mevcut video</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Parmak İzi Ekle</translation> <translation id="4562494484721939086">Hizmet yok</translation> <translation id="4563210852471260509">Başlangıç giriş dili Çince</translation> -<translation id="4563404051166505887">1 fotoğraf</translation> <translation id="4563880231729913339">3. parmak</translation> <translation id="4565377596337484307">Şifreyi gizle</translation> <translation id="4565917129334815774">Sistem günlüklerini depola</translation>
diff --git a/chrome/app/resources/generated_resources_uk.xtb b/chrome/app/resources/generated_resources_uk.xtb index 3b13a8b3..575eed3 100644 --- a/chrome/app/resources/generated_resources_uk.xtb +++ b/chrome/app/resources/generated_resources_uk.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Повідомити про помилку</translation> <translation id="3752582316358263300">ОК...</translation> <translation id="3752673729237782832">Мої пристрої</translation> -<translation id="3752757212511661046">Створити робочий профіль?</translation> <translation id="3753033997400164841">Збережіть один раз. Використовуйте на всіх пристроях</translation> <translation id="3755411799582650620">Тепер ваш <ph name="PHONE_NAME" /> може також розблоковувати цей пристрій <ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Сайт використовує мікрофон</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Показати PIN-коди</translation> <translation id="3873915545594852654">Виникла проблема з ARC++.</translation> <translation id="3874164307099183178">Увімкнути Google Асистента</translation> -<translation id="387531380970557479">Розширення "<ph name="EXTENSION_NAME" />" вимкнено, оскільки воно містить зловмисне програмне забезпечення.</translation> <translation id="3879748587602334249">Диспетчер завантажень</translation> <translation id="3881478300875776315">Показати менше рядків</translation> <translation id="3882165008614329320">Наявні відео з камери або файлу</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Додати відбиток пальця</translation> <translation id="4562494484721939086">Не працює</translation> <translation id="4563210852471260509">Початкова мова введення – китайська</translation> -<translation id="4563404051166505887">1 фотографія</translation> <translation id="4563880231729913339">Палець 3</translation> <translation id="4565377596337484307">Сховати пароль</translation> <translation id="4565917129334815774">Зберігати журнали системи</translation>
diff --git a/chrome/app/resources/generated_resources_ur.xtb b/chrome/app/resources/generated_resources_ur.xtb index b34c2d2..d682278 100644 --- a/chrome/app/resources/generated_resources_ur.xtb +++ b/chrome/app/resources/generated_resources_ur.xtb
@@ -2265,7 +2265,6 @@ <translation id="3748706263662799310">بگ کی اطلاع دیں</translation> <translation id="3752582316358263300">ٹھیک ہے…</translation> <translation id="3752673729237782832">میرے آلات</translation> -<translation id="3752757212511661046">دفتری پروفائل تخلیق کریں؟</translation> <translation id="3753033997400164841">ایک بار اسٹور کریں۔ ہر جگہ استعمال کریں</translation> <translation id="3755411799582650620">آپ کا <ph name="PHONE_NAME" /> اب اس <ph name="DEVICE_TYPE" /> کو بھی غیر مقفل کر سکتا ہے۔</translation> <translation id="375636864092143889">سائٹ آپ کا مائیکروفون استعمال کر رہی ہے</translation> @@ -2386,7 +2385,6 @@ <translation id="3873423927483480833">PINs دکھائیں</translation> <translation id="3873915545594852654">++ARC کے ساتھ ایک مسئلہ پیش آگیا۔</translation> <translation id="3874164307099183178">Google اسسٹنٹ آن کریں</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" کو غیر فعال کر دیا گیا ہے کیونکہ اس میں میلوئیر شامل ہے۔</translation> <translation id="3879748587602334249">ڈاؤن لوڈ مینیجر</translation> <translation id="3881478300875776315">قدرے کم لائنز دکھائیں</translation> <translation id="3882165008614329320">کیمرے یا فائل سے لی گئی موجودہ ویڈیو</translation> @@ -2905,7 +2903,6 @@ <translation id="4562155214028662640">فنگر پرنٹ شامل کریں</translation> <translation id="4562494484721939086">کوئی سروس نہیں</translation> <translation id="4563210852471260509">ان پٹ کی ابتدائی زبان چینی ہے</translation> -<translation id="4563404051166505887">1 تصویر</translation> <translation id="4563880231729913339">انگلی 3</translation> <translation id="4565377596337484307">پاس ورڈ چھپائیں</translation> <translation id="4565917129334815774">سسٹم لاگز اسٹور کریں</translation>
diff --git a/chrome/app/resources/generated_resources_uz.xtb b/chrome/app/resources/generated_resources_uz.xtb index 7e899b5..1ff1453 100644 --- a/chrome/app/resources/generated_resources_uz.xtb +++ b/chrome/app/resources/generated_resources_uz.xtb
@@ -2278,7 +2278,6 @@ <translation id="3748706263662799310">Xatolik haqida xabar berish</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Mening qurilmalarim</translation> -<translation id="3752757212511661046">Ish profili yaratilsinmi?</translation> <translation id="3753033997400164841">Bir marta saqlash. Doim ishlatish</translation> <translation id="3755411799582650620">Endi <ph name="PHONE_NAME" /> telefonni <ph name="DEVICE_TYPE" /> qulfdan yechishi mumkin.</translation> <translation id="375636864092143889">Sayt mikrofondan foydalanmoqda</translation> @@ -2400,7 +2399,6 @@ <translation id="3873423927483480833">PIN kodlar berkitilmasin</translation> <translation id="3873915545594852654">ARC++ ishga tushmadi.</translation> <translation id="3874164307099183178">Google Assistentni yoqish</translation> -<translation id="387531380970557479">“<ph name="EXTENSION_NAME" />” kengaytmasi faolsizlantirildi, chunki unda zararli dastur bor.</translation> <translation id="3879748587602334249">Yuklanmalar menejeri</translation> <translation id="3881478300875776315">Kamroq qatorlarni koʻrsatish</translation> <translation id="3882165008614329320">Kamera yoki galereyadan olingan video</translation> @@ -2921,7 +2919,6 @@ <translation id="4562155214028662640">Barmoq izi qo‘shish</translation> <translation id="4562494484721939086">Tarmoq topilmadi</translation> <translation id="4563210852471260509">Boshlang‘ich matn kiritish tili xitoycha</translation> -<translation id="4563404051166505887">1 ta rasm</translation> <translation id="4563880231729913339">3-barmoq</translation> <translation id="4565377596337484307">Parolni berkitish</translation> <translation id="4565577809484439917">{NUM_DAYS,plural, =1{<ph name="DOMAIN" /> maʼlumotlaringizni zaxiralash va bu <ph name="DEVICE_TYPE" />qurilmasini bugunoq qaytarishingizni talab qilmoqda.}other{<ph name="DOMAIN" /> maʼlumotlaringizni zaxiralash va bu <ph name="DEVICE_TYPE" />qurilmasini bugunoq qaytarishingizni talab qilmoqda.}}</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb index e2b498fc..bdff963 100644 --- a/chrome/app/resources/generated_resources_vi.xtb +++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -2264,7 +2264,6 @@ <translation id="3748706263662799310">Báo cáo lỗi</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Thiết bị của tôi</translation> -<translation id="3752757212511661046">Tạo hồ sơ công việc?</translation> <translation id="3753033997400164841">Lưu trữ một lần. Dùng ở mọi nơi</translation> <translation id="3755411799582650620">Giờ đây, <ph name="PHONE_NAME" /> của bạn cũng có thể mở khóa <ph name="DEVICE_TYPE" /> này.</translation> <translation id="375636864092143889">Trang web đang sử dụng micrô của bạn</translation> @@ -2385,7 +2384,6 @@ <translation id="3873423927483480833">Hiển thị mã PIN</translation> <translation id="3873915545594852654">Đã xảy ra lỗi với ARC++.</translation> <translation id="3874164307099183178">Bật Trợ lý Google</translation> -<translation id="387531380970557479">"<ph name="EXTENSION_NAME" />" đã bị vô hiệu hóa vì chứa phần mềm độc hại.</translation> <translation id="3879748587602334249">Trình quản lý tải xuống</translation> <translation id="3881478300875776315">Ẩn bớt dòng</translation> <translation id="3882165008614329320">Video hiện có từ camera hoặc tệp</translation> @@ -2904,7 +2902,6 @@ <translation id="4562155214028662640">Thêm vân tay</translation> <translation id="4562494484721939086">Không có dịch vụ</translation> <translation id="4563210852471260509">Ngôn ngữ nhập vào ban đầu là tiếng Trung</translation> -<translation id="4563404051166505887">1 ảnh</translation> <translation id="4563880231729913339">Ngón tay số 3</translation> <translation id="4565377596337484307">Ẩn mật khẩu</translation> <translation id="4565917129334815774">Lưu trữ nhật ký hệ thống</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb index c30c4b7..10d67db 100644 --- a/chrome/app/resources/generated_resources_zh-CN.xtb +++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -2260,7 +2260,6 @@ <translation id="3748706263662799310">报告错误</translation> <translation id="3752582316358263300">确定...</translation> <translation id="3752673729237782832">我的设备</translation> -<translation id="3752757212511661046">要创建工作资料?</translation> <translation id="3753033997400164841">一次储存,随时随地使用</translation> <translation id="3755411799582650620">您的“<ph name="PHONE_NAME" />”现在也可用来为此 <ph name="DEVICE_TYPE" /> 解锁。</translation> <translation id="375636864092143889">该网站正在使用您的麦克风</translation> @@ -2381,7 +2380,6 @@ <translation id="3873423927483480833">显示 PIN 码</translation> <translation id="3873915545594852654">ARC++ 出问题了。</translation> <translation id="3874164307099183178">开启 Google 助理</translation> -<translation id="387531380970557479">“<ph name="EXTENSION_NAME" />”含有恶意软件,因此已被停用。</translation> <translation id="3879748587602334249">下载管理器</translation> <translation id="3881478300875776315">隐藏部分行</translation> <translation id="3882165008614329320">来自摄像头或文件的现有视频</translation> @@ -2899,7 +2897,6 @@ <translation id="4562155214028662640">添加指纹</translation> <translation id="4562494484721939086">无服务</translation> <translation id="4563210852471260509">初始输入语言是中文</translation> -<translation id="4563404051166505887">1 张照片</translation> <translation id="4563880231729913339">手指 3</translation> <translation id="4565377596337484307">隐藏密码</translation> <translation id="4565917129334815774">存储系统日志</translation>
diff --git a/chrome/app/resources/generated_resources_zh-HK.xtb b/chrome/app/resources/generated_resources_zh-HK.xtb index 3fe29923..318aded 100644 --- a/chrome/app/resources/generated_resources_zh-HK.xtb +++ b/chrome/app/resources/generated_resources_zh-HK.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">回報錯誤</translation> <translation id="3752582316358263300">確定…</translation> <translation id="3752673729237782832">我的裝置</translation> -<translation id="3752757212511661046">要建立工作設定檔嗎?</translation> <translation id="3753033997400164841">只需儲存一次,即可在所有裝置上使用</translation> <translation id="3755411799582650620">您的 <ph name="PHONE_NAME" /> 現在也可為這部 <ph name="DEVICE_TYPE" /> 解鎖。</translation> <translation id="375636864092143889">網站正在使用您的麥克風</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">顯示 PIN</translation> <translation id="3873915545594852654">ARC++ 發生問題。</translation> <translation id="3874164307099183178">開啟「Google 助理」</translation> -<translation id="387531380970557479">由於「<ph name="EXTENSION_NAME" />」含有惡意軟件,因此已被停用。</translation> <translation id="3879748587602334249">下載管理員</translation> <translation id="3881478300875776315">顯示較少行</translation> <translation id="3882165008614329320">相機或檔案中的現有影片</translation> @@ -2903,7 +2901,6 @@ <translation id="4562155214028662640">新增指紋</translation> <translation id="4562494484721939086">不提供服務</translation> <translation id="4563210852471260509">初始輸入語言為中文</translation> -<translation id="4563404051166505887">1 張相片</translation> <translation id="4563880231729913339">手指 3</translation> <translation id="4565377596337484307">隱藏密碼</translation> <translation id="4565917129334815774">儲存系統記錄</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb index 6c50d3d..2555848 100644 --- a/chrome/app/resources/generated_resources_zh-TW.xtb +++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -2263,7 +2263,6 @@ <translation id="3748706263662799310">回報錯誤</translation> <translation id="3752582316358263300">確定...</translation> <translation id="3752673729237782832">我的裝置</translation> -<translation id="3752757212511661046">要建立工作用的設定檔嗎?</translation> <translation id="3753033997400164841">只要儲存一次,即可在所有裝置上使用。</translation> <translation id="3755411799582650620">你的 <ph name="PHONE_NAME" /> 現在也可以解鎖這台 <ph name="DEVICE_TYPE" />。</translation> <translation id="375636864092143889">網站正在使用你的麥克風</translation> @@ -2384,7 +2383,6 @@ <translation id="3873423927483480833">顯示 PIN 碼</translation> <translation id="3873915545594852654">ARC++ 發生問題。</translation> <translation id="3874164307099183178">開啟 Google 助理</translation> -<translation id="387531380970557479">「<ph name="EXTENSION_NAME" />」含有惡意軟體,因此已遭到停用。</translation> <translation id="3879748587602334249">下載管理員</translation> <translation id="3881478300875776315">顯示較少行</translation> <translation id="3882165008614329320">相機或檔案中的現有影片</translation> @@ -2902,7 +2900,6 @@ <translation id="4562155214028662640">新增指紋</translation> <translation id="4562494484721939086">不提供服務</translation> <translation id="4563210852471260509">初始輸入語言為中文</translation> -<translation id="4563404051166505887">1 張相片</translation> <translation id="4563880231729913339">手指 3</translation> <translation id="4565377596337484307">隱藏密碼</translation> <translation id="4565917129334815774">儲存系統記錄</translation>
diff --git a/chrome/app/resources/generated_resources_zu.xtb b/chrome/app/resources/generated_resources_zu.xtb index 4533c5e..bef640d 100644 --- a/chrome/app/resources/generated_resources_zu.xtb +++ b/chrome/app/resources/generated_resources_zu.xtb
@@ -2262,7 +2262,6 @@ <translation id="3748706263662799310">Bika isiphazamiso</translation> <translation id="3752582316358263300">OK...</translation> <translation id="3752673729237782832">Amadivayisi wami</translation> -<translation id="3752757212511661046">Dala Iphrofayela Yomsebenzi</translation> <translation id="3753033997400164841">Londoloza kanye. Sebenzisa yonke indawo</translation> <translation id="3755411799582650620">I-<ph name="PHONE_NAME" /> yakho manje ingavula nale-<ph name="DEVICE_TYPE" />.</translation> <translation id="375636864092143889">Isaiyithi lisebenzisa imakrofoni yakho</translation> @@ -2383,7 +2382,6 @@ <translation id="3873423927483480833">Bonisa ama-PIN</translation> <translation id="3873915545594852654">Inkinga nge-ARC++ ivelile.</translation> <translation id="3874164307099183178">Vula Umsizi we-Google</translation> -<translation id="387531380970557479">I-"<ph name="EXTENSION_NAME" />" ikhutshaziwe ngoba iqukethe uhlelo olungayilungele ikhompyutha</translation> <translation id="3879748587602334249">Isiphathi zokulayisha</translation> <translation id="3881478300875776315">Bonisa imigqa embalwa</translation> <translation id="3882165008614329320">Ividiyo ekhona kusuka kukhamera noma ifayela</translation> @@ -2901,7 +2899,6 @@ <translation id="4562155214028662640">Engeza izigxivizo zeminwe</translation> <translation id="4562494484721939086">Ayikho isevisi</translation> <translation id="4563210852471260509">Ulimi lokufaka lasekuqaleni isi-Chinese</translation> -<translation id="4563404051166505887">isithombe esi-1</translation> <translation id="4563880231729913339">Umunwe 3</translation> <translation id="4565377596337484307">Fihla iphasiwedi</translation> <translation id="4565917129334815774">Gcina amalogu wesistimu</translation>
diff --git a/chrome/app/resources/google_chrome_strings_af.xtb b/chrome/app/resources/google_chrome_strings_af.xtb index 5ea0209..8c9c7f4 100644 --- a/chrome/app/resources/google_chrome_strings_af.xtb +++ b/chrome/app/resources/google_chrome_strings_af.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome is reeds vir alle gebruikers op jou rekenaar geïnstalleer.</translation> <translation id="6338556085225130112">Dateer tans Google Chrome op</translation> <translation id="6368958679917195344">Chrome-bedryfstelsel word moontlik gemaak deur bykomende <ph name="BEGIN_LINK_CROS_OSS" />oopbron-sagteware<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Jy het met 'n werkrekening aangemeld. Wil jy graag 'n nuwe Chrome-profiel vir werk skep om jou data apart te hou?</translation> <translation id="6454142105866844106">Chrome kyk een keer per week vir ongewenste sagteware</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Dateer Google Chrome tans op (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_am.xtb b/chrome/app/resources/google_chrome_strings_am.xtb index c78372f..1102608 100644 --- a/chrome/app/resources/google_chrome_strings_am.xtb +++ b/chrome/app/resources/google_chrome_strings_am.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome ቀደም ብሎ በእርስዎ ኮምፒውተር ላይ ላሉ ተጠቃሚዎች ተጭኗል።</translation> <translation id="6338556085225130112">Google Chromeን በማዘመን ላይ</translation> <translation id="6368958679917195344">Chrome ስርዓተ ክወና በተጨማሪ <ph name="BEGIN_LINK_CROS_OSS" />ክፍት ምንጭ ሶፍትዌር<ph name="END_LINK_CROS_OSS" /> እውን ሊሆን ችሏል።</translation> -<translation id="6372315130616785175">በሥራ መለያ ገብተዋል። የእርስዎን ውሂብ ለብቻው ለይቶ ለማቆየት አዲስ የChrome መገለጫ ለሥራ መፍጠር ይፈልጋሉ?</translation> <translation id="6454142105866844106">Chrome በሳምንት አንድ ጊዜ የማይፈለጉ ሶፍትዌሮች ካሉ ይፈትሻል</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome ግንባታ</translation> <translation id="6566149418543181476">Google Chromeን በማዘመን ላይ (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ar.xtb b/chrome/app/resources/google_chrome_strings_ar.xtb index 897a796..db7bc3a 100644 --- a/chrome/app/resources/google_chrome_strings_ar.xtb +++ b/chrome/app/resources/google_chrome_strings_ar.xtb
@@ -183,7 +183,6 @@ <translation id="6291549208091401781">تم تثبيت Google Chrome من قبل لجميع المستخدمين على الكمبيوتر.</translation> <translation id="6338556085225130112">تحديث Google Chrome</translation> <translation id="6368958679917195344">أصبح نظام التشغيل Chrome متاحًا من خلال <ph name="BEGIN_LINK_CROS_OSS" />برنامج مفتوح المصدر<ph name="END_LINK_CROS_OSS" /> إضافي.</translation> -<translation id="6372315130616785175">لقد سجَّلت الدخول باستخدام حساب عمل. هل تريد إنشاء ملف شخصي جديد على Chrome للعمل حتى تُبقي بياناتك منفصلة؟</translation> <translation id="6454142105866844106">يتحقَّق Chrome من وجود أي برامج غير مرغوب فيها مرة واحدة أسبوعيًا.</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - إصدار قناة مطوري البرامج من Google Chrome</translation> <translation id="6566149418543181476">جارٍ تحديث Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_as.xtb b/chrome/app/resources/google_chrome_strings_as.xtb index 32d4bd6..85ca4141 100644 --- a/chrome/app/resources/google_chrome_strings_as.xtb +++ b/chrome/app/resources/google_chrome_strings_as.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">আপোনাৰ কম্পিউটাৰত থকা সকলো ব্যৱহাৰকাৰীৰ বাবে Google Chrome ইতিমধ্যে ইনষ্টল কৰা আছে।</translation> <translation id="6338556085225130112">Google Chrome আপডে’ট কৰি থকা হৈছে</translation> <translation id="6368958679917195344">অতিৰিক্ত <ph name="BEGIN_LINK_CROS_OSS" />মুক্ত উৎসৰ ছফ্টৱেৰ<ph name="END_LINK_CROS_OSS" />ৰ জৰিয়তে Chrome OSক ব্যৱহাৰযোগ্য কৰা হৈছে।</translation> -<translation id="6372315130616785175">আপুনি এটা কৰ্মস্থানৰ একাউণ্টেৰে ছাইন ইন কৰিছে। আপোনাৰ ডেটা পৃথক কৰি ৰাখিবলৈ আপুনি কৰ্মস্থানৰ বাবে এটা নতুন Chrome প্ৰ’ফাইল সৃষ্টি কৰিব বিচাৰেনে?</translation> <translation id="6454142105866844106">Chromeএ সপ্তাহত এবাৰকৈ অনাকাংক্ষিত ছফ্টৱেৰৰ বাবে পৰীক্ষা কৰে</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome আপডে’ট কৰি থকা হৈছে (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_az.xtb b/chrome/app/resources/google_chrome_strings_az.xtb index 3999ac2..4dce543 100644 --- a/chrome/app/resources/google_chrome_strings_az.xtb +++ b/chrome/app/resources/google_chrome_strings_az.xtb
@@ -183,7 +183,6 @@ <translation id="6291549208091401781">Google Chrome kompüterinizdəki bütün istifadəçilər üçün artıq quraşdırılıb.</translation> <translation id="6338556085225130112">Google Chrome güncəlləşir</translation> <translation id="6368958679917195344">Chrome OS əlavə <ph name="BEGIN_LINK_CROS_OSS" />açıq mənbə proqram təminatı ilə<ph name="END_LINK_CROS_OSS" /> mümkün oldu.</translation> -<translation id="6372315130616785175">İş hesabı ilə daxil olmusunuz. Datanızı ayrı saxlamaq üçün yeni Chrome İş Profili yaratmaq istərdinizmi?</translation> <translation id="6454142105866844106">Chrome arzuolunmaz proqram olub-olmadığını həftədə bir dəfə yoxlayır</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome güncəllənir (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_be.xtb b/chrome/app/resources/google_chrome_strings_be.xtb index fc675c6..6f7147b0 100644 --- a/chrome/app/resources/google_chrome_strings_be.xtb +++ b/chrome/app/resources/google_chrome_strings_be.xtb
@@ -186,7 +186,6 @@ <translation id="6291549208091401781">Google Chrome зараз усталяваны для ўсіх карыстальнікаў на камп'ютары.</translation> <translation id="6338556085225130112">Ідзе абнаўленне браўзера Google Chrome</translation> <translation id="6368958679917195344">Chrome OS працуе дзякуючы дадатковаму <ph name="BEGIN_LINK_CROS_OSS" />праграмнаму забеспячэнню з адкрытым зыходным кодам<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Вы ўвайшлі ў працоўны ўліковы запіс. Ці не хочаце стварыць новы профіль Chrome для работы, каб трымаць свае даныя асобна?</translation> <translation id="6454142105866844106">Chrome правярае наяўнасць непажаданых праграм раз у тыдзень</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" />: Google Chrome для распрацоўшчыкаў</translation> <translation id="6566149418543181476">Google Chrome абнаўляецца (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_bg.xtb b/chrome/app/resources/google_chrome_strings_bg.xtb index c2c5ba6..2cd0247 100644 --- a/chrome/app/resources/google_chrome_strings_bg.xtb +++ b/chrome/app/resources/google_chrome_strings_bg.xtb
@@ -180,7 +180,6 @@ <translation id="6291549208091401781">Google Chrome вече е инсталиран за всички потребители на компютъра ви.</translation> <translation id="6338556085225130112">Google Chrome се актуализира</translation> <translation id="6368958679917195344">Chrome OS е възможна благодарение на допълнителен <ph name="BEGIN_LINK_CROS_OSS" />софтуер с отворен код<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Влязохте със служебен профил. Искате ли да създадете в Chrome нов потребителски профил за служебни цели, за да поддържате данните си разделени?</translation> <translation id="6454142105866844106">Chrome проверява за нежелан софтуер веднъж седмично</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome се актуализира (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_bn.xtb b/chrome/app/resources/google_chrome_strings_bn.xtb index 8969540..b9466b3 100644 --- a/chrome/app/resources/google_chrome_strings_bn.xtb +++ b/chrome/app/resources/google_chrome_strings_bn.xtb
@@ -183,7 +183,6 @@ <translation id="6291549208091401781">Google Chrome ইতোমধ্যে আপনার কম্পিউটারের সকল ব্যবহারকারীর জন্য ইনস্টল করা হয়েছে।</translation> <translation id="6338556085225130112">Google Chrome আপডেট করা হচ্ছে</translation> <translation id="6368958679917195344">Chrome OS সম্ভবত অতিরিক্ত <ph name="BEGIN_LINK_CROS_OSS" />ওপেন সোর্স সফ্টওয়্যার<ph name="END_LINK_CROS_OSS" /> দিয়ে তৈরি৷</translation> -<translation id="6372315130616785175">আপনি অফিস অ্যাকাউন্ট দিয়ে সাইন-ইন করেছেন। আপনার ডেটা আলাদা রাখতে আপনি কি অফিসের জন্য একটি নতুন Chrome প্রোফাইল তৈরি করতে চান?</translation> <translation id="6454142105866844106">Chrome সপ্তাহে একবার ডিভাইসে কোনও অযাচিত সফ্টওয়্যার আছে কিনা তা চেক করে দেখে</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome আপডেট হচ্ছে (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_bs.xtb b/chrome/app/resources/google_chrome_strings_bs.xtb index eadbf09..9a79776c 100644 --- a/chrome/app/resources/google_chrome_strings_bs.xtb +++ b/chrome/app/resources/google_chrome_strings_bs.xtb
@@ -185,7 +185,6 @@ <translation id="6291549208091401781">Google Chrome je već instaliran za sve korisnike na vašem računaru.</translation> <translation id="6338556085225130112">Ažuriranje Google Chromea</translation> <translation id="6368958679917195344">Chrome OS je moguć zahvaljujući dodatnom <ph name="BEGIN_LINK_CROS_OSS" />softveru otvorenog koda<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Prijavili ste se s poslovnim računom. Želite li kreirati novi Chrome profil za posao da odvojite podatke?</translation> <translation id="6454142105866844106">Chrome jednom sedmično provjerava je li prisutan neželjeni softver</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Ažuriranje Google Chromea (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ca.xtb b/chrome/app/resources/google_chrome_strings_ca.xtb index 80711d5..3060dca6b 100644 --- a/chrome/app/resources/google_chrome_strings_ca.xtb +++ b/chrome/app/resources/google_chrome_strings_ca.xtb
@@ -178,7 +178,6 @@ <translation id="6291549208091401781">Ja tens instal·lat Google Chrome per a tots els usuaris de l'ordinador.</translation> <translation id="6338556085225130112">S'està actualitzant Google Chrome</translation> <translation id="6368958679917195344">Chrome OS és possible gràcies a <ph name="BEGIN_LINK_CROS_OSS" />programari addicional de codi obert<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Has iniciat la sessió amb un compte de la feina. Vols crear un perfil de Chrome per a la feina que et permeti mantenir les dades separades?</translation> <translation id="6454142105866844106">Chrome comprova si hi ha programari no desitjat un cop per setmana</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">S'està actualitzant Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_cs.xtb b/chrome/app/resources/google_chrome_strings_cs.xtb index 69711552..abc9bc6 100644 --- a/chrome/app/resources/google_chrome_strings_cs.xtb +++ b/chrome/app/resources/google_chrome_strings_cs.xtb
@@ -186,7 +186,6 @@ <translation id="6291549208091401781">Prohlížeč Google Chrome je na tomto počítači již nainstalován pro všechny uživatele.</translation> <translation id="6338556085225130112">Aktualizace prohlížeče Google Chrome</translation> <translation id="6368958679917195344">Chrome OS by nemohl existovat bez dalšího <ph name="BEGIN_LINK_CROS_OSS" />softwaru s otevřeným zdrojovým kódem<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Přihlásili jste se pomocí pracovního účtu. Chcete v Chromu vytvořit nový pracovní profil, aby data byla oddělená?</translation> <translation id="6454142105866844106">Chrome jednou týdně kontroluje, zda počítač neobsahuje nevyžádaný software</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Aktualizace prohlížeče Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_da.xtb b/chrome/app/resources/google_chrome_strings_da.xtb index 1f4471fa..43b0db6 100644 --- a/chrome/app/resources/google_chrome_strings_da.xtb +++ b/chrome/app/resources/google_chrome_strings_da.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome er allerede installeret for alle brugere på computeren.</translation> <translation id="6338556085225130112">Opdaterer Google Chrome</translation> <translation id="6368958679917195344">Chrome OS er lavet ved hjælp af <ph name="BEGIN_LINK_CROS_OSS" />open source-software<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Du er logget ind med en arbejdskonto. Vi du oprette en ny Chrome-profil til dit arbejde for at holde dine data adskilt?</translation> <translation id="6454142105866844106">Chrome tjekker, om du har uønsket software, én gang om ugen</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome for udviklere</translation> <translation id="6566149418543181476">Opdaterer Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_de.xtb b/chrome/app/resources/google_chrome_strings_de.xtb index 2059179..737b593 100644 --- a/chrome/app/resources/google_chrome_strings_de.xtb +++ b/chrome/app/resources/google_chrome_strings_de.xtb
@@ -178,7 +178,6 @@ <translation id="6291549208091401781">Google Chrome ist bereits für alle Nutzer auf Ihrem Computer installiert.</translation> <translation id="6338556085225130112">Google Chrome wird aktualisiert</translation> <translation id="6368958679917195344">Chrome OS wird durch zusätzliche <ph name="BEGIN_LINK_CROS_OSS" />Open-Source-Software<ph name="END_LINK_CROS_OSS" /> ermöglicht.</translation> -<translation id="6372315130616785175">Sie haben sich mit einem Arbeitskonto angemeldet. Möchten Sie ein neues Chrome-Profil für die Arbeit erstellen, um Ihre Daten getrennt zu halten?</translation> <translation id="6454142105866844106">Chrome prüft Ihr Gerät einmal pro Woche auf unerwünschte Software</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome wird aktualisiert (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_el.xtb b/chrome/app/resources/google_chrome_strings_el.xtb index fe508f3..b5c5d404 100644 --- a/chrome/app/resources/google_chrome_strings_el.xtb +++ b/chrome/app/resources/google_chrome_strings_el.xtb
@@ -183,7 +183,6 @@ <translation id="6291549208091401781">Το Google Chrome είναι ήδη εγκατεστημένο για όλους τους χρήστες στον υπολογιστή σας.</translation> <translation id="6338556085225130112">Ενημέρωση Google Chrome</translation> <translation id="6368958679917195344">Το Chrome OS έγινε πραγματικότητα χάρη στην ύπαρξη πρόσθετων <ph name="BEGIN_LINK_CROS_OSS" />λογισμικών ανοικτού κώδικα<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Συνδεθήκατε με έναν λογαριασμό εργασίας. Θέλετε να δημιουργήσετε ένα νέο προφίλ Chrome για την εργασία έτσι ώστε να διατηρείτε τα δεδομένα σας ξεχωριστά;</translation> <translation id="6454142105866844106">To Chrome ελέγχει για ανεπιθύμητο λογισμικό μία φορά την εβδομάδα.</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Ενημέρωση του Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_en-GB.xtb b/chrome/app/resources/google_chrome_strings_en-GB.xtb index 956d4e99..1a697d0 100644 --- a/chrome/app/resources/google_chrome_strings_en-GB.xtb +++ b/chrome/app/resources/google_chrome_strings_en-GB.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome is already installed for all users on your computer.</translation> <translation id="6338556085225130112">Updating Google Chrome</translation> <translation id="6368958679917195344">Chrome OS is made possible by additional <ph name="BEGIN_LINK_CROS_OSS" />open-source software<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">You signed in with a work account. Would you like to create a new Chrome profile for work to keep your data separate?</translation> <translation id="6454142105866844106">Chrome checks for unwanted software once a week</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Updating Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_es-419.xtb b/chrome/app/resources/google_chrome_strings_es-419.xtb index 0704faa..34e52c024 100644 --- a/chrome/app/resources/google_chrome_strings_es-419.xtb +++ b/chrome/app/resources/google_chrome_strings_es-419.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome ya está instalado para todos los usuarios en tu computadora.</translation> <translation id="6338556085225130112">Actualizando Google Chrome</translation> <translation id="6368958679917195344">Chrome OS es posible gracias al <ph name="BEGIN_LINK_CROS_OSS" />software de código abierto<ph name="END_LINK_CROS_OSS" /> adicional.</translation> -<translation id="6372315130616785175">Accediste con una cuenta de trabajo. ¿Quieres crear un perfil de trabajo nuevo en Chrome para mantener los datos separados?</translation> <translation id="6454142105866844106">Chrome busca software no deseado una vez a la semana</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" />: Versión para desarrolladores de Google Chrome</translation> <translation id="6566149418543181476">Actualizando Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_es.xtb b/chrome/app/resources/google_chrome_strings_es.xtb index c797086..a2cd565 100644 --- a/chrome/app/resources/google_chrome_strings_es.xtb +++ b/chrome/app/resources/google_chrome_strings_es.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome ya está instalado para todos los usuarios de tu ordenador.</translation> <translation id="6338556085225130112">Actualizando Google Chrome</translation> <translation id="6368958679917195344">Chrome OS está creado con <ph name="BEGIN_LINK_CROS_OSS" />software libre<ph name="END_LINK_CROS_OSS" /> adicional.</translation> -<translation id="6372315130616785175">Has iniciado sesión con una cuenta de trabajo. ¿Quieres crear un nuevo perfil de trabajo de Chrome para mantener tus datos de forma separada?</translation> <translation id="6454142105866844106">Chrome comprueba si hay software no deseado una vez a la semana</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> ‑ Google Chrome Dev</translation> <translation id="6566149418543181476">Actualizando Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_et.xtb b/chrome/app/resources/google_chrome_strings_et.xtb index 69a6446..98f2dea 100644 --- a/chrome/app/resources/google_chrome_strings_et.xtb +++ b/chrome/app/resources/google_chrome_strings_et.xtb
@@ -183,7 +183,6 @@ <translation id="6291549208091401781">Google Chrome on arvutisse kõigi kasutajate jaoks juba installitud.</translation> <translation id="6338556085225130112">Google Chrome'i värskendamine</translation> <translation id="6368958679917195344">Chrome OS on võimalik tänu <ph name="BEGIN_LINK_CROS_OSS" />avatud lähtekoodiga lisatarkvarale<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Logisite sisse oma töökontoga. Kas soovite luua uue Chrome'i tööprofiili, et andmed eraldi hoida?</translation> <translation id="6454142105866844106">Chrome kontrollib soovimatu tarkvara olemasolu kord nädalas</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome'i värskendamine (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_eu.xtb b/chrome/app/resources/google_chrome_strings_eu.xtb index 8099fb0..b198517 100644 --- a/chrome/app/resources/google_chrome_strings_eu.xtb +++ b/chrome/app/resources/google_chrome_strings_eu.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Ordenagailuko erabiltzaile guztientzat dago instalatuta Google Chrome.</translation> <translation id="6338556085225130112">Google Chrome eguneratzen</translation> <translation id="6368958679917195344"><ph name="BEGIN_LINK_CROS_OSS" />Kode irekiko software<ph name="END_LINK_CROS_OSS" /> gehigarriari esker da posible Chrome OS.</translation> -<translation id="6372315130616785175">Laneko kontu batekin hasi duzu saioa. Laneko profil bat sortu nahi duzu Chrome-n, datuak bereiz gordetzeko?</translation> <translation id="6454142105866844106">Chrome-k nahi ez den softwarerik baden begiratzen du astean behin</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome eguneratzen (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fa.xtb b/chrome/app/resources/google_chrome_strings_fa.xtb index 8c0652c..6e6c7b3 100644 --- a/chrome/app/resources/google_chrome_strings_fa.xtb +++ b/chrome/app/resources/google_chrome_strings_fa.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome از قبل برای همه کاربران این رایانه نصب شده است.</translation> <translation id="6338556085225130112">بهروزرسانی Google Chrome</translation> <translation id="6368958679917195344">Chrome OS با یک <ph name="BEGIN_LINK_CROS_OSS" />نرمافزار منبع آزاد<ph name="END_LINK_CROS_OSS" /> دیگر امکانپذیر است.</translation> -<translation id="6372315130616785175">با حساب کاری به سیستم وارد شدهاید. مایلید «نمایه ویژه کار Chrome» جدیدی ایجاد کنید تا دادههایتان بهصورت جداگانه نگهداری شود؟</translation> <translation id="6454142105866844106">Chrome هفتهای یکبار وجود نرمافزارهای ناخواسته را بررسی میکند</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">درحال بهروزرسانی Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fi.xtb b/chrome/app/resources/google_chrome_strings_fi.xtb index 2bb7dff..524a4c6 100644 --- a/chrome/app/resources/google_chrome_strings_fi.xtb +++ b/chrome/app/resources/google_chrome_strings_fi.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome on jo asennettuna kaikille tietokoneen käyttäjille.</translation> <translation id="6338556085225130112">Päivitetään Google Chromea.</translation> <translation id="6368958679917195344">Chrome-käyttöjärjestelmää tukee toinen <ph name="BEGIN_LINK_CROS_OSS" />avoimen lähdekoodin ohjelmisto<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Kirjauduit sisään työtilillä. Haluatko luoda uuden Chrome-profiilin pitääksesi datasi erillään?</translation> <translation id="6454142105866844106">Chrome tarkistaa ei-toivotut ohjelmistot kerran viikossa</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Päivitetään Google Chromea (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fil.xtb b/chrome/app/resources/google_chrome_strings_fil.xtb index c31c160..245a5773 100644 --- a/chrome/app/resources/google_chrome_strings_fil.xtb +++ b/chrome/app/resources/google_chrome_strings_fil.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Naka-install na ang Google Chrome para sa lahat ng user sa iyong computer.</translation> <translation id="6338556085225130112">Ina-update ang Google Chrome</translation> <translation id="6368958679917195344">Ginagawang posible ang Chrome OS ng karagdagang <ph name="BEGIN_LINK_CROS_OSS" />open source na software<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Nag-sign in ka gamit ang isang account sa trabaho. Gusto mo bang gumawa ng bagong Profile sa Chrome para sa Trabaho para mapanatiling nakahiwalay ang iyong data?</translation> <translation id="6454142105866844106">Nagsusuri ang Chrome para sa hindi gustong software nang isang beses sa isang linggo</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Ina-update ang Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fr-CA.xtb b/chrome/app/resources/google_chrome_strings_fr-CA.xtb index a0e8a8d..76ed91c2 100644 --- a/chrome/app/resources/google_chrome_strings_fr-CA.xtb +++ b/chrome/app/resources/google_chrome_strings_fr-CA.xtb
@@ -186,7 +186,6 @@ <translation id="6291549208091401781">Google Chrome est déjà installé pour tous les utilisateurs sur votre ordinateur.</translation> <translation id="6338556085225130112">Mise à jour de Google Chrome en cours…</translation> <translation id="6368958679917195344">Chrome OS fonctionne grâce à d'autres <ph name="BEGIN_LINK_CROS_OSS" />logiciels libres<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Vous vous êtes connecté à l'aide d'un compte professionnel. Voulez-vous créer un profil Chrome pour le travail afin de garder vos données distinctes?</translation> <translation id="6454142105866844106">Chrome vérifie la présence de logiciels indésirables une fois par semaine</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome pour les concepteurs</translation> <translation id="6566149418543181476">Mise à jour de Google Chrome en cours (<ph name="PROGRESS_PERCENT" />)…</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fr.xtb b/chrome/app/resources/google_chrome_strings_fr.xtb index f45643dd..79e2b27 100644 --- a/chrome/app/resources/google_chrome_strings_fr.xtb +++ b/chrome/app/resources/google_chrome_strings_fr.xtb
@@ -185,7 +185,6 @@ <translation id="6291549208091401781">Google Chrome est déjà installé pour tous les utilisateurs de votre ordinateur.</translation> <translation id="6338556085225130112">Mise à jour de Google Chrome...</translation> <translation id="6368958679917195344">Google Chrome OS fonctionne grâce à d'autres <ph name="BEGIN_LINK_CROS_OSS" />logiciels Open Source<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Vous vous êtes connecté avec un compte professionnel. Voulez-vous créer un profil Chrome pour le travail afin de séparer vos données ?</translation> <translation id="6454142105866844106">Chrome vérifie la présence de logiciels indésirables une fois par semaine</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome pour les développeurs</translation> <translation id="6566149418543181476">Mise à jour de Google Chrome (<ph name="PROGRESS_PERCENT" />)…</translation>
diff --git a/chrome/app/resources/google_chrome_strings_gl.xtb b/chrome/app/resources/google_chrome_strings_gl.xtb index f89b8dd..eebe50e 100644 --- a/chrome/app/resources/google_chrome_strings_gl.xtb +++ b/chrome/app/resources/google_chrome_strings_gl.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome xa está instalado para todos os usuarios no teu ordenador.</translation> <translation id="6338556085225130112">Actualizando Google Chrome</translation> <translation id="6368958679917195344">Chrome OS está creado con <ph name="BEGIN_LINK_CROS_OSS" />software de código aberto<ph name="END_LINK_CROS_OSS" /> adicional.</translation> -<translation id="6372315130616785175">Iniciaches sesión cunha conta de traballo. Queres crear un perfil de Chrome novo para o traballo para manter separados os datos?</translation> <translation id="6454142105866844106">Chrome comproba se hai software non desexado unha vez á semana</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> (Google Chrome para programadores)</translation> <translation id="6566149418543181476">Actualizando Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_gu.xtb b/chrome/app/resources/google_chrome_strings_gu.xtb index b70b2f7..98dac6b1 100644 --- a/chrome/app/resources/google_chrome_strings_gu.xtb +++ b/chrome/app/resources/google_chrome_strings_gu.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome, તમારા કમ્પ્યુટર પર પહેલાંથી તમામ વપરાશકર્તાઓ માટે ઇન્સ્ટૉલ કરેલ છે.</translation> <translation id="6338556085225130112">Google Chrome અપડેટ થઈ રહ્યું છે</translation> <translation id="6368958679917195344">Chrome OS વધારાના <ph name="BEGIN_LINK_CROS_OSS" />ખુલ્લા સ્ત્રોત સૉફ્ટવેર<ph name="END_LINK_CROS_OSS" /> દ્વારા શક્ય બને છે.</translation> -<translation id="6372315130616785175">તમે ઑફિસના એકાઉન્ટ વડે લૉગ ઇન કર્યું છે. તમારો ડેટા અલગ રાખવા માટે, શું તમે ઑફિસ માટે નવી Chrome પ્રોફાઇલ બનાવવા માગો છો?</translation> <translation id="6454142105866844106">Chrome વણજોઈતા સૉફ્ટવેર શોધવા માટે અઠવાડિયામાં એક વાર ચેક કરે છે</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome અપડેટ થઈ રહ્યું છે (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hi.xtb b/chrome/app/resources/google_chrome_strings_hi.xtb index e727eff..9599efb 100644 --- a/chrome/app/resources/google_chrome_strings_hi.xtb +++ b/chrome/app/resources/google_chrome_strings_hi.xtb
@@ -183,7 +183,6 @@ <translation id="6291549208091401781">Google Chrome आपके कंप्यूटर पर मौजूद सभी उपयोगकर्ताओं के लिए पहले से इंंस्टॉल है.</translation> <translation id="6338556085225130112">Google Chrome अपडेट हो रहा है</translation> <translation id="6368958679917195344">Chrome OS को अतिरिक्त <ph name="BEGIN_LINK_CROS_OSS" />ओपन सोर्स सॉफ़्टवेयर<ph name="END_LINK_CROS_OSS" /> द्वारा संभव बनाया गया है.</translation> -<translation id="6372315130616785175">आपने काम से जुड़े खाते से साइन इन किया है. क्या आप डेटा को अलग रखने के लिए, Chrome क्रोमियम पर नई प्रोफ़ाइल बनाना चाहते हैं?</translation> <translation id="6454142105866844106">Chrome हफ़्ते में एक बार अनचाहे सॉफ़्टवेयर की जांच करता है</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome डेवलपर</translation> <translation id="6566149418543181476">Google Chrome अपडेट हो रहा है (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hr.xtb b/chrome/app/resources/google_chrome_strings_hr.xtb index 7f4852fb..8d8f2ed 100644 --- a/chrome/app/resources/google_chrome_strings_hr.xtb +++ b/chrome/app/resources/google_chrome_strings_hr.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome već je instaliran za sve korisnike na računalu.</translation> <translation id="6338556085225130112">Ažuriranje Google Chromea</translation> <translation id="6368958679917195344">OS Chrome omogućen je dodatnim <ph name="BEGIN_LINK_CROS_OSS" />softverom otvorenog koda<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Prijavili ste se poslovnim računom. Želite li izraditi novi Chromeov profil za posao da bi podaci ostali odvojeni?</translation> <translation id="6454142105866844106">Chrome provjerava ima li neželjenog softvera jednom tjedno</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Ažuriranje Google Chromea (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hu.xtb b/chrome/app/resources/google_chrome_strings_hu.xtb index ea9346a..8048c55b 100644 --- a/chrome/app/resources/google_chrome_strings_hu.xtb +++ b/chrome/app/resources/google_chrome_strings_hu.xtb
@@ -178,7 +178,6 @@ <translation id="6291549208091401781">A Google Chrome már telepítve van az összes felhasználó számára a számítógépen.</translation> <translation id="6338556085225130112">A Google Chrome frissítése</translation> <translation id="6368958679917195344">A Chrome OS-hez egyéb <ph name="BEGIN_LINK_CROS_OSS" />nyílt forráskódú szoftver<ph name="END_LINK_CROS_OSS" /> is hozzájárult.</translation> -<translation id="6372315130616785175">Ön munkahelyi fiókkal jelentkezett be. Szeretne új Chrome-profilt létrehozni a munkához, hogy adatait elkülönítve tárolhassa?</translation> <translation id="6454142105866844106">A Chrome hetente egyszer keres nem kívánt szoftvereket.</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">A Google Chrome frissítése (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hy.xtb b/chrome/app/resources/google_chrome_strings_hy.xtb index 38af1f60..af626fa 100644 --- a/chrome/app/resources/google_chrome_strings_hy.xtb +++ b/chrome/app/resources/google_chrome_strings_hy.xtb
@@ -185,7 +185,6 @@ <translation id="6291549208091401781">Google Chrome-ն արդեն տեղադրված է ձեր համակարգչում բոլոր օգտատերերի համար:</translation> <translation id="6338556085225130112">Google Chrome-ը թարմացվում է</translation> <translation id="6368958679917195344">Chrome OS-ն ստեղծվել է շնորհիվ լրացուցիչ <ph name="BEGIN_LINK_CROS_OSS" />բաց կոդով ծրագրակազմի<ph name="END_LINK_CROS_OSS" />:</translation> -<translation id="6372315130616785175">Դուք մուտք եք գործել աշխատանքային հաշվով։ Ուզո՞ւմ եք ստեղծել Chrome-ի նոր աշխատանքային պրոֆիլ՝ ձեր տվյալներն առանձին պահելու համար։</translation> <translation id="6454142105866844106">Chrome-ը ստուգում է անցանկալի ծրագրերի առկայությունը շաբաթը մեկ անգամ</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome-ի թարմացում (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_id.xtb b/chrome/app/resources/google_chrome_strings_id.xtb index e6d34b5..13171bd 100644 --- a/chrome/app/resources/google_chrome_strings_id.xtb +++ b/chrome/app/resources/google_chrome_strings_id.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome sudah terpasang untuk semua pengguna di komputer Anda.</translation> <translation id="6338556085225130112">Memperbarui Google Chrome</translation> <translation id="6368958679917195344">Chrome OS terwujud karena <ph name="BEGIN_LINK_CROS_OSS" />software sumber terbuka<ph name="END_LINK_CROS_OSS" /> tambahan.</translation> -<translation id="6372315130616785175">Anda login dengan akun kerja. Ingin membuat Profil Chrome baru untuk Kerja agar data pribadi dan data kerja tetap terpisah?</translation> <translation id="6454142105866844106">Chrome memeriksa software yang tidak diinginkan seminggu sekali</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Memperbarui Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_is.xtb b/chrome/app/resources/google_chrome_strings_is.xtb index 9391402..59a3f94 100644 --- a/chrome/app/resources/google_chrome_strings_is.xtb +++ b/chrome/app/resources/google_chrome_strings_is.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome hefur þegar verið sett upp fyrir alla notendur í tölvunni.</translation> <translation id="6338556085225130112">Uppfærir Google Chrome</translation> <translation id="6368958679917195344">Chrome OS á tilvist sína að þakka öðrum <ph name="BEGIN_LINK_CROS_OSS" />opnum hugbúnaði<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Þú skráðir þig inn með vinnureikningi. Viltu búa til nýtt Chrome vinnusnið til að halda gögnunum þínum aðskildum?</translation> <translation id="6454142105866844106">Chrome leitar að óæskilegum hugbúnaði einu sinni í viku</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Uppfærir Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_it.xtb b/chrome/app/resources/google_chrome_strings_it.xtb index 3377d00a..6304e093 100644 --- a/chrome/app/resources/google_chrome_strings_it.xtb +++ b/chrome/app/resources/google_chrome_strings_it.xtb
@@ -178,7 +178,6 @@ <translation id="6291549208091401781">Google Chrome è già installato per tutti gli utenti sul computer.</translation> <translation id="6338556085225130112">Aggiornamento di Google Chrome in corso</translation> <translation id="6368958679917195344">Chrome OS è reso possibile da <ph name="BEGIN_LINK_CROS_OSS" />software open source<ph name="END_LINK_CROS_OSS" /> aggiuntivi.</translation> -<translation id="6372315130616785175">Hai effettuato l'accesso con un account di lavoro. Vuoi creare un nuovo profilo Chrome di lavoro per mantenere i tuoi dati separati?</translation> <translation id="6454142105866844106">Chrome verifica la presenza di software indesiderato una volta a settimana</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome per gli sviluppatori</translation> <translation id="6566149418543181476">Aggiornamento di Google Chrome in corso (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_iw.xtb b/chrome/app/resources/google_chrome_strings_iw.xtb index 7966aa9..ee9b3173 100644 --- a/chrome/app/resources/google_chrome_strings_iw.xtb +++ b/chrome/app/resources/google_chrome_strings_iw.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome כבר מותקן במחשב ונגיש לכל המשתמשים.</translation> <translation id="6338556085225130112">מעדכן את Google Chrome</translation> <translation id="6368958679917195344">השימוש במערכת ההפעלה של Chrome מתאפשר באמצעות <ph name="BEGIN_LINK_CROS_OSS" />תוכנת קוד פתוח<ph name="END_LINK_CROS_OSS" /> נוספת.</translation> -<translation id="6372315130616785175">נכנסת באמצעות חשבון לצורכי עבודה. האם ברצונך ליצור פרופיל Chrome חדש לצורכי עבודה כדי לשמור את הנתונים שלך בנפרד?</translation> <translation id="6454142105866844106">Chrome מבצע בדיקה לאיתור תוכנות לא רצויות פעם בשבוע</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome בגירסת פיתוח</translation> <translation id="6566149418543181476">מעדכן את Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ja.xtb b/chrome/app/resources/google_chrome_strings_ja.xtb index 366558d9..a7e6b23 100644 --- a/chrome/app/resources/google_chrome_strings_ja.xtb +++ b/chrome/app/resources/google_chrome_strings_ja.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome は既にパソコンのすべてのユーザー対してインストールされています。</translation> <translation id="6338556085225130112">Google Chrome を更新しています</translation> <translation id="6368958679917195344">Chrome OS は、さらに追加の<ph name="BEGIN_LINK_CROS_OSS" />オープンソース ソフトウェア<ph name="END_LINK_CROS_OSS" />によって実現しました。</translation> -<translation id="6372315130616785175">仕事用アカウントでログインしています。データを分けて保持するよう仕事用の Chrome プロフィールを新しく作成しますか?</translation> <translation id="6454142105866844106">Chrome で週 1 回、望ましくないソフトウェアがないか確認します</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome を更新しています(<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ka.xtb b/chrome/app/resources/google_chrome_strings_ka.xtb index f909bf4..8ae1cf914 100644 --- a/chrome/app/resources/google_chrome_strings_ka.xtb +++ b/chrome/app/resources/google_chrome_strings_ka.xtb
@@ -186,7 +186,6 @@ <translation id="6291549208091401781">Google Chrome უკვე დაინსტალირებულია თქვენი კომპიუტერის ყველა მომხმარებლისთვის.</translation> <translation id="6338556085225130112">მიმდინარეობს Google Chrome-ის განახლება</translation> <translation id="6368958679917195344">Chrome OS არსებობს დამატებითი <ph name="BEGIN_LINK_CROS_OSS" />ღია წყაროს პროგრამული უზრუნველყოფის<ph name="END_LINK_CROS_OSS" /> წყალობით.</translation> -<translation id="6372315130616785175">თქვენ შეხვედით სამსახურის ანგარიშით. გსურთ, მონაცემების განსაცალკევებლად, შექმნათ ახალი Chrome პროფილი სამსახურისთვის?</translation> <translation id="6454142105866844106">Chrome კვირაში ერთხელ ამოწმებს არასასურველ პროგრამულ უზრუნველყოფას</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> — Google Chrome Dev</translation> <translation id="6566149418543181476">მიმდინარეობს Google Chrome-ის განახლება (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_kk.xtb b/chrome/app/resources/google_chrome_strings_kk.xtb index 09da9b69..d794aca 100644 --- a/chrome/app/resources/google_chrome_strings_kk.xtb +++ b/chrome/app/resources/google_chrome_strings_kk.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome компьютердегі барлық пайдаланушылар үшін әлдеқашан орнатылған.</translation> <translation id="6338556085225130112">Google Chrome браузерін жаңарту</translation> <translation id="6368958679917195344">Chrome OS қосымша <ph name="BEGIN_LINK_CROS_OSS" />ашық дереккөз бағдарламалық жасақтамасы<ph name="END_LINK_CROS_OSS" /> арқылы жасалды.</translation> -<translation id="6372315130616785175">Жұмыс есептік жазбасымен кірдіңіз. Деректеріңізді бөлек сақтау үшін жұмысқа жаңа Chrome профилін жасағыңыз келе ме?</translation> <translation id="6454142105866844106">Chrome браузері қажетсіз бағдарламалық құралдың бар-жоғын аптасына бір рет тексереді.</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome әзірлеуші нұсқасы</translation> <translation id="6566149418543181476">Google Chrome жаңартылуда (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_km.xtb b/chrome/app/resources/google_chrome_strings_km.xtb index dfd194b..0c29032 100644 --- a/chrome/app/resources/google_chrome_strings_km.xtb +++ b/chrome/app/resources/google_chrome_strings_km.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome ត្រូវបានដំឡើងរួចហើយសម្រាប់អ្នកប្រើទាំងអស់នៅលើកុំព្យូទ័ររបស់អ្នក។</translation> <translation id="6338556085225130112">កំពុងអាប់ដេត Google Chrome</translation> <translation id="6368958679917195344">Chrome OS អាចបង្កើតឡើងដោយ <ph name="BEGIN_LINK_CROS_OSS" />កម្មវិធីប្រភពបើកចំហរ<ph name="END_LINK_CROS_OSS" /> បន្ថែម។</translation> -<translation id="6372315130616785175">អ្នកបានចូលដោយប្រើគណនីការងារ។ តើអ្នកចង់បង្កើតកម្រងព័ត៌មាន Chrome ថ្មីសម្រាប់ការងារ ដើម្បីរក្សាទុកទិន្នន័យរបស់អ្នកដាច់ដោយឡែកដែរទេ?</translation> <translation id="6454142105866844106">Chrome ពិនិត្យរកមើលកម្មវិធីដែលមិនចង់បានម្ដងក្នុងមួយសប្ដាហ៍</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">កំពុងអាប់ដេត Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_kn.xtb b/chrome/app/resources/google_chrome_strings_kn.xtb index 5577cf9..e71f4439 100644 --- a/chrome/app/resources/google_chrome_strings_kn.xtb +++ b/chrome/app/resources/google_chrome_strings_kn.xtb
@@ -180,7 +180,6 @@ <translation id="6291549208091401781">ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ನಲ್ಲಿನ ಎಲ್ಲ ಬಳಕೆದಾರರಿಗೆ ಈಗಾಗಲೇ Google Chrome ಸ್ಥಾಪಿತವಾಗಿದೆ.</translation> <translation id="6338556085225130112">Google Chrome ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ</translation> <translation id="6368958679917195344">ಹೆಚ್ಚುವರಿ <ph name="BEGIN_LINK_CROS_OSS" />ಓಪನ್ ಸೋರ್ಸ್ ಸಾಫ್ಟ್ವೇರ್<ph name="END_LINK_CROS_OSS" /> ನಿಂದ Chrome OS ಸಾಕಾರಗೊಂಡಿದೆ.</translation> -<translation id="6372315130616785175">ನೀವು ಕೆಲಸದ ಖಾತೆಯೊಂದಿಗೆ ಸೈನ್ ಇನ್ ಆಗಿದ್ದೀರಿ. ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಪ್ರತ್ಯೇಕವಾಗಿಡಲು, ಕೆಲಸಕ್ಕಾಗಿ ಹೊಸ Chrome ಪ್ರೊಫೈಲ್ ಅನ್ನು ರಚಿಸಲು ನೀವು ಬಯಸುವಿರಾ?</translation> <translation id="6454142105866844106">Chrome ಅನಗತ್ಯ ಸಾಫ್ಟ್ವೇರ್ಗಳನ್ನು ವಾರಕ್ಕೊಮ್ಮೆ ಪರಿಶೀಲಿಸುತ್ತದೆ</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ko.xtb b/chrome/app/resources/google_chrome_strings_ko.xtb index cbf3fd2..1065cd6 100644 --- a/chrome/app/resources/google_chrome_strings_ko.xtb +++ b/chrome/app/resources/google_chrome_strings_ko.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">컴퓨터에 Chrome이 이미 설치되어 있으며 모든 사용자가 사용할 수 있습니다.</translation> <translation id="6338556085225130112">Chrome 업데이트 중</translation> <translation id="6368958679917195344">Chrome OS는 추가 <ph name="BEGIN_LINK_CROS_OSS" />오픈소스 소프트웨어<ph name="END_LINK_CROS_OSS" />를 사용했습니다.</translation> -<translation id="6372315130616785175">직장 계정으로 로그인했습니다. 데이터를 별도로 유지하기 위해 직장 Chrome 프로필을 새로 만드시겠습니까?</translation> <translation id="6454142105866844106">Chrome에서 일주일에 한 번 원치 않는 소프트웨어가 있는지 확인합니다.</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - 개발자용 Chrome</translation> <translation id="6566149418543181476">Chrome 업데이트 중(<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ky.xtb b/chrome/app/resources/google_chrome_strings_ky.xtb index 84f543a..e60bc57 100644 --- a/chrome/app/resources/google_chrome_strings_ky.xtb +++ b/chrome/app/resources/google_chrome_strings_ky.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome компьютериңиздеги бардык колдонуучулар үчүн орнотулуп коюлган.</translation> <translation id="6338556085225130112">Google Chrome жаңыртылууда</translation> <translation id="6368958679917195344">Chrome OS кошумча <ph name="BEGIN_LINK_CROS_OSS" />ачык программасы<ph name="END_LINK_CROS_OSS" /> менен иштетилди.</translation> -<translation id="6372315130616785175">Жумуш аккаунту менен кирдиңиз. Жумуш үчүн Chrome профилин түзүп, маалыматты өзүнчө сактагыңыз келеби?</translation> <translation id="6454142105866844106">Chrome кооптуу программаларды аптасына бир жолу текшерет</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome жаңыртылууда (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_lo.xtb b/chrome/app/resources/google_chrome_strings_lo.xtb index da8d4f20..906eb75b 100644 --- a/chrome/app/resources/google_chrome_strings_lo.xtb +++ b/chrome/app/resources/google_chrome_strings_lo.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">ຕິດຕັ້ງ Google Chrome ສຳລັບຜູ້ໃຊ້ທຸກຄົນໃນຄອມພິວເຕີຂອງທ່ານແລ້ວ.</translation> <translation id="6338556085225130112">ກໍາລັງອັບເດດ Google Chrome</translation> <translation id="6368958679917195344">Chrome OS ເຮັດໃຫ້ເປັນໄປໄດ້ໂດຍ <ph name="BEGIN_LINK_CROS_OSS" />ຊອບແວ open source<ph name="END_LINK_CROS_OSS" /> ເພີ່ມເຕີມ.</translation> -<translation id="6372315130616785175">ທ່ານເຂົ້າສູ່ລະບົບດ້ວຍບັນຊີບ່ອນເຮັດວຽກ. ທ່ານຕ້ອງການສ້າງໂປຣໄຟລ໌ Chrome ໃໝ່ສຳລັບວຽກເພື່ອເກັບຮັກສາຂໍ້ມູນຂອງທ່ານແຍກໄວ້ຕ່າງຫາກ.</translation> <translation id="6454142105866844106">Chrome ຈະກວດຫາຊອບແວທີ່ບໍ່ຕ້ອງການໜຶ່ງຄັ້ງຕໍ່ອາທິດ</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">ກຳລັງອັບເດດ Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_lt.xtb b/chrome/app/resources/google_chrome_strings_lt.xtb index e6475a9..297ceb8 100644 --- a/chrome/app/resources/google_chrome_strings_lt.xtb +++ b/chrome/app/resources/google_chrome_strings_lt.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">„Google Chrome“ jau įdiegta visiems kompiuterio naudotojams.</translation> <translation id="6338556085225130112">Atnaujinama „Google Chrome“</translation> <translation id="6368958679917195344">„Chrome“ OS galima naudojant papildomą <ph name="BEGIN_LINK_CROS_OSS" />atvirojo šaltinio programinę įrangą<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Prisijungėte naudodami darbo paskyrą. Ar norėtumėte sukurti naują „Chrome“ darbo profilį, kad duomenys būtų saugomi atskirai?</translation> <translation id="6454142105866844106">Kartą per savaitę „Chrome“ tikrina, ar nėra nepageidaujamos programinės įrangos</translation> <translation id="6515495397637126556">„<ph name="PAGE_TITLE" />“ – „Google Chrome Dev“</translation> <translation id="6566149418543181476">Atnaujinama „Google Chrome“ (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_lv.xtb b/chrome/app/resources/google_chrome_strings_lv.xtb index a42ea47..7b3134a6 100644 --- a/chrome/app/resources/google_chrome_strings_lv.xtb +++ b/chrome/app/resources/google_chrome_strings_lv.xtb
@@ -183,7 +183,6 @@ <translation id="6291549208091401781">Pārlūks Google Chrome jau ir instalēts visiem jūsu datora lietotājiem.</translation> <translation id="6338556085225130112">Notiek Google Chrome atjaunināšana</translation> <translation id="6368958679917195344">Chrome OS ir kļuvusi iespējama, pateicoties papildu <ph name="BEGIN_LINK_CROS_OSS" />atklātā pirmkoda programmatūrai<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Jūs pierakstījāties ar darba kontu. Vai vēlaties pārlūkā Chrome izveidot jaunu darba profilu, lai glabātu datus atsevišķi?</translation> <translation id="6454142105866844106">Chrome meklē nevēlamu programmatūru vienreiz nedēļā.</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> — Google Chrome izstrādātāju versija</translation> <translation id="6566149418543181476">Notiek Google Chrome atjaunināšana (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_mk.xtb b/chrome/app/resources/google_chrome_strings_mk.xtb index c70e907..029bff5 100644 --- a/chrome/app/resources/google_chrome_strings_mk.xtb +++ b/chrome/app/resources/google_chrome_strings_mk.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome веќе е инсталиран за сите корисници на вашиот компјутер.</translation> <translation id="6338556085225130112">Се ажурира Google Chrome</translation> <translation id="6368958679917195344">Chrome OS е овозможен од дополнителен <ph name="BEGIN_LINK_CROS_OSS" />софтвер со отворен код<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Се најавивте со работна сметка. Дали би сакале да создадете нов профил за работа на Chrome за да ги чувате податоците одделно?</translation> <translation id="6454142105866844106">Chrome проверува дали има несакан софтвер еднаш неделно</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome се ажурира (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ml.xtb b/chrome/app/resources/google_chrome_strings_ml.xtb index 8f3465a..7810f3d 100644 --- a/chrome/app/resources/google_chrome_strings_ml.xtb +++ b/chrome/app/resources/google_chrome_strings_ml.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">നിങ്ങളുടെ കമ്പ്യൂട്ടറിലെ എല്ലാ ഉപയോക്താക്കൾക്കുമായി Google Chrome നിലവിൽ ഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു.</translation> <translation id="6338556085225130112">Google Chrome അപ്ഡേറ്റുചെയ്യുന്നു</translation> <translation id="6368958679917195344">അനുബന്ധ <ph name="BEGIN_LINK_CROS_OSS" />ഓപ്പണ് ഉറവിട സോഫ്റ്റ്വെയർ<ph name="END_LINK_CROS_OSS" /> ഉപയോഗിച്ചാണ് Chrome OS നിര്മ്മിച്ചിരിക്കുന്നത്.</translation> -<translation id="6372315130616785175">നിങ്ങൾ ഒരു ഔദ്യോഗിക അക്കൗണ്ട് ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്തു. നിങ്ങളുടെ ഡാറ്റ പ്രത്യേകം വേർതിരിച്ച് സൂക്ഷിക്കാൻ ഔദ്യോഗികാവശ്യത്തിനുള്ള പുതിയൊരു Chrome പ്രൊഫൈൽ സൃഷ്ടിക്കണോ?</translation> <translation id="6454142105866844106">ആഴ്ചയിൽ ഒരിക്കൽ അനാവശ്യ സോഫ്റ്റ്വെയർ കണ്ടെത്താൻ Chrome പരിശോധിക്കുന്നു</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome അപ്ഡേറ്റുചെയ്യുന്നു, (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_mn.xtb b/chrome/app/resources/google_chrome_strings_mn.xtb index 41579ab..647b44f 100644 --- a/chrome/app/resources/google_chrome_strings_mn.xtb +++ b/chrome/app/resources/google_chrome_strings_mn.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome-г таны компьютерийн бүх хэрэглэгчид суулгасан.</translation> <translation id="6338556085225130112">Google Chrome-г шинэчилж байна</translation> <translation id="6368958679917195344">Chrome OS-ийг нэмэлт <ph name="BEGIN_LINK_CROS_OSS" /> нээлттэй эхийн программ хангамжаар ажиллуулж байна <ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Та ажлын бүртгэлээр нэвтэрсэн. Та өгөгдлөө тусад нь хадгалахын тулд ажилд зориулан шинэ Chrome-н профайл үүсгэмээр байна уу?</translation> <translation id="6454142105866844106">Chrome хүсээгүй програм хангамжийг долоо хоногт нэг удаа шалгадаг</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Дев</translation> <translation id="6566149418543181476">Google Chrome-г шинэчилж байна (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_mr.xtb b/chrome/app/resources/google_chrome_strings_mr.xtb index 4293eb92..30365fe 100644 --- a/chrome/app/resources/google_chrome_strings_mr.xtb +++ b/chrome/app/resources/google_chrome_strings_mr.xtb
@@ -185,7 +185,6 @@ <translation id="6291549208091401781">तुमच्या कॉंप्युटरवरील सर्व वापरकर्त्यांसाठी Google Chrome आधीच इंस्टॉल केला आहे.</translation> <translation id="6338556085225130112">Google Chrome अपडेट होत आहे</translation> <translation id="6368958679917195344"> Chrome OS अतिरिक्त <ph name="BEGIN_LINK_CROS_OSS" />मुक्त स्रोत सॉफ्टवेअर<ph name="END_LINK_CROS_OSS" /> द्वारे शक्य झाले आहे.</translation> -<translation id="6372315130616785175">तुम्ही ऑफिस खाते वापरून साइन इन केले आहे. तुमचा डेटा स्वतंत्र ठेवण्यासाठी तुम्हाला कामासाठी नवीन Chrome प्रोफाइल तयार करायची आहे का?</translation> <translation id="6454142105866844106">Chrome आठवड्यातून एकदा नकोसे सॉफ्टवेअर शोधण्यासाठी तपासणी करते</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome डेव्हलपर</translation> <translation id="6566149418543181476">Google Chrome अपडेट करीत आहे (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ms.xtb b/chrome/app/resources/google_chrome_strings_ms.xtb index ee7f4b66..415b7dd 100644 --- a/chrome/app/resources/google_chrome_strings_ms.xtb +++ b/chrome/app/resources/google_chrome_strings_ms.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome telah dipasang untuk semua pengguna pada komputer anda.</translation> <translation id="6338556085225130112">Mengemas kini Google Chrome</translation> <translation id="6368958679917195344">OS Chrome menjadi kenyataan dengan <ph name="BEGIN_LINK_CROS_OSS" />perisian sumber terbuka<ph name="END_LINK_CROS_OSS" /> tambahan.</translation> -<translation id="6372315130616785175">Anda dilog masuk dengan akaun kerja. Adakah anda mahu membuat Profil Chrome untuk Kerja yang baharu untuk mengasingkan data anda?</translation> <translation id="6454142105866844106">Chrome menyemak perisian yang tidak diingini seminggu sekali</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Mengemas kini Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_my.xtb b/chrome/app/resources/google_chrome_strings_my.xtb index c2f6a87..94e5566c 100644 --- a/chrome/app/resources/google_chrome_strings_my.xtb +++ b/chrome/app/resources/google_chrome_strings_my.xtb
@@ -105,7 +105,7 @@ <translation id="386202838227397562">ကျေးဇူးပြုပြီး Google Chrome ဝင်ဒိုးများကို ပိတ်ပြီ ထပ်စမ်းပါ။</translation> <translation id="3865754807470779944">Chrome ဗားရှင်း <ph name="PRODUCT_VERSION" /> ကို ထည့်သွင်းလိုက်သည်</translation> <translation id="3873044882194371212">Chrome ရုပ်ဖျက်ဝင်းဒိုးတွင် လင့်ခ်ကို ဖွင့်ရန်</translation> -<translation id="3879568094278837081">ဤ space ၏ ဖွင့်ကြည့်ထားသည့်မှတ်တမ်းဒေတာကို ဤစက်မှ ဖျက်လိုက်မည်။ ဒေတာကို ပြန်လည်ရယူရန် အဖြစ် Chrome သို့ လက်မှတ်ထိုးဝင်ပါ</translation> +<translation id="3879568094278837081">ဤ space ၏ ဖွင့်ကြည့်ထားသည့်မှတ်တမ်းဒေတာကို ဤစက်မှ ဖျက်လိုက်မည်။ ဒေတာကို ပြန်လည်ရယူရန် အောက်ပါဖြင့် Chrome သို့ လက်မှတ်ထိုးဝင်ပါ</translation> <translation id="3889417619312448367">Google Chrome ကို ဖြုတ်ရန်</translation> <translation id="4050175100176540509">အရေးကြီးလုံခြုံရေးဆိုင်ရာဖွံ့ဖြိုးတိုးတက်မှုများနှင့် အင်္ဂါရပ် အသစ်များအား နောက်ဆုံးပေါ် ဗားရှင်းဖြင့် ရရှိနိုင်ပါသည်။</translation> <translation id="4053720452172726777">Google Chrome ကို စိတ်ကြိုက် ပြုပြင်ရန် နှင့် ထိန်းချုပ်ရန်</translation> @@ -187,7 +187,6 @@ <translation id="6291549208091401781">သင့်ကွန်ပျူတာပေါ်ရှိ အသုံးပြုသူများအတွက် Google Chrome ကို ထည့်သွင်းထားပြီးဖြစ်ပါသည်။</translation> <translation id="6338556085225130112">Google Chrome ကို အပ်ဒိတ်လုပ်နေသည်</translation> <translation id="6368958679917195344">Chrome OS ကို ထပ်ဖြည့်ပေးခဲ့သည့် <ph name="BEGIN_LINK_CROS_OSS" />အခမဲ့ ရင်းမြစ် ဆော့ဝဲ<ph name="END_LINK_CROS_OSS" />များဖြင့် အားဖြည့်ပေးထားသည်။</translation> -<translation id="6372315130616785175">အလုပ်သုံးအကောင့်ဖြင့် သင်လက်မှတ်ထိုးဝင်ခဲ့သည်။ သင့်ဒေတာကို ခွဲထားရန်အတွက် အလုပ်သုံး Chrome ပရိုဖိုင်အသစ်တစ်ခု ပြုလုပ်လိုသလား။</translation> <translation id="6454142105866844106">မလိုချင်သောဆော့ဖ်ဝဲကို Chrome က တစ်ပတ်တစ်ကြိမ် စစ်ဆေးသည်</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome ကို အပ်ဒိတ်လုပ်နေသည် (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ne.xtb b/chrome/app/resources/google_chrome_strings_ne.xtb index f04448e..4b66001c 100644 --- a/chrome/app/resources/google_chrome_strings_ne.xtb +++ b/chrome/app/resources/google_chrome_strings_ne.xtb
@@ -183,7 +183,6 @@ <translation id="6291549208091401781">तपाईँको कम्प्युटरमा पहिले नै सबै प्रयोगकर्ताहरूका लागि Google Chrome को स्थापना गरिएको छ।</translation> <translation id="6338556085225130112">Google Chrome लाई अद्यावधिक गर्दै</translation> <translation id="6368958679917195344">Chrome OS अतिरिक्त <ph name="BEGIN_LINK_CROS_OSS" /> खुला स्रोत सफ्टवेयर <ph name="END_LINK_CROS_OSS" /> बाट सम्भव भएको हो ।</translation> -<translation id="6372315130616785175">तपाईंले कार्य खाता प्रयोग गरी साइन इन गर्नुभयो। तपाईं कार्यसम्बन्धी आफ्नो डेटा छुट्टै राख्न Chrome को नयाँ प्रोफाइल बनाउन चाहनुहुन्छ?</translation> <translation id="6454142105866844106">Chrome ले हप्तामा एक पटक अवाञ्छित सफ्टवेयर छन् कि छैनन् भनी जाँच गर्छ</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome लाई अद्यावधिक गर्दै (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_nl.xtb b/chrome/app/resources/google_chrome_strings_nl.xtb index 49f1c3f..6b52c89b 100644 --- a/chrome/app/resources/google_chrome_strings_nl.xtb +++ b/chrome/app/resources/google_chrome_strings_nl.xtb
@@ -184,7 +184,6 @@ <translation id="6291549208091401781">Google Chrome is al geïnstalleerd voor alle gebruikers op je computer.</translation> <translation id="6338556085225130112">Google Chrome updaten</translation> <translation id="6368958679917195344">Chrome OS wordt mogelijk gemaakt door aanvullende <ph name="BEGIN_LINK_CROS_OSS" />opensource-software<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Je bent ingelogd met een werkaccount. Wil je een nieuw Chrome-profiel voor je werk maken zodat je je gegevens gescheiden kunt houden?</translation> <translation id="6454142105866844106">Chrome checkt één keer per week op ongewenste software</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome updaten (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_no.xtb b/chrome/app/resources/google_chrome_strings_no.xtb index 97517ff..bf62cc0 100644 --- a/chrome/app/resources/google_chrome_strings_no.xtb +++ b/chrome/app/resources/google_chrome_strings_no.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome er allerede installert for alle brukerne på datamaskinen din.</translation> <translation id="6338556085225130112">Oppdaterer Google Chrome</translation> <translation id="6368958679917195344">Chrome OS muliggjøres av <ph name="BEGIN_LINK_CROS_OSS" />tilleggsprogramvare med åpen kildekode<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Du har logget på med en jobbkonto. Vil du opprette en ny Chrome-profil for arbeid for å holde dataene dine atskilt?</translation> <translation id="6454142105866844106">Chrome sjekker om du har uønsket programvare, én gang i uken</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome for utviklere</translation> <translation id="6566149418543181476">Oppdaterer Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_or.xtb b/chrome/app/resources/google_chrome_strings_or.xtb index d339c92..e57d9d1bb 100644 --- a/chrome/app/resources/google_chrome_strings_or.xtb +++ b/chrome/app/resources/google_chrome_strings_or.xtb
@@ -186,7 +186,6 @@ <translation id="6291549208091401781">ଆପଣଙ୍କ କମ୍ପ୍ୟୁଟର୍ରେ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ Google Chrome ପୂର୍ବରୁ ଇନ୍ଷ୍ଟଲ୍ ଅଛି।</translation> <translation id="6338556085225130112">Google Chrome ଅପ୍ଡେଟ୍ ହେଉଛି</translation> <translation id="6368958679917195344">Chrome OS ଅତିରିକ୍ତ <ph name="BEGIN_LINK_CROS_OSS" />ମୁକ୍ତ ଉତ୍ସ ସଫ୍ଟୱେୟାର୍ <ph name="END_LINK_CROS_OSS" /> ଦ୍ୱାରା ସମ୍ଭବପର ହୋଇଛି।</translation> -<translation id="6372315130616785175">ଆପଣ ଏକ କାର୍ଯ୍ୟସ୍ଥଳୀ ଆକାଉଣ୍ଟ ସହ ସାଇନ୍ ଇନ୍ କରିଛନ୍ତି। ଆପଣ ଆପଣଙ୍କ ଡାଟାକୁ ଅଲଗା ରଖିବା ପାଇଁ କାର୍ଯ୍ୟସ୍ଥଳୀ ନିମନ୍ତେ ଏକ ନୂଆ Chrome ପ୍ରୋଫାଇଲ୍ ତିଆରି କରିବାକୁ ପସନ୍ଦ କରିବେ?</translation> <translation id="6454142105866844106">Chrome ସପ୍ତାହକୁ ଥରେ ଅଦରକାରୀ ସଫ୍ଟୱେରର ଯାଞ୍ଚ କରେ</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome ଅପ୍ଡେଟ୍ ହେଉଛି (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_pa.xtb b/chrome/app/resources/google_chrome_strings_pa.xtb index 96ed632..42bd730c 100644 --- a/chrome/app/resources/google_chrome_strings_pa.xtb +++ b/chrome/app/resources/google_chrome_strings_pa.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome ਤੁਹਾਡੇ ਕੰਪਿਊਟਰ 'ਤੇ ਪਹਿਲਾਂ ਹੀ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਲਈ ਸਥਾਪਤ ਕੀਤਾ ਗਿਆ ਹੈ।</translation> <translation id="6338556085225130112">Google Chrome ਨੂੰ ਅੱਪਡੇਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ</translation> <translation id="6368958679917195344">Chrome OS ਵਾਧੂ <ph name="BEGIN_LINK_CROS_OSS" />ਖੁੱਲ੍ਹਾ ਸਰੋਤ ਸਾਫ਼ਟਵੇਅਰ<ph name="END_LINK_CROS_OSS" /> ਵੱਲੋਂ ਸੰਭਵ ਬਣਾਇਆ ਗਿਆ ਹੈ।</translation> -<translation id="6372315130616785175">ਤੁਸੀਂ ਕਾਰਜ ਖਾਤੇ ਨਾਲ ਸਾਈਨ-ਇਨ ਹੋਏ। ਕੀ ਤੁਸੀਂ ਆਪਣੇ ਡਾਟੇ ਨੂੰ ਵੱਖਰਾ ਰੱਖਣ ਲਈ ਕਾਰਜ ਵਾਸਤੇ ਨਵਾਂ Chrome ਪ੍ਰੋਫਾਈਲ ਬਣਾਉਣਾ ਚਾਹੋਗੇ?</translation> <translation id="6454142105866844106">Chrome ਹਫ਼ਤੇ ਵਿੱਚ ਇੱਕ ਵਾਰ ਅਣਚਾਹੇ ਸਾਫ਼ਟਵੇਅਰ ਲਈ ਜਾਂਚ ਕਰਦਾ ਹੈ</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome ਅੱਪਡੇਟ ਹੋ ਰਿਹਾ ਹੈ (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_pl.xtb b/chrome/app/resources/google_chrome_strings_pl.xtb index 020b96b..714b01b 100644 --- a/chrome/app/resources/google_chrome_strings_pl.xtb +++ b/chrome/app/resources/google_chrome_strings_pl.xtb
@@ -178,7 +178,6 @@ <translation id="6291549208091401781">Google Chrome jest już zainstalowany dla wszystkich użytkowników tego komputera.</translation> <translation id="6338556085225130112">Aktualizuję Google Chrome</translation> <translation id="6368958679917195344">Opracowanie systemu operacyjnego Chrome było możliwe dzięki dodatkowemu <ph name="BEGIN_LINK_CROS_OSS" />oprogramowaniu typu open source<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Używasz konta do pracy. Czy chcesz utworzyć nowy profil Chrome do pracy, by przechowywać dane oddzielnie?</translation> <translation id="6454142105866844106">Raz w tygodniu Chrome sprawdza, czy nie masz zainstalowanego niechcianego oprogramowania</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Aktualizuję Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_pt-BR.xtb b/chrome/app/resources/google_chrome_strings_pt-BR.xtb index 340118a..04ee8c42 100644 --- a/chrome/app/resources/google_chrome_strings_pt-BR.xtb +++ b/chrome/app/resources/google_chrome_strings_pt-BR.xtb
@@ -178,7 +178,6 @@ <translation id="6291549208091401781">O Google Chrome já está instalado para todos os usuários do seu computador.</translation> <translation id="6338556085225130112">Atualizando o Google Chrome</translation> <translation id="6368958679917195344">O sistema operacional do Chrome tornou-se possível graças a um <ph name="BEGIN_LINK_CROS_OSS" />software de código aberto<ph name="END_LINK_CROS_OSS" /> adicional.</translation> -<translation id="6372315130616785175">Você fez login com uma conta de trabalho. Quer criar um novo perfil do Chrome para trabalho e manter seus dados separados?</translation> <translation id="6454142105866844106">O Chrome verifica se há softwares indesejados uma vez por semana</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" />: Google Chrome Dev</translation> <translation id="6566149418543181476">Atualizando o Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_pt-PT.xtb b/chrome/app/resources/google_chrome_strings_pt-PT.xtb index 73c03aa..2c24f07 100644 --- a/chrome/app/resources/google_chrome_strings_pt-PT.xtb +++ b/chrome/app/resources/google_chrome_strings_pt-PT.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">O Google Chrome já está instalado para todos os utilizadores no seu computador.</translation> <translation id="6338556085225130112">A atualizar o Google Chrome…</translation> <translation id="6368958679917195344">O Chrome OS é possível através de <ph name="BEGIN_LINK_CROS_OSS" />software de código aberto<ph name="END_LINK_CROS_OSS" /> adicional.</translation> -<translation id="6372315130616785175">Iniciou sessão com uma conta profissional. Pretende criar um novo perfil do Chrome para trabalho para manter os seus dados separados?</translation> <translation id="6454142105866844106">O Chrome verifica a existência de software indesejável uma vez por semana.</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">A atualizar o Google Chrome (<ph name="PROGRESS_PERCENT" />)…</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ro.xtb b/chrome/app/resources/google_chrome_strings_ro.xtb index 42e7ea02..2f3644d4 100644 --- a/chrome/app/resources/google_chrome_strings_ro.xtb +++ b/chrome/app/resources/google_chrome_strings_ro.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome este instalat deja pentru toți utilizatorii de pe computerul tău.</translation> <translation id="6338556085225130112">Google Chrome se actualizează</translation> <translation id="6368958679917195344">Sistemul de operare Chrome este posibil datorită unui <ph name="BEGIN_LINK_CROS_OSS" />software open source<ph name="END_LINK_CROS_OSS" /> suplimentar.</translation> -<translation id="6372315130616785175">Te-ai conectat cu un cont de serviciu. Vrei să creezi un profil Chrome pentru serviciu ca să păstrezi datele separat?</translation> <translation id="6454142105866844106">Chrome verifică dacă există software nedorit o dată pe săptămână</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome se actualizează (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ru.xtb b/chrome/app/resources/google_chrome_strings_ru.xtb index b2a2af1..936596b5 100644 --- a/chrome/app/resources/google_chrome_strings_ru.xtb +++ b/chrome/app/resources/google_chrome_strings_ru.xtb
@@ -178,7 +178,6 @@ <translation id="6291549208091401781">Google Chrome уже установлен для всех пользователей вашего компьютера</translation> <translation id="6338556085225130112">Обновление Google Chrome…</translation> <translation id="6368958679917195344">Своим появлением Chrome OS обязана дополнительному <ph name="BEGIN_LINK_CROS_OSS" />программному обеспечению с открытым исходным кодом<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Вы вошли в рабочий аккаунт. Хотите создать для него отдельный профиль Chrome?</translation> <translation id="6454142105866844106">Chrome проверяет наличие нежелательного ПО раз в неделю</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome для разработчиков</translation> <translation id="6566149418543181476">Обновление Google Chrome (<ph name="PROGRESS_PERCENT" />)…</translation>
diff --git a/chrome/app/resources/google_chrome_strings_si.xtb b/chrome/app/resources/google_chrome_strings_si.xtb index bd5ec16..ef1daee1 100644 --- a/chrome/app/resources/google_chrome_strings_si.xtb +++ b/chrome/app/resources/google_chrome_strings_si.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">ඔබේ පරිගණකය මත සියලුම පරිශීලකයින් සඳහා Google Chrome දැනටමත් ස්ථාපනය කර ඇත.</translation> <translation id="6338556085225130112">Google Chrome යාවත්කාලීන කරමින්</translation> <translation id="6368958679917195344">Chrome OS යතාර්තයක් බවට පත්කරන වෙනත් <ph name="BEGIN_LINK_CROS_OSS" />විවෘත කේත මෘදුකාංග<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">ඔබ කාර්යාල ගිණුමක් සමගින් පුරා ඇත. ඔබගේ දත්ත වෙන් වෙන්ව තබා ගැනීම සඳහා කාර්යාලය සඳහා නව Chrome පැතිකඩක් තැනීමට ඔබ කැමතිද?</translation> <translation id="6454142105866844106">සතියකට වරක් අනවශ්ය මෘදුකාංග සඳහා Chrome පරික්ෂා කරයි</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome යාවත්කාලීන කරමින් (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_sk.xtb b/chrome/app/resources/google_chrome_strings_sk.xtb index b379b7d..3c18c56b 100644 --- a/chrome/app/resources/google_chrome_strings_sk.xtb +++ b/chrome/app/resources/google_chrome_strings_sk.xtb
@@ -184,7 +184,6 @@ <translation id="6291549208091401781">Google Chrome už majú nainštalovaný všetci používatelia na vašom počítači.</translation> <translation id="6338556085225130112">Chrome sa aktualizuje</translation> <translation id="6368958679917195344">Chrome OS mohol vzniknúť vďaka ďalšiemu <ph name="BEGIN_LINK_CROS_OSS" />softvéru s otvoreným zdrojom<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Prihlásili ste sa pracovným účtom. Chcete v Chrome vytvoriť nový pracovný profil a udržať tak svoje údaje oddelené?</translation> <translation id="6454142105866844106">Chrome kontroluje prítomnosť nechceného softvéru raz za týždeň</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Aktualizuje sa Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_sl.xtb b/chrome/app/resources/google_chrome_strings_sl.xtb index 9a9d248..6e269fe 100644 --- a/chrome/app/resources/google_chrome_strings_sl.xtb +++ b/chrome/app/resources/google_chrome_strings_sl.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome je že nameščen za vse uporabnike v računalniku.</translation> <translation id="6338556085225130112">Posodabljanje Google Chroma</translation> <translation id="6368958679917195344">Sistem Chrome OS uporablja dodatno <ph name="BEGIN_LINK_CROS_OSS" />odprtokodno programsko opremo<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Prijavili ste se s službenim računom. Ali želite v Chromu ustvariti nov službeni profil, da bodo podatki ločeni?</translation> <translation id="6454142105866844106">Chrome enkrat tedensko preveri, ali je nameščena neželena programska oprema</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> različica Google Chroma za razvijalce</translation> <translation id="6566149418543181476">Posodabljanje Google Chroma (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_sq.xtb b/chrome/app/resources/google_chrome_strings_sq.xtb index 99f2c52..3933e60 100644 --- a/chrome/app/resources/google_chrome_strings_sq.xtb +++ b/chrome/app/resources/google_chrome_strings_sq.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome është i instaluar tashmë për të gjithë përdoruesit në kompjuterin tënd.</translation> <translation id="6338556085225130112">Po përditëson Google Chrome</translation> <translation id="6368958679917195344">Sistemi operativ Chrome bëhet i mundur nga softueri shtesë <ph name="BEGIN_LINK_CROS_OSS" />me burim të hapur<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">U identifikove me një llogari pune. Dëshiron të krijosh një "Profil të ri Chrome për biznesin" për t'i mbajtur të dhënat e tua të ndara?</translation> <translation id="6454142105866844106">Chrome kontrollon për softuerë të padëshiruar një herë në javë</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Po përditëson Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_sr-Latn.xtb b/chrome/app/resources/google_chrome_strings_sr-Latn.xtb index d22d0a8..9147702a 100644 --- a/chrome/app/resources/google_chrome_strings_sr-Latn.xtb +++ b/chrome/app/resources/google_chrome_strings_sr-Latn.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome je već instaliran za sve korisnike na računaru.</translation> <translation id="6338556085225130112">Ažuriranje Google Chrome-a</translation> <translation id="6368958679917195344">Chrome OS je moguć zahvaljujući dodatnom <ph name="BEGIN_LINK_CROS_OSS" />softver otvorenog koda<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Prijavljeni ste pomoću poslovnog naloga. Da li želite da napravite nov Chrome poslovni profil da bi podaci ostali odvojeni?</translation> <translation id="6454142105866844106">Chrome proverava da li je prisutan neželjeni softver jednom nedeljno</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Programerska verzija Google Chrome-a</translation> <translation id="6566149418543181476">Ažuriranje Google Chrome-a (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_sr.xtb b/chrome/app/resources/google_chrome_strings_sr.xtb index 16425887e..69d4955 100644 --- a/chrome/app/resources/google_chrome_strings_sr.xtb +++ b/chrome/app/resources/google_chrome_strings_sr.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome је већ инсталиран за све кориснике на рачунару.</translation> <translation id="6338556085225130112">Ажурирање Google Chrome-а</translation> <translation id="6368958679917195344">Chrome OС je могућ захваљујући додатном <ph name="BEGIN_LINK_CROS_OSS" />софтвер отвореног кода<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Пријављени сте помоћу пословног налога. Да ли желите да направите нов Chrome пословни профил да би подаци остали одвојени?</translation> <translation id="6454142105866844106">Chrome проверава да ли је присутан нежељени софтвер једном недељно</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Програмерска верзија Google Chrome-а</translation> <translation id="6566149418543181476">Ажурирање Google Chrome-а (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_sv.xtb b/chrome/app/resources/google_chrome_strings_sv.xtb index 4c8c6e8e..4475625 100644 --- a/chrome/app/resources/google_chrome_strings_sv.xtb +++ b/chrome/app/resources/google_chrome_strings_sv.xtb
@@ -188,7 +188,6 @@ <translation id="6338556085225130112">Uppdaterar Google Chrome </translation> <translation id="6368958679917195344">Chrome OS fungerar tack vare <ph name="BEGIN_LINK_CROS_OSS" />ytterligare program med öppen källkod<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Du har loggat in med ett jobbkonto. Vill du skapa en ny Chrome-profil för jobbet och hålla uppgifterna åtskilda?</translation> <translation id="6454142105866844106">Chrome söker efter oönskad programvara en gång i veckan</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome uppdateras (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_sw.xtb b/chrome/app/resources/google_chrome_strings_sw.xtb index 8bf232f..db021d1 100644 --- a/chrome/app/resources/google_chrome_strings_sw.xtb +++ b/chrome/app/resources/google_chrome_strings_sw.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Tayari Google Chrome imesakinishwa kwa watumiaji wote kwenye kompyuta yako.</translation> <translation id="6338556085225130112">Inasasisha Google Chrome</translation> <translation id="6368958679917195344">Chrome OS imewezeshwa na programu ya ziada ya <ph name="BEGIN_LINK_CROS_OSS" />programu huria<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Umeingia ukitumia akaunti ya kazini. Ungependa kufungua Wasifu mpya wa Kikazi kwenye Chrome ili utenganishe data yako?</translation> <translation id="6454142105866844106">Chrome hukagua kama kuna programu isiyotakikana mara moja kwa wiki</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome ya Wasanidi Programu</translation> <translation id="6566149418543181476">Inasasisha Google Chrome <ph name="PROGRESS_PERCENT" /></translation>
diff --git a/chrome/app/resources/google_chrome_strings_ta.xtb b/chrome/app/resources/google_chrome_strings_ta.xtb index c0ba2f1..0bb4d6e 100644 --- a/chrome/app/resources/google_chrome_strings_ta.xtb +++ b/chrome/app/resources/google_chrome_strings_ta.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">உங்கள் கம்ப்யூட்டரில் ஏற்கனவே எல்லாப் பயனர்களுக்கும் Google Chrome நிறுவப்பட்டுள்ளது.</translation> <translation id="6338556085225130112">Google Chromeஐப் புதுப்பிக்கிறது</translation> <translation id="6368958679917195344">கூடுதலான <ph name="BEGIN_LINK_CROS_OSS" />ஓப்பன் சோர்ஸ் மென்பொருள்களால்<ph name="END_LINK_CROS_OSS" /> Chrome OS ஐ உருவாக்குவது சாத்தியமானது.</translation> -<translation id="6372315130616785175">பணிக் கணக்கின் மூலம் உள்நுழைந்துள்ளீர்கள். உங்கள் தரவைத் தனிப்பட்டதாக வைத்திருக்கும் வகையில் பணிக்கான புதிய Chrome சுயவிவரத்தை உருவாக்க விரும்புகிறீர்களா?</translation> <translation id="6454142105866844106">தேவையற்ற மென்பொருள் உள்ளதா என Chrome வாரம் ஒருமுறை சரிபார்க்கும்</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chromeஐப் புதுப்பிக்கிறது (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_te.xtb b/chrome/app/resources/google_chrome_strings_te.xtb index b69c6ef4..b96e9ff 100644 --- a/chrome/app/resources/google_chrome_strings_te.xtb +++ b/chrome/app/resources/google_chrome_strings_te.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">మీ కంప్యూటర్లోని వినియోగదారులందరికీ Google Chrome ఇప్పటికే ఇన్స్టాల్ చేయబడింది.</translation> <translation id="6338556085225130112">Google Chromeని నవీకరిస్తోంది</translation> <translation id="6368958679917195344">అదనపు <ph name="BEGIN_LINK_CROS_OSS" />ఓపన్ సోర్స్ సాఫ్ట్వేర్<ph name="END_LINK_CROS_OSS" />పై Chrome OS ఎంతగానో ఆధారపడుతుంది.</translation> -<translation id="6372315130616785175">మీ కార్యాలయ ఖాతాతో సైన్ ఇన్ చేశారు. కార్యాలయం కోసం మీ డేటాను విడిగా ఉంచడానికి కొత్త Chrome ప్రొఫైల్ను సృష్టించాలనుకొంటున్నారా?</translation> <translation id="6454142105866844106">అవాంఛిత సాఫ్ట్వేర్ ఏదైనా ఉందా? అని వారానికి ఒకసారి Chromium తనిఖీ చేస్తుంది.</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome నవీకరించబడుతోంది (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_th.xtb b/chrome/app/resources/google_chrome_strings_th.xtb index 2db228a38..4ebb10e 100644 --- a/chrome/app/resources/google_chrome_strings_th.xtb +++ b/chrome/app/resources/google_chrome_strings_th.xtb
@@ -178,7 +178,6 @@ <translation id="6291549208091401781">มีการติดตั้ง Google Chrome สำหรับผู้ใช้ทุกคนบนคอมพิวเตอร์ของคุณแล้ว</translation> <translation id="6338556085225130112">กำลังอัปเดต Google Chrome</translation> <translation id="6368958679917195344">Chrome OS เกิดขึ้นได้ด้วยการสนับสนุนจาก<ph name="BEGIN_LINK_CROS_OSS" />ซอฟต์แวร์โอเพนซอร์ส<ph name="END_LINK_CROS_OSS" />เพิ่มเติม</translation> -<translation id="6372315130616785175">คุณลงชื่อเข้าใช้ด้วยบัญชีงาน ต้องการสร้างโปรไฟล์ Chrome สำหรับงานรายการใหม่เพื่อเก็บข้อมูลแยกไว้ต่างหากไหม</translation> <translation id="6454142105866844106">Chrome จะตรวจหาซอฟต์แวร์ไม่พึงประสงค์สัปดาห์ละครั้ง</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">กำลังอัปเดต Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_tr.xtb b/chrome/app/resources/google_chrome_strings_tr.xtb index 839978b..3a988df8 100644 --- a/chrome/app/resources/google_chrome_strings_tr.xtb +++ b/chrome/app/resources/google_chrome_strings_tr.xtb
@@ -181,7 +181,6 @@ <translation id="6291549208091401781">Google Chrome zaten bilgisayarınızdaki tüm kullanıcılar için yüklendi.</translation> <translation id="6338556085225130112">Google Chrome güncelleniyor</translation> <translation id="6368958679917195344">Chrome OS, ek <ph name="BEGIN_LINK_CROS_OSS" />açık kaynak yazılımlardan<ph name="END_LINK_CROS_OSS" /> yararlanılarak geliştirilmiştir.</translation> -<translation id="6372315130616785175">İş hesabıyla oturum açtınız. Verilerinizi ayrı tutmak için İş amaçlı yeni bir Chrome Profili oluşturmak ister misiniz?</translation> <translation id="6454142105866844106">Chrome, istenmeyen yazılımları haftada bir kontrol eder</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome güncelleniyor (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_uk.xtb b/chrome/app/resources/google_chrome_strings_uk.xtb index d6c5279e..c8ad899 100644 --- a/chrome/app/resources/google_chrome_strings_uk.xtb +++ b/chrome/app/resources/google_chrome_strings_uk.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">Google Chrome уже встановлено для всіх користувачів на вашому комп’ютері.</translation> <translation id="6338556085225130112">Оновлення Google Chrome</translation> <translation id="6368958679917195344">ОС Chrome стала можливою завдяки додатковому <ph name="BEGIN_LINK_CROS_OSS" />програмному забезпеченню з відкритим кодом<ph name="END_LINK_CROS_OSS" />.</translation> -<translation id="6372315130616785175">Ви ввійшли в корпоративний обліковий запис. Створити новий робочий профіль Chrome, щоб зберігати дані окремо?</translation> <translation id="6454142105866844106">Chrome перевіряє пристрій на наявність небажаного програмного забезпечення один раз на тиждень</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Версія Google Chrome для розробників</translation> <translation id="6566149418543181476">Google Chrome оновлюється (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_ur.xtb b/chrome/app/resources/google_chrome_strings_ur.xtb index 3c5c7ff..9562dbb 100644 --- a/chrome/app/resources/google_chrome_strings_ur.xtb +++ b/chrome/app/resources/google_chrome_strings_ur.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">Google Chrome پہلے سے ہی آپ کے کمپیوٹر پر سبھی صارفین کیلئے انسٹال ہے۔</translation> <translation id="6338556085225130112">Google Chrome کو اپ ڈیٹ کیا جا رہا ہے</translation> <translation id="6368958679917195344">Chrome OS کو اضافی <ph name="BEGIN_LINK_CROS_OSS" />اوپن سورس سافٹ ویئر<ph name="END_LINK_CROS_OSS" /> کے ذریعے ممکن بنایا جاتا ہے۔</translation> -<translation id="6372315130616785175">آپ نے دفتری اکاؤنٹ کے ساتھ سائن ان کیا ہے۔ کیا آپ اپنے ڈیٹا کو الگ رکھنے کی خاطر دفتر کے لئے ایک نئی Chrome پروفائل تخلیق چاہیں گے؟</translation> <translation id="6454142105866844106">Chrome ہفتے میں ایک بار غیر مطلوبہ سافٹ ویئر کو چیک کرتا ہے</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome کو اپ ڈیٹ کیا جا رہا ہے (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_uz.xtb b/chrome/app/resources/google_chrome_strings_uz.xtb index 5aeaebb..ab5dc00 100644 --- a/chrome/app/resources/google_chrome_strings_uz.xtb +++ b/chrome/app/resources/google_chrome_strings_uz.xtb
@@ -184,7 +184,6 @@ <translation id="6291549208091401781">Google Chrome allaqachon kompyuterdagi barcha foydalanuvchilar uchun o‘rnatilgan.</translation> <translation id="6338556085225130112">Google Chrome yangilanmoqda</translation> <translation id="6368958679917195344">Chrome OS paydo bo‘lishida qo‘shimcha <ph name="BEGIN_LINK_CROS_OSS" />ochiq kodli dasturiy ta'minotlarning<ph name="END_LINK_CROS_OSS" /> katta o‘rni bor.</translation> -<translation id="6372315130616785175">Ishchi hisobingiz bilan kirgansiz. Maʼlumotlaringizni alohida saqlash maqsadida ish uchun yangi Chrome profilini yaratishni istaysizmi?</translation> <translation id="6454142105866844106">Chrome haftada bir marta zararli dasturlar mavjudligini tekshiradi</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Google Chrome yangilanmoqda (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_vi.xtb b/chrome/app/resources/google_chrome_strings_vi.xtb index 73e7ed9..0f0f286 100644 --- a/chrome/app/resources/google_chrome_strings_vi.xtb +++ b/chrome/app/resources/google_chrome_strings_vi.xtb
@@ -183,7 +183,6 @@ <translation id="6291549208091401781">Google Chrome đã được cài đặt cho tất cả người dùng trên máy tính của bạn.</translation> <translation id="6338556085225130112">Đang cập nhật Google Chrome</translation> <translation id="6368958679917195344">Chrome OS trở nên khả thi là nhờ <ph name="BEGIN_LINK_CROS_OSS" />phần mềm nguồn mở<ph name="END_LINK_CROS_OSS" /> bổ sung.</translation> -<translation id="6372315130616785175">Bạn đang đăng nhập bằng tài khoản công việc. Bạn có muốn tạo Hồ sơ Chrome mới dành cho Công việc để lưu giữ dữ liệu riêng biệt không?</translation> <translation id="6454142105866844106">Chrome kiểm tra để phát hiện phần mềm không mong muốn một lần một tuần</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome dành cho nhà phát triển</translation> <translation id="6566149418543181476">Đang cập nhật Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zh-CN.xtb b/chrome/app/resources/google_chrome_strings_zh-CN.xtb index e46478e..174b2441 100644 --- a/chrome/app/resources/google_chrome_strings_zh-CN.xtb +++ b/chrome/app/resources/google_chrome_strings_zh-CN.xtb
@@ -179,7 +179,6 @@ <translation id="6291549208091401781">已为您计算机上的所有用户安装 Google Chrome。</translation> <translation id="6338556085225130112">正在更新 Google Chrome</translation> <translation id="6368958679917195344">Chrome 操作系统的问世还有其他<ph name="BEGIN_LINK_CROS_OSS" />开放源代码软件<ph name="END_LINK_CROS_OSS" />的一份功劳。</translation> -<translation id="6372315130616785175">您已使用工作帐号登录。想创建一份新的 Chrome 工作资料来单独保存您的数据吗?</translation> <translation id="6454142105866844106">Chrome 会以每周 1 次的频率检查是否有垃圾软件</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome 开发者版</translation> <translation id="6566149418543181476">正在更新 Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zh-HK.xtb b/chrome/app/resources/google_chrome_strings_zh-HK.xtb index e549fc9..4eb35cb 100644 --- a/chrome/app/resources/google_chrome_strings_zh-HK.xtb +++ b/chrome/app/resources/google_chrome_strings_zh-HK.xtb
@@ -186,7 +186,6 @@ <translation id="6291549208091401781">電腦上的所有使用者均安裝了 Google Chrome。</translation> <translation id="6338556085225130112">正在更新 Google Chrome</translation> <translation id="6368958679917195344">Chrome 作業系統的開發全賴其他<ph name="BEGIN_LINK_CROS_OSS" />開放原始碼軟件<ph name="END_LINK_CROS_OSS" />協助才得以面世。</translation> -<translation id="6372315130616785175">您已使用公司帳戶登入。要建立新的公司 Chrome 設定檔以分開保留資料嗎?</translation> <translation id="6454142105866844106">Chrome 每星期會檢查 1 次,查看有否垃圾軟件</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome 開發人員版</translation> <translation id="6566149418543181476">正在更新 Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zh-TW.xtb b/chrome/app/resources/google_chrome_strings_zh-TW.xtb index 7c8a481..8735a35c 100644 --- a/chrome/app/resources/google_chrome_strings_zh-TW.xtb +++ b/chrome/app/resources/google_chrome_strings_zh-TW.xtb
@@ -181,7 +181,6 @@ <translation id="6291549208091401781">電腦上的所有使用者都已經安裝 Google Chrome 了。</translation> <translation id="6338556085225130112">正在更新 Google Chrome</translation> <translation id="6368958679917195344">Chrome 作業系統藉助了其他<ph name="BEGIN_LINK_CROS_OSS" />開放原始碼軟體<ph name="END_LINK_CROS_OSS" />的相關技術才得以問世。</translation> -<translation id="6372315130616785175">你已使用公司帳戶登入。要建立新的工作用 Chrome 設定檔以分開保留資料嗎?</translation> <translation id="6454142105866844106">Chrome 每週檢查一次垃圾軟體</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome 開發人員版</translation> <translation id="6566149418543181476">正在更新 Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zu.xtb b/chrome/app/resources/google_chrome_strings_zu.xtb index 6531cc693..a69517bd 100644 --- a/chrome/app/resources/google_chrome_strings_zu.xtb +++ b/chrome/app/resources/google_chrome_strings_zu.xtb
@@ -187,7 +187,6 @@ <translation id="6291549208091401781">I-Google Chrome isivele ifakelwe bonke abasebenzisi kukhompuyutha yakho.</translation> <translation id="6338556085225130112">Ibuyekeza i-Google Chrome</translation> <translation id="6368958679917195344">I-Chrome OS yenziwa yenzeke nge-<ph name="BEGIN_LINK_CROS_OSS" />softhiwe yelayisense evulekile<ph name="END_LINK_CROS_OSS" /> engeziwe.</translation> -<translation id="6372315130616785175">Ungene ngemvume nge-akhawunti yomsebenzi. Ingabe ungathanda ukudala Iphrofayela Yomsebenzi ye-Chrome entsha ukugcina idatha yakho yehlukile?</translation> <translation id="6454142105866844106">I-Chrome ihlola isofthiwe engafuneki kanye ngeviki</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6566149418543181476">Ibuyekeza i-Google Chrome (<ph name="PROGRESS_PERCENT" />)</translation>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index f64bada..b86fb5f 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -953,6 +953,9 @@ <message name="IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_WARNING" desc="Warning shown to the user to inform them that Google Cloud Print will no longer be supported."> Google Cloud Print will no longer be supported after December 31 </message> + <message name="IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_FULL_WARNING" desc="Warning shown to the user to inform them that Google Cloud Print will no longer be supported. Same as above, with the addition of the learn more link."> + Google Cloud Print will no longer be supported after December 31. <ph name="BEGIN_LINK"><a target="_blank" href="$1"></ph>Learn more<ph name="END_LINK"></a></ph> + </message> <message name="IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_WARNING_ENTERPRISE" desc="Warning shown to users managed by enterprise policy to inform them that Google Cloud Print will no longer be supported."> Google Cloud Print will no longer be supported after December 31. Contact your administrator. </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_FULL_WARNING.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_FULL_WARNING.png.sha1 new file mode 100644 index 0000000..bd2bbed5 --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_FULL_WARNING.png.sha1
@@ -0,0 +1 @@ +6e3be5b68c4153050b9695a5fab2014c3a36eec1 \ No newline at end of file
diff --git a/chrome/app/theme/default_100_percent/common/safety_tip_lookalike_illustration_dark.png b/chrome/app/theme/default_100_percent/common/safety_tip_lookalike_illustration_dark.png index adb8515..9322c455 100644 --- a/chrome/app/theme/default_100_percent/common/safety_tip_lookalike_illustration_dark.png +++ b/chrome/app/theme/default_100_percent/common/safety_tip_lookalike_illustration_dark.png Binary files differ
diff --git a/chrome/app/theme/default_100_percent/common/safety_tip_lookalike_illustration_light.png b/chrome/app/theme/default_100_percent/common/safety_tip_lookalike_illustration_light.png index 8190921..ebf1eac 100644 --- a/chrome/app/theme/default_100_percent/common/safety_tip_lookalike_illustration_light.png +++ b/chrome/app/theme/default_100_percent/common/safety_tip_lookalike_illustration_light.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/safety_tip_lookalike_illustration_dark.png b/chrome/app/theme/default_200_percent/common/safety_tip_lookalike_illustration_dark.png index 5f93196..bce5c63e1 100644 --- a/chrome/app/theme/default_200_percent/common/safety_tip_lookalike_illustration_dark.png +++ b/chrome/app/theme/default_200_percent/common/safety_tip_lookalike_illustration_dark.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/safety_tip_lookalike_illustration_light.png b/chrome/app/theme/default_200_percent/common/safety_tip_lookalike_illustration_light.png index e49d4b6..051d585 100644 --- a/chrome/app/theme/default_200_percent/common/safety_tip_lookalike_illustration_light.png +++ b/chrome/app/theme/default_200_percent/common/safety_tip_lookalike_illustration_light.png Binary files differ
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 34f8f27..1238196 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -15,6 +15,7 @@ import("//chrome/browser/buildflags.gni") import("//chrome/browser/downgrade/buildflags.gni") import("//chrome/common/features.gni") +import("//chrome/services/machine_learning/features.gni") import("//components/captive_portal/core/features.gni") import("//components/feed/features.gni") import("//components/nacl/features.gni") @@ -1240,6 +1241,8 @@ "predictors/predictors_enums.h", "predictors/predictors_features.cc", "predictors/predictors_features.h", + "predictors/predictors_switches.cc", + "predictors/predictors_switches.h", "predictors/prefetch_manager.cc", "predictors/prefetch_manager.h", "predictors/proxy_lookup_client_impl.cc", @@ -1491,6 +1494,8 @@ "sessions/chrome_serialized_navigation_driver.h", "sessions/chrome_tab_restore_service_client.cc", "sessions/chrome_tab_restore_service_client.h", + "sessions/closed_tab_cache.cc", + "sessions/closed_tab_cache.h", "sessions/restore_on_startup_policy_handler.cc", "sessions/restore_on_startup_policy_handler.h", "sessions/session_common_utils.cc", @@ -1818,6 +1823,7 @@ "//chrome/common", "//chrome/common:buildflags", "//chrome/services/file_util/public/mojom", + "//chrome/services/machine_learning:machine_learning_tflite_buildflags", "//components/account_id", "//components/autofill/core/browser", "//components/nacl/common:buildflags", @@ -2176,6 +2182,21 @@ "//ui/web_dialogs", ] + if (build_with_tflite_lib) { + sources += [ + "tflite_experiment/tflite_experiment_keyed_service.cc", + "tflite_experiment/tflite_experiment_keyed_service.h", + "tflite_experiment/tflite_experiment_keyed_service_factory.cc", + "tflite_experiment/tflite_experiment_keyed_service_factory.h", + "tflite_experiment/tflite_experiment_observer.cc", + "tflite_experiment/tflite_experiment_observer.h", + "tflite_experiment/tflite_experiment_switches.cc", + "tflite_experiment/tflite_experiment_switches.h", + ] + + deps += [ "//chrome/services/machine_learning:machine_learning" ] + } + if (is_posix || is_fuchsia) { sources += [ "download/trusted_sources_manager_posix.cc", @@ -3379,6 +3400,8 @@ "nearby_sharing/share_target.cc", "nearby_sharing/share_target.h", "nearby_sharing/share_target_discovered_callback.h", + "nearby_sharing/share_target_info.cc", + "nearby_sharing/share_target_info.h", "nearby_sharing/transfer_metadata.cc", "nearby_sharing/transfer_metadata.h", "nearby_sharing/transfer_metadata_builder.cc", @@ -4781,6 +4804,7 @@ ] deps += [ "//components/printing/browser", + "//components/printing/common:mojo_interfaces", "//components/services/print_compositor/public/cpp", "//components/services/print_compositor/public/mojom", "//printing", @@ -4829,8 +4853,6 @@ "printing/pwg_raster_converter.h", ] - deps += [ "//components/printing/common:mojo_interfaces" ] - if (is_win) { sources += [ "printing/print_dialog_cloud_win.cc",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 3ed8ded..a030162 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -374,6 +374,7 @@ "+third_party/metrics_proto", "+third_party/widevine/cdm/buildflags.h", "+third_party/widevine/cdm/widevine_cdm_common.h", + "+chrome/services/machine_learning", # Code under //ash should be accessed via its public API. See //ash/README.md. "-ash",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 973fb02..d95c972c 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -261,15 +261,6 @@ const unsigned kOsAura = kOsWin | kOsLinux | kOsCrOS; #endif // USE_AURA || OS_ANDROID -const FeatureEntry::Choice kTouchEventFeatureDetectionChoices[] = { - {flags_ui::kGenericExperimentChoiceDisabled, "", ""}, - {flags_ui::kGenericExperimentChoiceEnabled, - switches::kTouchEventFeatureDetection, - switches::kTouchEventFeatureDetectionEnabled}, - {flags_ui::kGenericExperimentChoiceAutomatic, - switches::kTouchEventFeatureDetection, - switches::kTouchEventFeatureDetectionAuto}}; - #if defined(USE_AURA) const FeatureEntry::Choice kPullToRefreshChoices[] = { {flags_ui::kGenericExperimentChoiceDefault, "", ""}, @@ -1387,9 +1378,15 @@ const FeatureEntry::FeatureParam kPromoBrowserCommandUnknownCommandParam[] = { {features::kPromoBrowserCommandIdParam, "0"}}; +const FeatureEntry::FeatureParam + kPromoBrowserCommandOpenSafetyCheckCommandParam[] = { + {features::kPromoBrowserCommandIdParam, "1"}}; const FeatureEntry::FeatureVariation kPromoBrowserCommandsVariations[] = { {"- Unknown Command", kPromoBrowserCommandUnknownCommandParam, base::size(kPromoBrowserCommandUnknownCommandParam), + "t4237555" /* variation_id */}, + {"- Open Safety Check", kPromoBrowserCommandOpenSafetyCheckCommandParam, + base::size(kPromoBrowserCommandOpenSafetyCheckCommandParam), "t4237555" /* variation_id */}}; #if defined(OS_ANDROID) @@ -2501,13 +2498,6 @@ {"focus-mode", flag_descriptions::kFocusMode, flag_descriptions::kFocusModeDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kFocusMode)}, - {"touch-events", flag_descriptions::kTouchEventsName, - flag_descriptions::kTouchEventsDescription, kOsDesktop, - MULTI_VALUE_TYPE(kTouchEventFeatureDetectionChoices)}, - {"disable-touch-adjustment", flag_descriptions::kTouchAdjustmentName, - flag_descriptions::kTouchAdjustmentDescription, - kOsWin | kOsLinux | kOsCrOS | kOsAndroid, - SINGLE_DISABLE_VALUE_TYPE(switches::kDisableTouchAdjustment)}, #if defined(OS_CHROMEOS) {"disable-explicit-dma-fences", flag_descriptions::kDisableExplicitDmaFencesName, @@ -2645,6 +2635,16 @@ flag_descriptions::kSystemTrayMicGainDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kSystemTrayMicGainSetting)}, #endif // OS_CHROMEOS + +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + { + "enable-accelerated-video-decode", + flag_descriptions::kAcceleratedVideoDecodeName, + flag_descriptions::kAcceleratedVideoDecodeDescription, + kOsLinux, + SINGLE_VALUE_TYPE(switches::kEnableAcceleratedVideoDecode), + }, +#else { "disable-accelerated-video-decode", flag_descriptions::kAcceleratedVideoDecodeName, @@ -2652,6 +2652,7 @@ kOsMac | kOsWin | kOsCrOS | kOsAndroid, SINGLE_DISABLE_VALUE_TYPE(switches::kDisableAcceleratedVideoDecode), }, +#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_ANDROID) { "disable-accelerated-video-encode", flag_descriptions::kAcceleratedVideoEncodeName, @@ -2883,7 +2884,7 @@ {"reduced-referrer-granularity", flag_descriptions::kReducedReferrerGranularityName, flag_descriptions::kReducedReferrerGranularityDescription, kOsAll, - FEATURE_VALUE_TYPE(features::kReducedReferrerGranularity)}, + FEATURE_VALUE_TYPE(blink::features::kReducedReferrerGranularity)}, #if defined(OS_CHROMEOS) {"crostini-port-forwarding", flag_descriptions::kCrostiniPortForwardingName, flag_descriptions::kCrostiniPortForwardingDescription, kOsCrOS, @@ -3603,9 +3604,15 @@ {"files-transfer-details", flag_descriptions::kFilesTransferDetailsName, flag_descriptions::kFilesTransferDetailsDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kFilesTransferDetails)}, - {"files-zip-no-nacl", flag_descriptions::kFilesZipNoNaClName, - flag_descriptions::kFilesZipNoNaClDescription, kOsCrOS, - FEATURE_VALUE_TYPE(chromeos::features::kFilesZipNoNaCl)}, + {"files-zip-mount", flag_descriptions::kFilesZipMountName, + flag_descriptions::kFilesZipMountDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kFilesZipMount)}, + {"files-zip-pack", flag_descriptions::kFilesZipPackName, + flag_descriptions::kFilesZipPackDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kFilesZipPack)}, + {"files-zip-unpack", flag_descriptions::kFilesZipUnpackName, + flag_descriptions::kFilesZipUnpackDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kFilesZipUnpack)}, {"files-unified-media-view", flag_descriptions::kUnifiedMediaViewName, flag_descriptions::kUnifiedMediaViewDescription, kOsCrOS, FEATURE_VALUE_TYPE(chromeos::features::kUnifiedMediaView)}, @@ -3676,6 +3683,15 @@ flag_descriptions::kOmniboxClobberIsZeroSuggestEntrypointDescription, kOsAll, FEATURE_VALUE_TYPE(omnibox::kClobberIsZeroSuggestEntrypoint)}, + {"omnibox-focus-gesture-triggers-contextual-web-zero-suggest", + flag_descriptions:: + kOmniboxFocusGestureTriggersContextualWebZeroSuggestName, + flag_descriptions:: + kOmniboxFocusGestureTriggersContextualWebZeroSuggestDescription, + kOsAll, + FEATURE_VALUE_TYPE( + omnibox::kFocusGestureTriggersContextualWebZeroSuggest)}, + {"omnibox-on-device-head-suggestions-incognito", flag_descriptions::kOmniboxOnDeviceHeadSuggestionsIncognitoName, flag_descriptions::kOmniboxOnDeviceHeadSuggestionsIncognitoDescription, @@ -4712,12 +4728,6 @@ MULTI_VALUE_TYPE(kUseAngleChoices)}, #endif #if defined(OS_ANDROID) - {"draw-vertically-edge-to-edge", - flag_descriptions::kDrawVerticallyEdgeToEdgeName, - flag_descriptions::kDrawVerticallyEdgeToEdgeDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kDrawVerticallyEdgeToEdge)}, -#endif -#if defined(OS_ANDROID) {"enable-ephemeral-tab-bottom-sheet", flag_descriptions::kEphemeralTabUsingBottomSheetName, flag_descriptions::kEphemeralTabUsingBottomSheetDescription, kOsAndroid, @@ -6065,11 +6075,6 @@ flag_descriptions::kEnablePalmSuppressionDescription, kOsCrOS, FEATURE_VALUE_TYPE(ui::kEnablePalmSuppression)}, - {"enable-high-resolution-mouse-scrolling", - flag_descriptions::kEnableHighResolutionMouseScrollingName, - flag_descriptions::kEnableHighResolutionMouseScrollingDescription, kOsCrOS, - FEATURE_VALUE_TYPE(ui::kEnableHighResolutionMouseScrolling)}, - {"movable-partial-screenshot-region", flag_descriptions::kMovablePartialScreenshotName, flag_descriptions::kMovablePartialScreenshotDescription, kOsCrOS, @@ -6272,6 +6277,12 @@ FEATURE_VALUE_TYPE(features::kCpuAffinityRestrictToLittleCores)}, #endif // OS_ANDROID +#if defined(OS_CHROMEOS) + {"enable-auto-select", flag_descriptions::kEnableAutoSelectName, + flag_descriptions::kEnableAutoSelectDescription, kOsCrOS, + FEATURE_VALUE_TYPE(blink::features::kCrOSAutoSelect)}, +#endif // defined(OS_CHROMEOS) + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/about_flags_browsertest.cc b/chrome/browser/about_flags_browsertest.cc index 2f65e11..9811f3f 100644 --- a/chrome/browser/about_flags_browsertest.cc +++ b/chrome/browser/about_flags_browsertest.cc
@@ -413,7 +413,10 @@ "const e = document.createEvent('HTMLEvents');" "e.initEvent('change', true, true);" "s.dispatchEvent(e);", - kFlagWithOptionSelectorName))); + kFlagWithOptionSelectorName), + // Execute script in an isolated world to avoid causing a Trusted Types + // violation due to eval. + content::EXECUTE_SCRIPT_DEFAULT_OPTIONS, /*world_id=*/1)); } } // namespace
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index a01ed3e..ed485f8 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -678,11 +678,13 @@ JNIEnv* env = AttachCurrentThread(); bool has_close_or_cancel = false; - auto chips = Java_AutofillAssistantUiController_createChipList(env); + auto jchips = Java_AutofillAssistantUiController_createChipList(env); + auto jsticky_chips = Java_AutofillAssistantUiController_createChipList(env); int user_action_count = static_cast<int>(user_actions.size()); for (int i = 0; i < user_action_count; i++) { const auto& action = user_actions[i]; const Chip& chip = action.chip(); + base::android::ScopedJavaLocalRef<jobject> jchip; switch (chip.type) { default: // Ignore actions with other chip types or with no chips. break; @@ -692,16 +694,17 @@ // can hide all the chips except for the cancel chip when the keyboard // is showing. // TODO(b/149543425): Find a better way to do this. - Java_AutofillAssistantUiController_addHighlightedActionButton( - env, java_object_, chips, chip.icon, - base::android::ConvertUTF8ToJavaString(env, chip.text), i, - !action.enabled(), chip.sticky, - base::android::ConvertUTF8ToJavaString(env, "")); + jchip = + Java_AutofillAssistantUiController_createHighlightedActionButton( + env, java_object_, chip.icon, + base::android::ConvertUTF8ToJavaString(env, chip.text), i, + !action.enabled(), chip.sticky, + base::android::ConvertUTF8ToJavaString(env, "")); break; case NORMAL_ACTION: - Java_AutofillAssistantUiController_addActionButton( - env, java_object_, chips, chip.icon, + jchip = Java_AutofillAssistantUiController_createActionButton( + env, java_object_, chip.icon, base::android::ConvertUTF8ToJavaString(env, chip.text), i, !action.enabled(), chip.sticky, base::android::ConvertUTF8ToJavaString(env, "")); @@ -710,8 +713,8 @@ case CANCEL_ACTION: // A Cancel button sneaks in an UNDO snackbar before executing the // action, while a close button behaves like a normal button. - Java_AutofillAssistantUiController_addCancelButton( - env, java_object_, chips, chip.icon, + jchip = Java_AutofillAssistantUiController_createCancelButton( + env, java_object_, chip.icon, base::android::ConvertUTF8ToJavaString(env, chip.text), i, !action.enabled(), chip.sticky, base::android::ConvertUTF8ToJavaString(env, kCancelChipIdentifier)); @@ -719,8 +722,8 @@ break; case CLOSE_ACTION: - Java_AutofillAssistantUiController_addActionButton( - env, java_object_, chips, chip.icon, + jchip = Java_AutofillAssistantUiController_createActionButton( + env, java_object_, chip.icon, base::android::ConvertUTF8ToJavaString(env, chip.text), i, !action.enabled(), chip.sticky, base::android::ConvertUTF8ToJavaString(env, "")); @@ -728,33 +731,50 @@ break; case DONE_ACTION: - Java_AutofillAssistantUiController_addHighlightedActionButton( - env, java_object_, chips, chip.icon, - base::android::ConvertUTF8ToJavaString(env, chip.text), i, - !action.enabled(), chip.sticky, - base::android::ConvertUTF8ToJavaString(env, "")); + jchip = + Java_AutofillAssistantUiController_createHighlightedActionButton( + env, java_object_, chip.icon, + base::android::ConvertUTF8ToJavaString(env, chip.text), i, + !action.enabled(), chip.sticky, + base::android::ConvertUTF8ToJavaString(env, "")); has_close_or_cancel = true; break; } + if (jchip) { + Java_AutofillAssistantUiController_appendChipToList(env, jchips, jchip); + if (chip.sticky) { + Java_AutofillAssistantUiController_appendChipToList(env, jsticky_chips, + jchip); + } + } } if (!has_close_or_cancel) { + base::android::ScopedJavaLocalRef<jobject> jcancel_chip; if (ui_delegate_->GetState() == AutofillAssistantState::STOPPED) { - Java_AutofillAssistantUiController_addCloseButton( - env, java_object_, chips, ICON_CLEAR, + jcancel_chip = Java_AutofillAssistantUiController_createCloseButton( + env, java_object_, ICON_CLEAR, base::android::ConvertUTF8ToJavaString(env, ""), /* disabled= */ false, /* sticky= */ true, base::android::ConvertUTF8ToJavaString(env, "")); } else if (ui_delegate_->GetState() != AutofillAssistantState::INACTIVE) { - Java_AutofillAssistantUiController_addCancelButton( - env, java_object_, chips, ICON_CLEAR, + jcancel_chip = Java_AutofillAssistantUiController_createCancelButton( + env, java_object_, ICON_CLEAR, base::android::ConvertUTF8ToJavaString(env, ""), -1, /* disabled= */ false, /* sticky= */ true, base::android::ConvertUTF8ToJavaString(env, kCancelChipIdentifier)); } + if (jcancel_chip) { + Java_AutofillAssistantUiController_appendChipToList(env, jchips, + jcancel_chip); + Java_AutofillAssistantUiController_appendChipToList(env, jsticky_chips, + jcancel_chip); + } } - Java_AutofillAssistantUiController_setActions(env, java_object_, chips); + Java_AutofillAssistantUiController_setActions(env, java_object_, jchips); + Java_AssistantHeaderModel_setChips(AttachCurrentThread(), GetHeaderModel(), + jsticky_chips); } void UiControllerAndroid::OnUserActionsChanged(
diff --git a/chrome/browser/android/battery/android_battery_metrics.cc b/chrome/browser/android/battery/android_battery_metrics.cc index 0595203f..5106040 100644 --- a/chrome/browser/android/battery/android_battery_metrics.cc +++ b/chrome/browser/android/battery/android_battery_metrics.cc
@@ -48,7 +48,8 @@ AddCount(capacity_consumed / num_sampling_periods, num_sampling_periods), base::Histogram::FactoryGet( - kName, /*min_value=*/1, /*max_value=*/100000, /*bucket_count=*/50, + kExclusiveName, /*min_value=*/1, /*max_value=*/100000, + /*bucket_count=*/50, base::HistogramBase::kUmaTargetedHistogramFlag)); }
diff --git a/chrome/browser/android/customtabs/detached_resource_request_unittest.cc b/chrome/browser/android/customtabs/detached_resource_request_unittest.cc index f1ac5cc..632f24e 100644 --- a/chrome/browser/android/customtabs/detached_resource_request_unittest.cc +++ b/chrome/browser/android/customtabs/detached_resource_request_unittest.cc
@@ -26,6 +26,7 @@ #include "net/test/embedded_test_server/http_response.h" #include "net/test/embedded_test_server/request_handler_util.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "url/gurl.h" namespace customtabs { @@ -270,7 +271,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, ""); + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, ""); first_request_waiter.Run(); second_request_waiter.Run(); @@ -327,7 +328,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, "", + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "", base::BindLambdaForTesting([&](int net_error) { EXPECT_EQ(net::OK, net_error); request_completion_waiter.Quit(); @@ -352,7 +353,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, "", + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "", base::BindLambdaForTesting([&](int net_error) { EXPECT_NE(net::OK, net_error); request_waiter.Quit(); @@ -382,7 +383,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, "", + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "", base::BindLambdaForTesting([&](int net_error) { EXPECT_EQ(net::OK, net_error); request_waiter.Quit(); @@ -405,7 +406,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, "", + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "", base::BindLambdaForTesting([&](int net_error) { EXPECT_NE(net::OK, net_error); request_waiter.Quit(); @@ -433,7 +434,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, "", + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "", base::BindLambdaForTesting([&](int net_error) { EXPECT_NE(net::OK, net_error); request_waiter.Quit(); @@ -468,7 +469,7 @@ for (int i = 0; i < 2; ++i) { DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, ""); + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, ""); } request_waiter.Run(); EXPECT_EQ(site_for_cookies.spec(), headers["referer"]); @@ -489,7 +490,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, ""); + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, ""); request_waiter.Run(); EXPECT_EQ("", headers["referer"]); } @@ -516,7 +517,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, ""); + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, ""); first_request_waiter.Run(); second_request_waiter.Run(); } @@ -541,7 +542,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, "", + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "", base::BindLambdaForTesting([&](int net_error) { EXPECT_EQ(net::OK, net_error); request_completion_waiter.Quit(); @@ -555,7 +556,7 @@ TEST_F(DetachedResourceRequestTest, DefaultReferrerPolicy) { // No Referrer on downgrade. SetAndCheckReferrer("https://cats.google.com", "", - content::Referrer::GetDefaultReferrerPolicy()); + blink::ReferrerUtils::GetDefaultNetReferrerPolicy()); } TEST_F(DetachedResourceRequestTest, OriginReferrerPolicy) { @@ -601,7 +602,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, "", + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "", base::BindLambdaForTesting([&](int net_error) { EXPECT_EQ(net::OK, net_error); detached_request_waiter.Quit(); @@ -639,7 +640,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "com.google.android.googlequicksearchbox", base::BindLambdaForTesting([&](int net_error) { EXPECT_EQ(net::OK, net_error); @@ -671,7 +672,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, "", + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "", base::BindLambdaForTesting([&](int net_error) { EXPECT_EQ(-net::ERR_TOO_MANY_REDIRECTS, net_error); request_waiter.Quit(); @@ -700,7 +701,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, "", + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "", base::BindLambdaForTesting([&](int net_error) { EXPECT_EQ(net::OK, net_error); first_request_waiter.Quit(); @@ -709,7 +710,7 @@ DetachedResourceRequest::CreateAndStart( browser_context(), url, site_for_cookies, - content::Referrer::GetDefaultReferrerPolicy(), kMotivation, "", + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), kMotivation, "", base::BindLambdaForTesting([&](int net_error) { EXPECT_EQ(net::OK, net_error); second_request_waiter.Quit();
diff --git a/chrome/browser/android/vr/browser_renderer_factory.cc b/chrome/browser/android/vr/browser_renderer_factory.cc index 123e0c7..4063193 100644 --- a/chrome/browser/android/vr/browser_renderer_factory.cc +++ b/chrome/browser/android/vr/browser_renderer_factory.cc
@@ -10,13 +10,11 @@ #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/android/vr/cardboard_input_delegate.h" #include "chrome/browser/android/vr/gvr_input_delegate.h" -#include "chrome/browser/android/vr/gvr_keyboard_delegate.h" #include "chrome/browser/android/vr/gvr_scheduler_delegate.h" #include "chrome/browser/android/vr/ui_factory.h" #include "chrome/browser/android/vr/vr_gl_thread.h" #include "chrome/browser/vr/browser_renderer.h" #include "chrome/browser/vr/sounds_manager_audio_delegate.h" -#include "chrome/browser/vr/text_input_delegate.h" #include "chrome/browser/vr/ui_interface.h" namespace { @@ -52,23 +50,12 @@ UiFactory* ui_factory, std::unique_ptr<Params> params) { DCHECK(params); - auto keyboard_delegate = GvrKeyboardDelegate::Create(); - auto text_input_delegate = std::make_unique<TextInputDelegate>(); - if (!keyboard_delegate) { - params->ui_initial_state.needs_keyboard_update = true; - } else { - text_input_delegate->SetUpdateInputCallback( - base::BindRepeating(&KeyboardDelegate::UpdateInput, - base::Unretained(keyboard_delegate.get()))); - } - params->ui_initial_state.gvr_input_support = !params->cardboard_gamepad; auto audio_delegate = std::make_unique<SoundsManagerAudioDelegate>(); - auto ui = ui_factory->Create( - vr_gl_thread, vr_gl_thread, std::move(keyboard_delegate), - std::move(text_input_delegate), std::move(audio_delegate), - params->ui_initial_state); + auto ui = + ui_factory->Create(vr_gl_thread, vr_gl_thread, nullptr, nullptr, + std::move(audio_delegate), params->ui_initial_state); std::unique_ptr<InputDelegate> input_delegate; if (params->cardboard_gamepad) { input_delegate = std::make_unique<CardboardInputDelegate>(params->gvr_api);
diff --git a/chrome/browser/apps/app_service/app_icon_factory.cc b/chrome/browser/apps/app_service/app_icon_factory.cc index 354c959c..c21bf72 100644 --- a/chrome/browser/apps/app_service/app_icon_factory.cc +++ b/chrome/browser/apps/app_service/app_icon_factory.cc
@@ -13,6 +13,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/memory/ref_counted.h" +#include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" #include "base/task/cancelable_task_tracker.h" #include "base/task/post_task.h" @@ -454,11 +455,12 @@ // constructor. icon_scale_for_compressed_response_ = icon_scale_; - if (icon_manager.HasSmallestIcon(web_app_id, icon_size_in_px_)) { + if (icon_manager.HasSmallestIcon(web_app_id, {IconPurpose::ANY}, + icon_size_in_px_)) { switch (icon_type_) { case apps::mojom::IconType::kCompressed: if (icon_effects_ == apps::IconEffects::kNone) { - icon_manager.ReadSmallestCompressedIcon( + icon_manager.ReadSmallestCompressedIconAny( web_app_id, icon_size_in_px_, base::BindOnce(&IconLoadingPipeline::CompleteWithCompressed, base::WrapRefCounted(this))); @@ -483,7 +485,7 @@ // If |icon_effects| are requested, we must always load the // uncompressed image to apply the icon effects, and then re-encode the // image if the compressed icon is requested. - icon_manager.ReadSmallestIcon( + icon_manager.ReadSmallestIconAny( web_app_id, icon_size_in_px_, SkBitmapToImageSkiaCallback( base::BindOnce( @@ -948,6 +950,8 @@ // For non-adaptive icons, add the white color background, and apply the mask. if (!icon->is_adaptive_icon) { + base::UmaHistogramBoolean("Arc.AdaptiveIconLoad.FromNonArcAppIcon", false); + if (!icon->icon_png_data.has_value() || icon->icon_png_data.value().empty()) { std::move(callback).Run(gfx::ImageSkia()); @@ -961,6 +965,8 @@ return; } + base::UmaHistogramBoolean("Arc.AdaptiveIconLoad.FromNonArcAppIcon", true); + if (!icon->foreground_icon_png_data.has_value() || icon->foreground_icon_png_data.value().empty() || !icon->background_icon_png_data.has_value() ||
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index badf56a1..20be74d 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -139,7 +139,9 @@ <include name="IDR_INLINE_LOGIN_BROWSER_PROXY_JS" file="resources\inline_login\inline_login_browser_proxy.js" type ="BINDATA"/> </if> - <include name="IDR_CHROME_URLS_DISABLED_PAGE_HTML" file="resources\chrome_urls_disabled_page\app.html" type="BINDATA" /> + <if expr="chromeos"> + <include name="IDR_CHROME_URLS_DISABLED_PAGE_HTML" file="resources\chromeos\chrome_urls_disabled_page\app.html" type="BINDATA" /> + </if> <include name="IDR_IDENTITY_API_SCOPE_APPROVAL_MANIFEST" file="resources\identity_scope_approval_dialog\manifest.json" type="BINDATA" />
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 91b9459..d53f83b7 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2175,7 +2175,8 @@ base::size(kDinosaurEasterEggSwitches)); if (content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()) - command_line->AppendSwitch(switches::kForceLegacyDefaultReferrerPolicy); + command_line->AppendSwitch( + blink::switches::kForceLegacyDefaultReferrerPolicy); #if defined(OS_CHROMEOS) // On Chrome OS need to pass primary user homedir (in multi-profiles session). @@ -4444,14 +4445,14 @@ web_contents); if (client_data_header_observer) client_data_header = client_data_header_observer->header(); - } - auto* delegate = TabAndroid::FromWebContents(web_contents) - ? static_cast<android::TabWebContentsDelegateAndroid*>( - web_contents->GetDelegate()) - : nullptr; - if (delegate) { - night_mode_enabled = delegate->IsNightModeEnabled(); + auto* delegate = + TabAndroid::FromWebContents(web_contents) + ? static_cast<android::TabWebContentsDelegateAndroid*>( + web_contents->GetDelegate()) + : nullptr; + if (delegate) + night_mode_enabled = delegate->IsNightModeEnabled(); } } #endif
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index b4f897d..f20e00d 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -113,6 +113,7 @@ "//chromeos/components/mojo_bootstrap", "//chromeos/components/multidevice", "//chromeos/components/multidevice/logging", + "//chromeos/components/phonehub", "//chromeos/components/power", "//chromeos/components/print_management/mojom", "//chromeos/components/proximity_auth", @@ -808,6 +809,14 @@ "bluetooth/debug_logs_manager_factory.h", "boot_times_recorder.cc", "boot_times_recorder.h", + "borealis/borealis_installer.cc", + "borealis/borealis_installer.h", + "borealis/borealis_installer_factory.cc", + "borealis/borealis_installer_factory.h", + "borealis/borealis_installer_impl.cc", + "borealis/borealis_installer_impl.h", + "borealis/borealis_util.cc", + "borealis/borealis_util.h", "browser_context_keyed_service_factories.cc", "browser_context_keyed_service_factories.h", "camera_detector.cc", @@ -925,6 +934,8 @@ "concierge_helper_service.h", "crosapi/ash_chrome_service_impl.cc", "crosapi/ash_chrome_service_impl.h", + "crosapi/attestation_ash.cc", + "crosapi/attestation_ash.h", "crosapi/browser_loader.cc", "crosapi/browser_loader.h", "crosapi/browser_manager.cc", @@ -1881,6 +1892,8 @@ "ownership/owner_settings_service_chromeos.h", "ownership/owner_settings_service_chromeos_factory.cc", "ownership/owner_settings_service_chromeos_factory.h", + "phonehub/phone_hub_manager_factory.cc", + "phonehub/phone_hub_manager_factory.h", "platform_keys/extension_platform_keys_service.cc", "platform_keys/extension_platform_keys_service.h", "platform_keys/extension_platform_keys_service_factory.cc", @@ -3049,6 +3062,8 @@ "authpolicy/authpolicy_helper.unittest.cc", "base/file_flusher_unittest.cc", "bluetooth/debug_logs_manager_unittest.cc", + "borealis/borealis_installer_mock.cc", + "borealis/borealis_installer_mock.h", "cert_provisioning/cert_provisioning_invalidator_unittest.cc", "cert_provisioning/cert_provisioning_platform_keys_helpers_unittest.cc", "cert_provisioning/cert_provisioning_scheduler_unittest.cc",
diff --git a/chrome/browser/chromeos/accessibility/dictation_chromeos.cc b/chrome/browser/chromeos/accessibility/dictation_chromeos.cc index 3062ec09a..9904ab8 100644 --- a/chrome/browser/chromeos/accessibility/dictation_chromeos.cc +++ b/chrome/browser/chromeos/accessibility/dictation_chromeos.cc
@@ -17,9 +17,9 @@ #include "services/network/public/cpp/shared_url_loader_factory.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/ime_bridge.h" +#include "ui/base/ime/chromeos/ime_input_context_handler_interface.h" #include "ui/base/ime/chromeos/input_method_util.h" #include "ui/base/ime/composition_text.h" -#include "ui/base/ime/ime_input_context_handler_interface.h" namespace chromeos {
diff --git a/chrome/browser/chromeos/accessibility/dictation_chromeos_browsertest.cc b/chrome/browser/chromeos/accessibility/dictation_chromeos_browsertest.cc index 2890312..bf26f65 100644 --- a/chrome/browser/chromeos/accessibility/dictation_chromeos_browsertest.cc +++ b/chrome/browser/chromeos/accessibility/dictation_chromeos_browsertest.cc
@@ -8,9 +8,9 @@ #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h" #include "ui/base/ime/chromeos/ime_bridge.h" +#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h" #include "ui/base/ime/dummy_text_input_client.h" #include "ui/base/ime/input_method_base.h" -#include "ui/base/ime/mock_ime_input_context_handler.h" namespace chromeos {
diff --git a/chrome/browser/chromeos/arc/OWNERS b/chrome/browser/chromeos/arc/OWNERS index ab4ebe9c..02d6b48 100644 --- a/chrome/browser/chromeos/arc/OWNERS +++ b/chrome/browser/chromeos/arc/OWNERS
@@ -1,4 +1 @@ -hidehiko@chromium.org -yusukes@chromium.org -# backup reviewer -elijahtaylor@chromium.org +file://components/arc/OWNERS
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc index c8773bf9..9fe1fd5a 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
@@ -33,9 +33,9 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/ime_bridge.h" +#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h" #include "ui/base/ime/chromeos/mock_input_method_manager.h" #include "ui/base/ime/dummy_text_input_client.h" -#include "ui/base/ime/mock_ime_input_context_handler.h" #include "ui/base/ime/mock_input_method.h" #include "ui/views/widget/widget.h"
diff --git a/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl_unittest.cc index 6cd1a8b..ea0b7f1d 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl_unittest.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/input_connection_impl_unittest.cc
@@ -10,9 +10,9 @@ #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/chromeos/ime_bridge.h" +#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h" #include "ui/base/ime/chromeos/mock_input_method_manager.h" #include "ui/base/ime/dummy_text_input_client.h" -#include "ui/base/ime/mock_ime_input_context_handler.h" #include "ui/base/ime/mock_input_method.h" #include "ui/events/keycodes/dom/dom_codes.h"
diff --git a/chrome/browser/chromeos/borealis/OWNERS b/chrome/browser/chromeos/borealis/OWNERS new file mode 100644 index 0000000..e025940 --- /dev/null +++ b/chrome/browser/chromeos/borealis/OWNERS
@@ -0,0 +1,3 @@ +cpelling@google.com +danielng@google.com +hollingum@google.com
diff --git a/chrome/browser/chromeos/borealis/borealis_installer.cc b/chrome/browser/chromeos/borealis/borealis_installer.cc new file mode 100644 index 0000000..d03d2f0b --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_installer.cc
@@ -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. + +#include "chrome/browser/chromeos/borealis/borealis_installer.h" + +namespace borealis { + +BorealisInstaller::BorealisInstaller() = default; + +BorealisInstaller::~BorealisInstaller() = default; + +// static +std::string BorealisInstaller::GetInstallingStateName(InstallingState state) { + switch (state) { + case InstallingState::kInactive: + return "kInactive"; + case InstallingState::kInstallingDlc: + return "kInstallingDlc"; + } +} + +void BorealisInstaller::AddObserver(Observer* observer) { + DCHECK(!observer); + observers_.AddObserver(observer); +} + +void BorealisInstaller::RemoveObserver(Observer* observer) { + DCHECK(!observer); + observers_.RemoveObserver(observer); +} + +} // namespace borealis
diff --git a/chrome/browser/chromeos/borealis/borealis_installer.h b/chrome/browser/chromeos/borealis/borealis_installer.h new file mode 100644 index 0000000..3eb14b4 --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_installer.h
@@ -0,0 +1,72 @@ +// 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_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_H_ +#define CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace borealis { + +class BorealisInstaller : public KeyedService { + public: + enum class InstallationResult { + kCompleted, + kCancelled, + kNotAllowed, + kOperationInProgress, + kDlcInternal, + kDlcUnsupported, + kDlcBusy, + kDlcNeedReboot, + kDlcNeedSpace, + kDlcUnknown, + }; + + enum class InstallingState { + kInactive, + kInstallingDlc, + }; + + // Observer class for the Borealis installation related events. + class Observer : public base::CheckedObserver { + public: + virtual void OnProgressUpdated(double fraction_complete) = 0; + virtual void OnStateUpdated(InstallingState new_state) = 0; + virtual void OnInstallationEnded(InstallationResult result) = 0; + virtual void OnCancelInitiated() = 0; + }; + + BorealisInstaller(); + + static std::string GetInstallingStateName(InstallingState state); + + // Checks if an installation process is already running. + virtual bool IsProcessing() = 0; + // Start the installation process. + virtual void Start() = 0; + // Cancels the installation process. + virtual void Cancel() = 0; + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + protected: + ~BorealisInstaller() override; + + base::ObserverList<Observer> observers_; + + private: + base::WeakPtrFactory<BorealisInstaller> weak_ptr_factory_{this}; +}; + +} // namespace borealis + +#endif // CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_H_
diff --git a/chrome/browser/chromeos/borealis/borealis_installer_factory.cc b/chrome/browser/chromeos/borealis/borealis_installer_factory.cc new file mode 100644 index 0000000..1f1111ed --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_installer_factory.cc
@@ -0,0 +1,46 @@ +// 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/chromeos/borealis/borealis_installer_factory.h" + +#include "chrome/browser/chromeos/borealis/borealis_installer_impl.h" +#include "chrome/browser/download/download_service_factory.h" +#include "chrome/browser/profiles/incognito_helpers.h" +#include "chrome/browser/profiles/profile.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" + +namespace borealis { + +// static +BorealisInstaller* BorealisInstallerFactory::GetForProfile(Profile* profile) { + return static_cast<BorealisInstaller*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + +// static +BorealisInstallerFactory* BorealisInstallerFactory::GetInstance() { + static base::NoDestructor<BorealisInstallerFactory> factory; + return factory.get(); +} + +BorealisInstallerFactory::BorealisInstallerFactory() + : BrowserContextKeyedServiceFactory( + "BorealisInstaller", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(DownloadServiceFactory::GetInstance()); +} + +BorealisInstallerFactory::~BorealisInstallerFactory() = default; + +KeyedService* BorealisInstallerFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + return new BorealisInstallerImpl(); +} + +content::BrowserContext* BorealisInstallerFactory::GetBrowserContextToUse( + content::BrowserContext* context) const { + return chrome::GetBrowserContextRedirectedInIncognito(context); +} + +} // namespace borealis
diff --git a/chrome/browser/chromeos/borealis/borealis_installer_factory.h b/chrome/browser/chromeos/borealis/borealis_installer_factory.h new file mode 100644 index 0000000..54d6ac4 --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_installer_factory.h
@@ -0,0 +1,44 @@ +// 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_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_FACTORY_H_ +#define CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_FACTORY_H_ + +#include "base/macros.h" +#include "base/no_destructor.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace content { +class BrowserContext; +} // namespace content + +class Profile; + +namespace borealis { + +class BorealisInstaller; + +class BorealisInstallerFactory : public BrowserContextKeyedServiceFactory { + public: + static BorealisInstaller* GetForProfile(Profile* profile); + static BorealisInstallerFactory* GetInstance(); + + private: + friend base::NoDestructor<BorealisInstallerFactory>; + + BorealisInstallerFactory(); + ~BorealisInstallerFactory() override; + + // BrowserContextKeyedServiceFactory implementation. + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + content::BrowserContext* GetBrowserContextToUse( + content::BrowserContext* context) const override; + + DISALLOW_COPY_AND_ASSIGN(BorealisInstallerFactory); +}; + +} // namespace borealis + +#endif // CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_FACTORY_H_
diff --git a/chrome/browser/chromeos/borealis/borealis_installer_impl.cc b/chrome/browser/chromeos/borealis/borealis_installer_impl.cc new file mode 100644 index 0000000..ef4d2579 --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_installer_impl.cc
@@ -0,0 +1,163 @@ +// 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/chromeos/borealis/borealis_installer_impl.h" + +#include "base/bind.h" +#include "chrome/browser/chromeos/borealis/borealis_util.h" +#include "content/public/browser/browser_thread.h" + +namespace borealis { + +BorealisInstallerImpl::BorealisInstallerImpl() = default; + +BorealisInstallerImpl::~BorealisInstallerImpl() = default; + +bool BorealisInstallerImpl::IsProcessing() { + return state_ != State::kIdle; +} + +void BorealisInstallerImpl::Start() { + if (!IsBorealisAllowed()) { + LOG(ERROR) << "Installation of Borealis cannot be started because " + << "Borealis is not allowed."; + InstallationEnded(InstallationResult::kNotAllowed); + return; + } + + if (IsProcessing()) { + LOG(ERROR) << "Installation of Borealis is already in progress."; + InstallationEnded(InstallationResult::kOperationInProgress); + return; + } + + progress_ = 0; + StartDlcInstallation(); +} + +void BorealisInstallerImpl::Cancel() { + state_ = State::kCancelling; + for (auto& observer : observers_) { + observer.OnCancelInitiated(); + } +} + +void BorealisInstallerImpl::StartDlcInstallation() { + state_ = State::kInstalling; + UpdateInstallingState(InstallingState::kInstallingDlc); + + chromeos::DlcserviceClient::Get()->Install( + "borealis-dlc", + base::BindOnce(&BorealisInstallerImpl::OnDlcInstallationCompleted, + weak_ptr_factory_.GetWeakPtr()), + base::BindRepeating( + &BorealisInstallerImpl::OnDlcInstallationProgressUpdated, + weak_ptr_factory_.GetWeakPtr())); +} + +void BorealisInstallerImpl::InstallationEnded(InstallationResult result) { + state_ = State::kIdle; + installing_state_ = InstallingState::kInactive; + for (auto& observer : observers_) { + observer.OnInstallationEnded(result); + } +} + +void BorealisInstallerImpl::UpdateProgress(double state_progress) { + DCHECK_EQ(state_, State::kInstalling); + if (state_progress < 0 || state_progress > 1) { + LOG(ERROR) << "Unexpected progress value " << state_progress + << " in installing state " + << GetInstallingStateName(installing_state_); + return; + } + + double start_range = 0; + double end_range = 0; + switch (installing_state_) { + case InstallingState::kInstallingDlc: + start_range = 0; + end_range = 1; + break; + default: + NOTREACHED(); + } + + double new_progress = + start_range + (end_range - start_range) * state_progress; + if (new_progress < progress_) { + LOG(ERROR) << "Progress went backwards from " << progress_ << " to " + << progress_; + return; + } + + progress_ = new_progress; + for (auto& observer : observers_) { + observer.OnProgressUpdated(new_progress); + } +} + +void BorealisInstallerImpl::UpdateInstallingState( + InstallingState installing_state) { + DCHECK_NE(installing_state, InstallingState::kInactive); + installing_state_ = installing_state; + for (auto& observer : observers_) { + observer.OnStateUpdated(installing_state_); + } +} + +void BorealisInstallerImpl::OnDlcInstallationProgressUpdated(double progress) { + DCHECK_EQ(installing_state_, InstallingState::kInstallingDlc); + if (state_ == State::kCancelling) + return; + + UpdateProgress(progress); +} + +void BorealisInstallerImpl::OnDlcInstallationCompleted( + const chromeos::DlcserviceClient::InstallResult& install_result) { + DCHECK_EQ(installing_state_, InstallingState::kInstallingDlc); + if (state_ == State::kCancelling) { + // Since DLC installation is currently the only step of installation, + // Borealis has actually been installed by this stage. This is calling + // CancelFinished() instead of InstallFinished(), to help provide clarity + // and also make it easier to add new installation steps in the future. + InstallationEnded(InstallationResult::kCancelled); + return; + } + + // If success, continue to the next state. + if (install_result.error == dlcservice::kErrorNone) { + InstallationEnded(InstallationResult::kCompleted); + return; + } + + // At this point, the Borealis DLC installation has failed. + InstallationResult result = InstallationResult::kDlcUnknown; + + if (install_result.error == dlcservice::kErrorInternal) { + LOG(ERROR) << "Something went wrong internally with DlcService."; + result = InstallationResult::kDlcInternal; + } else if (install_result.error == dlcservice::kErrorInvalidDlc) { + LOG(ERROR) << "Borealis DLC is not supported, need to enable Borealis DLC."; + result = InstallationResult::kDlcUnsupported; + } else if (install_result.error == dlcservice::kErrorBusy) { + LOG(ERROR) + << "Borealis DLC is not able to be installed as dlcservice is busy."; + result = InstallationResult::kDlcBusy; + } else if (install_result.error == dlcservice::kErrorNeedReboot) { + LOG(ERROR) + << "Device has pending update and needs a reboot to use Borealis DLC."; + result = InstallationResult::kDlcBusy; + } else if (install_result.error == dlcservice::kErrorAllocation) { + LOG(ERROR) << "Device needs to free space to use Borealis DLC."; + result = InstallationResult::kDlcNeedSpace; + } else { + LOG(ERROR) << "Failed to install Borealis DLC: " << install_result.error; + } + + InstallationEnded(result); +} + +} // namespace borealis
diff --git a/chrome/browser/chromeos/borealis/borealis_installer_impl.h b/chrome/browser/chromeos/borealis/borealis_installer_impl.h new file mode 100644 index 0000000..049a6043 --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_installer_impl.h
@@ -0,0 +1,60 @@ +// 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_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_IMPL_H_ +#define CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_IMPL_H_ + +#include "chrome/browser/chromeos/borealis/borealis_installer.h" +#include "chromeos/dbus/dlcservice/dlcservice_client.h" + +namespace borealis { + +// This class is responsible for installing the Borealis VM. Currently +// the only installation requirements for Borealis is to install the +// relevant DLC component. The installer works with closesly with +// chrome/browser/ui/views/borealis/borealis_installer_view.h. +class BorealisInstallerImpl : public BorealisInstaller { + public: + BorealisInstallerImpl(); + + // Disallow copy and assign. + BorealisInstallerImpl(const BorealisInstallerImpl&) = delete; + BorealisInstallerImpl& operator=(const BorealisInstallerImpl&) = delete; + + // Checks if an installation process is already running. + bool IsProcessing() override; + // Start the installation process. + void Start() override; + // Cancels the installation process. + void Cancel() override; + + private: + enum class State { + kIdle, + kInstalling, + kCancelling, + }; + + ~BorealisInstallerImpl() override; + + void StartDlcInstallation(); + void InstallationEnded(InstallationResult result); + + void UpdateProgress(double state_progress); + void UpdateInstallingState(InstallingState installing_state); + + void OnDlcInstallationProgressUpdated(double progress); + void OnDlcInstallationCompleted( + const chromeos::DlcserviceClient::InstallResult& install_result); + + State state_ = State::kIdle; + InstallingState installing_state_ = InstallingState::kInactive; + double progress_ = 0; + + base::WeakPtrFactory<BorealisInstallerImpl> weak_ptr_factory_{this}; +}; + +} // namespace borealis + +#endif // CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_IMPL_H_
diff --git a/chrome/browser/chromeos/borealis/borealis_installer_mock.cc b/chrome/browser/chromeos/borealis/borealis_installer_mock.cc new file mode 100644 index 0000000..0345837d --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_installer_mock.cc
@@ -0,0 +1,14 @@ +// 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/chromeos/borealis/borealis_installer_mock.h" + +namespace borealis { +namespace test { + +BorealisInstallerMock::BorealisInstallerMock() = default; +BorealisInstallerMock::~BorealisInstallerMock() = default; + +} // namespace test +} // namespace borealis
diff --git a/chrome/browser/chromeos/borealis/borealis_installer_mock.h b/chrome/browser/chromeos/borealis/borealis_installer_mock.h new file mode 100644 index 0000000..52e2c2e --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_installer_mock.h
@@ -0,0 +1,29 @@ +// 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_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_MOCK_H_ +#define CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_MOCK_H_ + +#include "chrome/browser/chromeos/borealis/borealis_installer.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace borealis { +namespace test { + +class BorealisInstallerMock : public BorealisInstaller { + public: + BorealisInstallerMock(); + ~BorealisInstallerMock(); + BorealisInstallerMock(const BorealisInstallerMock&) = delete; + BorealisInstallerMock& operator=(const BorealisInstallerMock&) = delete; + + MOCK_METHOD(bool, IsProcessing, (), ()); + MOCK_METHOD(void, Start, (), ()); + MOCK_METHOD(void, Cancel, (), ()); +}; + +} // namespace test +} // namespace borealis + +#endif // CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_INSTALLER_MOCK_H_
diff --git a/chrome/browser/chromeos/borealis/borealis_util.cc b/chrome/browser/chromeos/borealis/borealis_util.cc new file mode 100644 index 0000000..178d6602 --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_util.cc
@@ -0,0 +1,16 @@ +// 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/chromeos/borealis/borealis_util.h" + +#include "chrome/common/chrome_features.h" + +namespace borealis { + +bool IsBorealisAllowed() { + // Check that the Borealis feature is enabled. + return base::FeatureList::IsEnabled(features::kBorealis); +} + +} // namespace borealis
diff --git a/chrome/browser/chromeos/borealis/borealis_util.h b/chrome/browser/chromeos/borealis/borealis_util.h new file mode 100644 index 0000000..e339f0df --- /dev/null +++ b/chrome/browser/chromeos/borealis/borealis_util.h
@@ -0,0 +1,20 @@ +// 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_CHROMEOS_BOREALIS_BOREALIS_UTIL_H_ +#define CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_UTIL_H_ + +class Profile; + +namespace borealis { + +// Checks if Borealis is allowed to run in the current environment. +bool IsBorealisAllowed(); + +// Shows the Borealis installer (borealis_installer_view). +void ShowBorealisInstallerView(Profile* profile); + +} // namespace borealis + +#endif // CHROME_BROWSER_CHROMEOS_BOREALIS_BOREALIS_UTIL_H_
diff --git a/chrome/browser/chromeos/browser_context_keyed_service_factories.cc b/chrome/browser/chromeos/browser_context_keyed_service_factories.cc index f94e0f0..4f3f819 100644 --- a/chrome/browser/chromeos/browser_context_keyed_service_factories.cc +++ b/chrome/browser/chromeos/browser_context_keyed_service_factories.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service_factory.h" #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_service_factory.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" +#include "chrome/browser/chromeos/phonehub/phone_hub_manager_factory.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_engagement_metrics_service.h" #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" #include "chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder_factory.h" @@ -70,6 +71,7 @@ KerberosCredentialsManagerFactory::GetInstance(); launcher_search_provider::ServiceFactory::GetInstance(); OwnerSettingsServiceChromeOSFactory::GetInstance(); + phonehub::PhoneHubManagerFactory::GetInstance(); plugin_vm::PluginVmEngagementMetricsService::Factory::GetInstance(); policy::PolicyCertServiceFactory::GetInstance(); policy::UserCloudPolicyTokenForwarderFactory::GetInstance();
diff --git a/chrome/browser/chromeos/crosapi/ash_chrome_service_impl.cc b/chrome/browser/chromeos/crosapi/ash_chrome_service_impl.cc index 3648012..384bbac 100644 --- a/chrome/browser/chromeos/crosapi/ash_chrome_service_impl.cc +++ b/chrome/browser/chromeos/crosapi/ash_chrome_service_impl.cc
@@ -4,11 +4,15 @@ #include "chrome/browser/chromeos/crosapi/ash_chrome_service_impl.h" +#include <memory> #include <utility> +#include <vector> #include "base/logging.h" +#include "chrome/browser/chromeos/crosapi/attestation_ash.h" #include "chrome/browser/chromeos/crosapi/screen_manager_crosapi.h" #include "chrome/browser/chromeos/crosapi/select_file_ash.h" +#include "chromeos/crosapi/mojom/attestation.mojom.h" #include "chromeos/crosapi/mojom/screen_manager.mojom.h" #include "chromeos/crosapi/mojom/select_file.mojom.h" @@ -25,6 +29,12 @@ AshChromeServiceImpl::~AshChromeServiceImpl() = default; +void AshChromeServiceImpl::BindAttestation( + mojo::PendingReceiver<crosapi::mojom::Attestation> receiver) { + attestation_ash_ = + std::make_unique<crosapi::AttestationAsh>(std::move(receiver)); +} + void AshChromeServiceImpl::BindSelectFile( mojo::PendingReceiver<mojom::SelectFile> receiver) { select_file_crosapi_ = std::make_unique<SelectFileAsh>(std::move(receiver));
diff --git a/chrome/browser/chromeos/crosapi/ash_chrome_service_impl.h b/chrome/browser/chromeos/crosapi/ash_chrome_service_impl.h index bc10ce39..a533ae3 100644 --- a/chrome/browser/chromeos/crosapi/ash_chrome_service_impl.h +++ b/chrome/browser/chromeos/crosapi/ash_chrome_service_impl.h
@@ -15,6 +15,7 @@ namespace crosapi { +class AttestationAsh; class SelectFileAsh; // Implementation of AshChromeService. It provides a set of APIs that @@ -26,6 +27,8 @@ ~AshChromeServiceImpl() override; // crosapi::mojom::AshChromeService: + void BindAttestation( + mojo::PendingReceiver<crosapi::mojom::Attestation> receiver) override; void BindScreenManager( mojo::PendingReceiver<mojom::ScreenManager> receiver) override; void BindSelectFile( @@ -34,6 +37,7 @@ private: mojo::Receiver<mojom::AshChromeService> receiver_; + std::unique_ptr<crosapi::AttestationAsh> attestation_ash_; std::unique_ptr<ScreenManagerCrosapi> screen_manager_crosapi_; std::unique_ptr<SelectFileAsh> select_file_crosapi_; };
diff --git a/chrome/browser/chromeos/crosapi/attestation_ash.cc b/chrome/browser/chromeos/crosapi/attestation_ash.cc new file mode 100644 index 0000000..b2a415c --- /dev/null +++ b/chrome/browser/chromeos/crosapi/attestation_ash.cc
@@ -0,0 +1,79 @@ +// 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/chromeos/crosapi/attestation_ash.h" + +#include <utility> + +#include "chrome/browser/chromeos/attestation/tpm_challenge_key.h" +#include "chrome/browser/profiles/profile_manager.h" + +namespace crosapi { + +AttestationAsh::AttestationAsh( + mojo::PendingReceiver<mojom::Attestation> receiver) + : receiver_(this, std::move(receiver)) {} + +AttestationAsh::~AttestationAsh() = default; + +void AttestationAsh::ChallengeKey(const std::string& challenge, + mojom::ChallengeKeyType type, + ChallengeKeyCallback callback) { + if (!crosapi::mojom::IsKnownEnumValue(type)) { + mojom::ChallengeKeyResultPtr result_ptr = mojom::ChallengeKeyResult::New(); + result_ptr->set_error_message("unsupported challenge key type"); + std::move(callback).Run(std::move(result_ptr)); + return; + } + chromeos::attestation::AttestationKeyType key_type; + switch (type) { + case mojom::ChallengeKeyType::kUser: + key_type = chromeos::attestation::KEY_USER; + break; + case mojom::ChallengeKeyType::kDevice: + key_type = chromeos::attestation::KEY_DEVICE; + break; + } + Profile* profile = ProfileManager::GetActiveUserProfile(); + + std::unique_ptr<chromeos::attestation::TpmChallengeKey> challenge_key = + chromeos::attestation::TpmChallengeKeyFactory::Create(); + chromeos::attestation::TpmChallengeKey* challenge_key_ptr = + challenge_key.get(); + outstanding_challenges_.push_back(std::move(challenge_key)); + challenge_key_ptr->BuildResponse( + key_type, profile, + base::BindOnce(&AttestationAsh::DidChallengeKey, + weak_factory_.GetWeakPtr(), std::move(callback), + challenge_key_ptr), + challenge, + /*register_key=*/false, /*key_name_for_spkac=*/""); +} + +void AttestationAsh::DidChallengeKey( + ChallengeKeyCallback callback, + void* challenge_key_ptr, + const chromeos::attestation::TpmChallengeKeyResult& result) { + mojom::ChallengeKeyResultPtr result_ptr = mojom::ChallengeKeyResult::New(); + if (result.IsSuccess()) { + result_ptr->set_challenge_response(result.challenge_response); + } else { + result_ptr->set_error_message(result.GetErrorMessage()); + } + std::move(callback).Run(std::move(result_ptr)); + + // Remove the outstanding challenge_key object. + bool found = false; + for (auto it = outstanding_challenges_.begin(); + it != outstanding_challenges_.end(); ++it) { + if (it->get() == challenge_key_ptr) { + outstanding_challenges_.erase(it); + found = true; + break; + } + } + DCHECK(found); +} + +} // namespace crosapi
diff --git a/chrome/browser/chromeos/crosapi/attestation_ash.h b/chrome/browser/chromeos/crosapi/attestation_ash.h new file mode 100644 index 0000000..b3ff385e --- /dev/null +++ b/chrome/browser/chromeos/crosapi/attestation_ash.h
@@ -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. + +#ifndef CHROME_BROWSER_CHROMEOS_CROSAPI_ATTESTATION_ASH_H_ +#define CHROME_BROWSER_CHROMEOS_CROSAPI_ATTESTATION_ASH_H_ + +#include <memory> +#include <vector> + +#include "base/memory/weak_ptr.h" +#include "chromeos/crosapi/mojom/attestation.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver.h" + +namespace chromeos { +namespace attestation { +class TpmChallengeKey; +struct TpmChallengeKeyResult; +} // namespace attestation +} // namespace chromeos + +namespace crosapi { + +// This class is the ash implementation of the Attestation crosapi. It allows +// lacros to expose blessed extension APIs which issue key challenges. These in +// turn are forwarded to ash, which signs the challenge with a private key. +class AttestationAsh : public mojom::Attestation { + public: + explicit AttestationAsh(mojo::PendingReceiver<mojom::Attestation> receiver); + AttestationAsh(const AttestationAsh&) = delete; + AttestationAsh& operator=(const AttestationAsh&) = delete; + ~AttestationAsh() override; + + // mojom::Attestation: + void ChallengeKey(const std::string& challenge, + mojom::ChallengeKeyType type, + ChallengeKeyCallback callback) override; + + private: + // |challenge| is used as a opaque identifier to match against the unique_ptr + // in outstanding_challenges_. It should not be dereferenced. + void DidChallengeKey( + ChallengeKeyCallback callback, + void* challenge, + const chromeos::attestation::TpmChallengeKeyResult& result); + + // Container to keep outstanding challenges alive. + std::vector<std::unique_ptr<chromeos::attestation::TpmChallengeKey>> + outstanding_challenges_; + mojo::Receiver<mojom::Attestation> receiver_; + + base::WeakPtrFactory<AttestationAsh> weak_factory_{this}; +}; + +} // namespace crosapi + +#endif // CHROME_BROWSER_CHROMEOS_CROSAPI_ATTESTATION_ASH_H_
diff --git a/chrome/browser/chromeos/crosapi/screen_manager_crosapi.cc b/chrome/browser/chromeos/crosapi/screen_manager_crosapi.cc index fcd9a4c..2692ae3 100644 --- a/chrome/browser/chromeos/crosapi/screen_manager_crosapi.cc +++ b/chrome/browser/chromeos/crosapi/screen_manager_crosapi.cc
@@ -13,7 +13,7 @@ #include "base/numerics/checked_math.h" #include "base/numerics/safe_conversions.h" #include "base/strings/utf_string_conversions.h" -#include "chromeos/crosapi/cpp/window_snapshot.h" +#include "chromeos/crosapi/cpp/bitmap.h" #include "ui/snapshot/snapshot.h" ScreenManagerCrosapi::ScreenManagerCrosapi() = default; @@ -93,7 +93,7 @@ TakeWindowSnapshotCallback callback) { auto it = id_to_window_.find(id); if (it == id_to_window_.end()) { - std::move(callback).Run(/*success=*/false, crosapi::WindowSnapshot()); + std::move(callback).Run(/*success=*/false, crosapi::Bitmap()); return; } @@ -132,9 +132,9 @@ uint8_t* base = static_cast<uint8_t*>(bitmap.getPixels()); std::vector<uint8_t> bytes(base, base + bitmap.computeByteSize()); - crosapi::WindowSnapshot snapshot; + crosapi::Bitmap snapshot; snapshot.width = bitmap.width(); snapshot.height = bitmap.height(); - snapshot.bitmap.swap(bytes); + snapshot.pixels.swap(bytes); std::move(callback).Run(std::move(snapshot)); }
diff --git a/chrome/browser/chromeos/crosapi/screen_manager_crosapi.h b/chrome/browser/chromeos/crosapi/screen_manager_crosapi.h index c066caf0..4d568ca1 100644 --- a/chrome/browser/chromeos/crosapi/screen_manager_crosapi.h +++ b/chrome/browser/chromeos/crosapi/screen_manager_crosapi.h
@@ -16,6 +16,10 @@ #include "ui/aura/window_observer.h" #include "ui/gfx/image/image.h" +namespace crosapi { +struct Bitmap; +} // namespace crosapi + // This class is the ash-chrome implementation of the ScreenManager interface. // This class must only be used from the main thread. class ScreenManagerCrosapi : public crosapi::mojom::ScreenManager, @@ -42,8 +46,7 @@ void OnWindowDestroying(aura::Window* window) final; private: - using SnapshotCallback = - base::OnceCallback<void(const crosapi::WindowSnapshot&)>; + using SnapshotCallback = base::OnceCallback<void(const crosapi::Bitmap&)>; void DidTakeSnapshot(SnapshotCallback callback, gfx::Image image); // This class generates unique, non-reused IDs for windows on demand. The IDs
diff --git a/chrome/browser/chromeos/crosapi/screen_manager_crosapi_browsertest.cc b/chrome/browser/chromeos/crosapi/screen_manager_crosapi_browsertest.cc index d82eb2c..b187f461 100644 --- a/chrome/browser/chromeos/crosapi/screen_manager_crosapi_browsertest.cc +++ b/chrome/browser/chromeos/crosapi/screen_manager_crosapi_browsertest.cc
@@ -11,7 +11,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/test/base/in_process_browser_test.h" -#include "chromeos/crosapi/cpp/window_snapshot.h" +#include "chromeos/crosapi/cpp/bitmap.h" #include "chromeos/crosapi/mojom/screen_manager.mojom.h" #include "content/public/test/browser_test.h" #include "mojo/public/cpp/bindings/remote.h" @@ -82,12 +82,12 @@ // Tests that taking a screen snapshot works. IN_PROC_BROWSER_TEST_F(ScreenManagerCrosapiBrowserTest, TakeScreenSnapshot) { base::RunLoop run_loop; - crosapi::WindowSnapshot snapshot; + crosapi::Bitmap snapshot; // Take a snapshot on a background sequence. The call is blocking, so when it // finishes, we can also unblock the main thread. auto take_snapshot_background = base::BindOnce( - [](SMRemote* remote, crosapi::WindowSnapshot* snapshot) { + [](SMRemote* remote, crosapi::Bitmap* snapshot) { mojo::ScopedAllowSyncCallForTesting allow_sync; (*remote)->TakeScreenSnapshot(snapshot); }, @@ -106,12 +106,12 @@ IN_PROC_BROWSER_TEST_F(ScreenManagerCrosapiBrowserTest, TakeWindowSnapshot) { base::RunLoop run_loop; bool success; - crosapi::WindowSnapshot snapshot; + crosapi::Bitmap snapshot; // Take a snapshot on a background sequence. The call is blocking, so when it // finishes, we can also unblock the main thread. auto take_snapshot_background = base::BindOnce( - [](SMRemote* remote, bool* success, crosapi::WindowSnapshot* snapshot) { + [](SMRemote* remote, bool* success, crosapi::Bitmap* snapshot) { mojo::ScopedAllowSyncCallForTesting allow_sync; std::vector<crosapi::mojom::WindowDetailsPtr> windows; (*remote)->ListWindows(&windows);
diff --git a/chrome/browser/chromeos/crostini/crostini_pref_names.cc b/chrome/browser/chromeos/crostini/crostini_pref_names.cc index 3d05227d..0d6a1ad 100644 --- a/chrome/browser/chromeos/crostini/crostini_pref_names.cc +++ b/chrome/browser/chromeos/crostini/crostini_pref_names.cc
@@ -124,7 +124,7 @@ registry->RegisterBooleanPref(kCrostiniDefaultContainerConfigured, false); registry->RegisterDictionaryPref( kCrostiniTerminalSettings, base::DictionaryValue(), - user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF); registry->RegisterIntegerPref( kCrostiniArcAdbSideloadingUserPref,
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc index 183d1c98..9506a25 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
@@ -51,8 +51,12 @@ dict->SetBoolean( "FILES_TRANSFER_DETAILS_ENABLED", base::FeatureList::IsEnabled(chromeos::features::kFilesTransferDetails)); - dict->SetBoolean("ZIP_NO_NACL", base::FeatureList::IsEnabled( - chromeos::features::kFilesZipNoNaCl)); + dict->SetBoolean("ZIP_MOUNT", base::FeatureList::IsEnabled( + chromeos::features::kFilesZipMount)); + dict->SetBoolean("ZIP_PACK", base::FeatureList::IsEnabled( + chromeos::features::kFilesZipPack)); + dict->SetBoolean("ZIP_UNPACK", base::FeatureList::IsEnabled( + chromeos::features::kFilesZipUnpack)); dict->SetBoolean("SHARESHEET_ENABLED", base::FeatureList::IsEnabled(features::kSharesheet)); dict->SetBoolean(
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index b873ff3..215f8f8 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -112,6 +112,7 @@ return *this; } + // TODO(crbug.com/912236) Remove once transition to new ZIP system is done. TestCase& ZipNoNaCl() { options.zip_no_nacl = true; return *this;
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc index 02861cd3..30897d0 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -1567,9 +1567,13 @@ } if (options.zip_no_nacl) { - enabled_features.push_back(chromeos::features::kFilesZipNoNaCl); + enabled_features.push_back(chromeos::features::kFilesZipMount); + enabled_features.push_back(chromeos::features::kFilesZipPack); + enabled_features.push_back(chromeos::features::kFilesZipUnpack); } else { - disabled_features.push_back(chromeos::features::kFilesZipNoNaCl); + disabled_features.push_back(chromeos::features::kFilesZipMount); + disabled_features.push_back(chromeos::features::kFilesZipPack); + disabled_features.push_back(chromeos::features::kFilesZipUnpack); } // This is destroyed in |TearDown()|. We cannot initialize this in the
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h index 5f53b08b..5af16f4 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h
@@ -62,9 +62,11 @@ bool browser = false; // Whether test requires zip/unzip support. + // TODO(crbug.com/912236) Remove once transition to new ZIP system is done. bool zip = false; - // Whether test should have zip-no-nacl active. + // Whether test uses the new ZIP system. + // TODO(crbug.com/912236) Remove once transition to new ZIP system is done. bool zip_no_nacl = false; // Whether Drive should act as if offline.
diff --git a/chrome/browser/chromeos/input_method/input_method_engine.h b/chrome/browser/chromeos/input_method/input_method_engine.h index ba901b0..fd421fc 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine.h +++ b/chrome/browser/chromeos/input_method/input_method_engine.h
@@ -16,9 +16,9 @@ #include "chrome/browser/chromeos/input_method/input_method_engine_base.h" #include "chrome/browser/chromeos/input_method/suggestion_handler_interface.h" #include "ui/base/ime/candidate_window.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/chromeos/input_method_descriptor.h" #include "ui/base/ime/chromeos/input_method_manager.h" -#include "ui/base/ime/ime_engine_handler_interface.h" #include "url/gurl.h" namespace ui {
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_base.h b/chrome/browser/chromeos/input_method/input_method_engine_base.h index cddcc6c0..82679b9 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_base.h +++ b/chrome/browser/chromeos/input_method/input_method_engine_base.h
@@ -16,9 +16,9 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_observer.h" #include "components/prefs/pref_change_registrar.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/chromeos/input_method_descriptor.h" #include "ui/base/ime/composition_text.h" -#include "ui/base/ime/ime_engine_handler_interface.h" #include "url/gurl.h" namespace ui {
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc index f6cd567c..237e9da 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
@@ -30,13 +30,13 @@ #include "ui/base/ime/chromeos/component_extension_ime_manager.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/ime_bridge.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/chromeos/input_method_descriptor.h" #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h" +#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h" #include "ui/base/ime/composition_text.h" #include "ui/base/ime/dummy_text_input_client.h" -#include "ui/base/ime/ime_engine_handler_interface.h" -#include "ui/base/ime/mock_ime_input_context_handler.h" #include "ui/base/ime/text_input_flags.h" #include "ui/events/event.h" #include "ui/events/keycodes/dom/dom_code.h"
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc index 43687f8..491e74bc 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -22,9 +22,9 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/ime_bridge.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h" -#include "ui/base/ime/ime_engine_handler_interface.h" -#include "ui/base/ime/mock_ime_input_context_handler.h" +#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h" #include "ui/base/ime/text_input_flags.h" #include "ui/events/base_event_utils.h" #include "ui/events/keycodes/dom/dom_code.h"
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.h b/chrome/browser/chromeos/input_method/input_method_manager_impl.h index 0e39f1c2..ffb6117 100644 --- a/chrome/browser/chromeos/input_method/input_method_manager_impl.h +++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.h
@@ -20,9 +20,9 @@ #include "chrome/browser/chromeos/input_method/candidate_window_controller.h" #include "chrome/browser/chromeos/input_method/ime_service_connector.h" #include "chrome/browser/profiles/profile.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/chromeos/input_method_util.h" -#include "ui/base/ime/ime_engine_handler_interface.h" namespace ui { class IMEEngineHandlerInterface;
diff --git a/chrome/browser/chromeos/input_method/mock_input_method_engine.h b/chrome/browser/chromeos/input_method/mock_input_method_engine.h index 1aadbce..b85c3741 100644 --- a/chrome/browser/chromeos/input_method/mock_input_method_engine.h +++ b/chrome/browser/chromeos/input_method/mock_input_method_engine.h
@@ -11,8 +11,8 @@ #include <string> #include <vector> +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/chromeos/input_method_descriptor.h" -#include "ui/base/ime/ime_engine_handler_interface.h" namespace ui { class IMEEngineHandlerInterface;
diff --git a/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc b/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc index 0c6ad14..0ef66980 100644 --- a/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc +++ b/chrome/browser/chromeos/input_method/native_input_method_engine_browsertest.cc
@@ -35,9 +35,9 @@ #include "mojo/core/embedder/embedder.h" #include "ui/aura/window_tree_host.h" #include "ui/base/ime/chromeos/ime_bridge.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/chromeos/input_method_chromeos.h" #include "ui/base/ime/dummy_text_input_client.h" -#include "ui/base/ime/ime_engine_handler_interface.h" #include "ui/base/ime/input_method_delegate.h" #include "ui/base/ime/text_input_flags.h" #include "ui/events/event.h"
diff --git a/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc b/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc new file mode 100644 index 0000000..6823d6cf --- /dev/null +++ b/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc
@@ -0,0 +1,85 @@ +// 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/chromeos/phonehub/phone_hub_manager_factory.h" + +#include "chrome/browser/chromeos/device_sync/device_sync_client_factory.h" +#include "chrome/browser/chromeos/multidevice_setup/multidevice_setup_client_factory.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/profiles/profile.h" +#include "chromeos/components/phonehub/phone_hub_manager.h" +#include "chromeos/constants/chromeos_features.h" +#include "chromeos/services/multidevice_setup/public/cpp/prefs.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" + +namespace chromeos { +namespace phonehub { +namespace { + +bool IsProhibitedByPolicy(Profile* profile) { + return !multidevice_setup::IsFeatureAllowed( + multidevice_setup::mojom::Feature::kPhoneHub, profile->GetPrefs()); +} + +bool IsLoggedInAsPrimaryUser(Profile* profile) { + // Guest/incognito profiles cannot use Phone Hub. + if (profile->IsOffTheRecord()) + return false; + + // Likewise, kiosk users are ineligible. + if (user_manager::UserManager::Get()->IsLoggedInAsAnyKioskApp()) + return false; + + return ProfileHelper::IsPrimaryProfile(profile); +} + +} // namespace + +// static +PhoneHubManager* PhoneHubManagerFactory::GetForProfile(Profile* profile) { + return static_cast<PhoneHubManager*>( + PhoneHubManagerFactory::GetInstance()->GetServiceForBrowserContext( + profile, /*create=*/true)); +} + +// static +PhoneHubManagerFactory* PhoneHubManagerFactory::GetInstance() { + return base::Singleton<PhoneHubManagerFactory>::get(); +} + +PhoneHubManagerFactory::PhoneHubManagerFactory() + : BrowserContextKeyedServiceFactory( + "PhoneHubManager", + BrowserContextDependencyManager::GetInstance()) { + DependsOn(device_sync::DeviceSyncClientFactory::GetInstance()); + DependsOn(multidevice_setup::MultiDeviceSetupClientFactory::GetInstance()); +} + +PhoneHubManagerFactory::~PhoneHubManagerFactory() = default; + +KeyedService* PhoneHubManagerFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + if (!features::IsPhoneHubEnabled()) + return nullptr; + + Profile* profile = Profile::FromBrowserContext(context); + + // Only available to the primary profile. + if (!IsLoggedInAsPrimaryUser(profile)) + return nullptr; + + if (IsProhibitedByPolicy(profile)) + return nullptr; + + return new PhoneHubManager( + device_sync::DeviceSyncClientFactory::GetForProfile(profile), + multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(profile)); +} + +bool PhoneHubManagerFactory::ServiceIsCreatedWithBrowserContext() const { + return true; +} + +} // namespace phonehub +} // namespace chromeos
diff --git a/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.h b/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.h new file mode 100644 index 0000000..c8d0f6f --- /dev/null +++ b/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.h
@@ -0,0 +1,44 @@ +// 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_CHROMEOS_PHONEHUB_PHONE_HUB_MANAGER_FACTORY_H_ +#define CHROME_BROWSER_CHROMEOS_PHONEHUB_PHONE_HUB_MANAGER_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class Profile; + +namespace chromeos { +namespace phonehub { + +class PhoneHubManager; + +class PhoneHubManagerFactory : public BrowserContextKeyedServiceFactory { + public: + // Returns the PhoneHubManager instance associated with |profile|. Null is + // returned if |profile| is not the primary Profile, if the kPhoneHub flag + // is disabled, or if the feature is prohibited by policy. + static PhoneHubManager* GetForProfile(Profile* profile); + + static PhoneHubManagerFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits<PhoneHubManagerFactory>; + + PhoneHubManagerFactory(); + PhoneHubManagerFactory(const PhoneHubManagerFactory&) = delete; + PhoneHubManagerFactory& operator=(const PhoneHubManagerFactory&) = delete; + ~PhoneHubManagerFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; + bool ServiceIsCreatedWithBrowserContext() const override; +}; + +} // namespace phonehub +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_PHONEHUB_PHONE_HUB_MANAGER_FACTORY_H_
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc index a87ac66..2b9c66a 100644 --- a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc
@@ -31,7 +31,8 @@ namespace { // List of policies where variables like ${MACHINE_NAME} should be expanded. -constexpr const char* kPoliciesToExpand[] = {key::kNativePrinters}; +constexpr const char* kPoliciesToExpand[] = {key::kNativePrinters, + key::kPrinters}; // Fetch policy every 90 minutes which matches the Windows default: // https://technet.microsoft.com/en-us/library/cc940895.aspx
diff --git a/chrome/browser/chromeos/policy/arc_app_install_event_log_manager.cc b/chrome/browser/chromeos/policy/arc_app_install_event_log_manager.cc index 44b10dbb..7d460ab 100644 --- a/chrome/browser/chromeos/policy/arc_app_install_event_log_manager.cc +++ b/chrome/browser/chromeos/policy/arc_app_install_event_log_manager.cc
@@ -37,8 +37,8 @@ : InstallEventLogManagerBase(log_task_runner_wrapper, profile), uploader_(uploader) { uploader_->SetDelegate(this); - app_log_upload_ = std::make_unique<AppLogUpload>(this); log_ = std::make_unique<ArcLog>(); + app_log_upload_ = std::make_unique<AppLogUpload>(this); base::PostTaskAndReplyWithResult( log_task_runner_.get(), FROM_HERE, base::BindOnce(&ArcLog::Init, base::Unretained(log_.get()), @@ -49,8 +49,11 @@ } ArcAppInstallEventLogManager::~ArcAppInstallEventLogManager() { - app_log_upload_.reset(); logger_.reset(); + // Destroy |app_log_upload_| after |logger_| otherwise it is possible + // that when we add new logs created through |logger_| cause the crash as + // |app_log_upload_| will be destroyed already. + app_log_upload_.reset(); uploader_->SetDelegate(nullptr); log_task_runner_->DeleteSoon(FROM_HERE, std::move(log_)); } @@ -76,7 +79,7 @@ base::BindOnce(&ArcLog::Add, base::Unretained(log_.get()), packages, event), base::BindOnce(&ArcAppInstallEventLogManager::AppLogUpload::OnLogChange, - base::Unretained(app_log_upload_.get()))); + app_log_upload_->log_weak_factory_.GetWeakPtr())); } void ArcAppInstallEventLogManager::GetAndroidId(
diff --git a/chrome/browser/chromeos/policy/arc_app_install_event_log_manager.h b/chrome/browser/chromeos/policy/arc_app_install_event_log_manager.h index 9526c43..656ff85d 100644 --- a/chrome/browser/chromeos/policy/arc_app_install_event_log_manager.h +++ b/chrome/browser/chromeos/policy/arc_app_install_event_log_manager.h
@@ -102,11 +102,11 @@ // to disk in its destructor. std::unique_ptr<ArcLog> log_; - // Collects log events and passes them to |this|. - std::unique_ptr<AppInstallEventLogger> logger_; - // Handles storing the logs and preparing them for upload. std::unique_ptr<AppLogUpload> app_log_upload_; + + // Collects log events and passes them to |this|. + std::unique_ptr<AppInstallEventLogger> logger_; }; } // namespace policy
diff --git a/chrome/browser/chromeos/policy/extension_install_event_log_manager.cc b/chrome/browser/chromeos/policy/extension_install_event_log_manager.cc index 3ea748ff..2d38fa18 100644 --- a/chrome/browser/chromeos/policy/extension_install_event_log_manager.cc +++ b/chrome/browser/chromeos/policy/extension_install_event_log_manager.cc
@@ -37,8 +37,8 @@ : InstallEventLogManagerBase(log_task_runner_wrapper, profile), uploader_(uploader) { uploader_->SetDelegate(this); - extension_log_upload_ = std::make_unique<ExtensionLogUpload>(this); log_ = std::make_unique<ExtensionLog>(); + extension_log_upload_ = std::make_unique<ExtensionLogUpload>(this); base::PostTaskAndReplyWithResult( log_task_runner_.get(), FROM_HERE, base::BindOnce(&ExtensionLog::Init, base::Unretained(log_.get()), @@ -51,8 +51,11 @@ } ExtensionInstallEventLogManager::~ExtensionInstallEventLogManager() { - extension_log_upload_.reset(); logger_.reset(); + // Destroy |extension_log_upload_| after |logger_| otherwise it is possible + // that when we add new logs created through |logger_| cause the crash as + // |extension_log_upload_| will be destroyed already. + extension_log_upload_.reset(); uploader_->SetDelegate(nullptr); log_task_runner_->DeleteSoon(FROM_HERE, std::move(log_)); } @@ -71,13 +74,17 @@ const em::ExtensionInstallReportLogEvent& event) { if (extensions.empty()) return; + // After |logger_| is destroyed, we do not add any new events. And |log_| is + // destroyed by creating a non nestable task at the end of + // ExtensionInstallEventLogManager destructor, it is safe to use + // base::Unretained(log_.get()) here. base::PostTaskAndReplyWithResult( log_task_runner_.get(), FROM_HERE, base::BindOnce(&ExtensionLog::Add, base::Unretained(log_.get()), std::move(extensions), event), base::BindOnce( &ExtensionInstallEventLogManager::ExtensionLogUpload::OnLogChange, - base::Unretained(extension_log_upload_.get()))); + extension_log_upload_->log_weak_factory_.GetWeakPtr())); } void ExtensionInstallEventLogManager::SerializeExtensionLogForUpload(
diff --git a/chrome/browser/chromeos/policy/extension_install_event_log_manager.h b/chrome/browser/chromeos/policy/extension_install_event_log_manager.h index 7f522ce7..38faddaf 100644 --- a/chrome/browser/chromeos/policy/extension_install_event_log_manager.h +++ b/chrome/browser/chromeos/policy/extension_install_event_log_manager.h
@@ -103,11 +103,11 @@ // to disk in its destructor. std::unique_ptr<ExtensionLog> log_; - // Collects log events and passes them to |this|. - std::unique_ptr<ExtensionInstallEventLogger> logger_; - // Handles storing the logs and preparing them for upload. std::unique_ptr<ExtensionLogUpload> extension_log_upload_; + + // Collects log events and passes them to |this|. + std::unique_ptr<ExtensionInstallEventLogger> logger_; }; } // namespace policy
diff --git a/chrome/browser/chromeos/policy/external_data_handlers/native_printers_external_data_handler.cc b/chrome/browser/chromeos/policy/external_data_handlers/native_printers_external_data_handler.cc index c0d6326..dfc17e99 100644 --- a/chrome/browser/chromeos/policy/external_data_handlers/native_printers_external_data_handler.cc +++ b/chrome/browser/chromeos/policy/external_data_handlers/native_printers_external_data_handler.cc
@@ -33,7 +33,7 @@ DeviceLocalAccountPolicyService* policy_service) : native_printers_observer_(cros_settings, policy_service, - key::kNativePrintersBulkConfiguration, + key::kPrintersBulkConfiguration, this) { native_printers_observer_.Init(); }
diff --git a/chrome/browser/chromeos/printing/enterprise_printers_provider.cc b/chrome/browser/chromeos/printing/enterprise_printers_provider.cc index 5fa2718..3bf97b8d 100644 --- a/chrome/browser/chromeos/printing/enterprise_printers_provider.cc +++ b/chrome/browser/chromeos/printing/enterprise_printers_provider.cc
@@ -90,7 +90,7 @@ // Binds policy with recommended printers (deprecated). This method calls // indirectly RecalculateCurrentPrintersList() that prepares the first // version of final list of printers. - BindPref(prefs::kRecommendedNativePrinters, + BindPref(prefs::kRecommendedPrinters, &EnterprisePrintersProviderImpl::UpdateUserRecommendedPrinters); } @@ -128,8 +128,7 @@ // printers. It is called when value of the policy changes. void UpdateUserRecommendedPrinters() { recommended_printers_.clear(); - std::vector<std::string> data = - FromPrefs(prefs::kRecommendedNativePrinters); + std::vector<std::string> data = FromPrefs(prefs::kRecommendedPrinters); for (const auto& printer_json : data) { base::Optional<base::Value> printer_dictionary = base::JSONReader::Read( printer_json, base::JSON_ALLOW_TRAILING_COMMAS); @@ -174,7 +173,7 @@ user_printers_is_complete_ = user_printers_->IsComplete() && (user_printers_->IsDataPolicySet() || - !PolicyWithDataIsSet(policy::key::kNativePrintersBulkConfiguration)); + !PolicyWithDataIsSet(policy::key::kPrintersBulkConfiguration)); } void RecalculateCompleteFlagForDevicePrinters() { @@ -282,7 +281,7 @@ // static void EnterprisePrintersProvider::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { - registry->RegisterListPref(prefs::kRecommendedNativePrinters); + registry->RegisterListPref(prefs::kRecommendedPrinters); CalculatorsPoliciesBinder::RegisterProfilePrefs(registry); }
diff --git a/chrome/browser/chromeos/printing/enterprise_printers_provider_unittest.cc b/chrome/browser/chromeos/printing/enterprise_printers_provider_unittest.cc index 49199e5..16a191c 100644 --- a/chrome/browser/chromeos/printing/enterprise_printers_provider_unittest.cc +++ b/chrome/browser/chromeos/printing/enterprise_printers_provider_unittest.cc
@@ -98,7 +98,7 @@ sync_preferences::TestingPrefServiceSyncable* prefs = profile_.GetTestingPrefService(); // TestingPrefSyncableService assumes ownership of |value|. - prefs->SetManagedPref(prefs::kRecommendedNativePrinters, std::move(value)); + prefs->SetManagedPref(prefs::kRecommendedPrinters, std::move(value)); } // Must outlive |profile_|.
diff --git a/chrome/browser/chromeos/release_notes/release_notes_storage.cc b/chrome/browser/chromeos/release_notes/release_notes_storage.cc index ba8e1c86..f29c4b5 100644 --- a/chrome/browser/chromeos/release_notes/release_notes_storage.cc +++ b/chrome/browser/chromeos/release_notes/release_notes_storage.cc
@@ -27,7 +27,7 @@ return version_info::GetVersion().components()[0]; } -constexpr int kTimesToShowSuggestionChip = 1; +constexpr int kTimesToShowSuggestionChip = 3; } // namespace
diff --git a/chrome/browser/component_updater/soda_component_installer.cc b/chrome/browser/component_updater/soda_component_installer.cc index 1ca1dc01..07e70ac 100644 --- a/chrome/browser/component_updater/soda_component_installer.cc +++ b/chrome/browser/component_updater/soda_component_installer.cc
@@ -36,9 +36,6 @@ const char kSODAManifestName[] = "SODA Library"; -constexpr base::FilePath::CharType kSodaBinaryRelativePath[] = - FILE_PATH_LITERAL("SODAFiles/libsoda.so"); - constexpr base::FilePath::CharType kSodaEnUsConfigFileRelativePath[] = FILE_PATH_LITERAL("SODAFiles/en_us/dictation.ascii_proto"); @@ -129,7 +126,7 @@ const base::FilePath& install_dir) { #if !defined(OS_ANDROID) prefs->SetFilePath(prefs::kSodaBinaryPath, - install_dir.Append(kSodaBinaryRelativePath)); + install_dir.Append(speech::kSodaBinaryRelativePath)); prefs->SetFilePath(prefs::kSodaEnUsConfigPath, install_dir.Append(kSodaEnUsConfigFileRelativePath)); #endif
diff --git a/chrome/browser/content_settings/OWNERS b/chrome/browser/content_settings/OWNERS index 83eb633..d04971d 100644 --- a/chrome/browser/content_settings/OWNERS +++ b/chrome/browser/content_settings/OWNERS
@@ -1,5 +1,3 @@ -engedy@chromium.org -msramek@chromium.org -raymes@chromium.org +file://components/content_settings/OWNERS # COMPONENT: Internals>Permissions>Model
diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogCoordinator.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogCoordinator.java index 5d512a2..3965f50 100644 --- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogCoordinator.java +++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLaterDialogCoordinator.java
@@ -70,6 +70,7 @@ * @param prefService {@link PrefService} to write download later prompt status preference. * @param model The data model that defines the UI details. */ + // TODO(xingliu): The public showDialog API should use a param instead of exposing the model. public void showDialog(Context context, ModalDialogManager modalDialogManager, PrefService prefService, PropertyModel model) { if (context == null || modalDialogManager == null) { @@ -88,10 +89,13 @@ mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(mDownloadLaterDialogModel, mCustomView, DownloadLaterDialogView.Binder::bind, true /*performInitialBind*/); - mDownloadLaterChoice = model.get(DownloadLaterDialogProperties.INITIAL_CHOICE); // Set up the modal dialog. mDialogModel = getModalDialogModel(context, this); + + // Adjust models based on initial choice. + onChoiceChanged(model.get(DownloadLaterDialogProperties.INITIAL_CHOICE)); + mModalDialogManager.showDialog(mDialogModel, ModalDialogManager.ModalDialogType.APP); } @@ -138,8 +142,6 @@ } private void onPositiveButtonClicked(@DownloadLaterDialogChoice int choice) { - mDownloadLaterChoice = choice; - // Immediately show the date time picker when selecting the "Download later". if (choice == DownloadLaterDialogChoice.DOWNLOAD_LATER) { dismissDialog(DialogDismissalCause.ACTION_ON_CONTENT); @@ -244,6 +246,10 @@ @Override public void onCheckedChanged(@DownloadLaterDialogChoice int choice) { + onChoiceChanged(choice); + } + + private void onChoiceChanged(@DownloadLaterDialogChoice int choice) { @DownloadLaterDialogChoice int previousChoice = mDownloadLaterChoice; mDownloadLaterChoice = choice;
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index 4da81dc..9c7f63d6 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -142,7 +142,7 @@ #include "services/device/public/mojom/wake_lock.mojom.h" #include "services/device/public/mojom/wake_lock_provider.mojom.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/loader/network_utils.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/page_transition_types.h" @@ -3451,8 +3451,8 @@ // resolve referrer_policy() into a concrete policy. auto policy_for_comparison = referrer_policy(); if (policy_for_comparison == network::mojom::ReferrerPolicy::kDefault) { - policy_for_comparison = blink::NetToMojoReferrerPolicy( - content::Referrer::GetDefaultReferrerPolicy()); + policy_for_comparison = blink::ReferrerUtils::NetToMojoReferrerPolicy( + blink::ReferrerUtils::GetDefaultNetReferrerPolicy()); } switch (policy_for_comparison) {
diff --git a/chrome/browser/download/download_shelf.h b/chrome/browser/download/download_shelf.h index 682b6c1..427305d 100644 --- a/chrome/browser/download/download_shelf.h +++ b/chrome/browser/download/download_shelf.h
@@ -60,17 +60,15 @@ // Closes the shelf. void Close(); - // Hides the shelf. This closes the shelf if it is currently showing. + // Closes the shelf and prevents it from reopening until Unhide() is called. void Hide(); - // Unhides the shelf. This will cause the shelf to be opened if it was open - // when it was hidden, or was shown while it was hidden. + // Allows the shelf to open after a previous call to Hide(). Opens the shelf + // if, had Hide() not been called, it would currently be open. void Unhide(); Browser* browser() { return browser_; } - - // Returns whether the download shelf is hidden. - bool is_hidden() { return is_hidden_; } + bool is_hidden() const { return is_hidden_; } protected: virtual void DoShowDownload(DownloadUIModel::DownloadUIModelPtr download) = 0; @@ -86,7 +84,7 @@ Profile* profile() { return profile_; } private: - // Show the download on the shelf immediately. Also displayes the download + // Shows the download on the shelf immediately. Also displays the download // started animation if necessary. void ShowDownload(DownloadUIModel::DownloadUIModelPtr download);
diff --git a/chrome/browser/download/test_download_shelf.h b/chrome/browser/download/test_download_shelf.h index 3ee966e..3fec922 100644 --- a/chrome/browser/download/test_download_shelf.h +++ b/chrome/browser/download/test_download_shelf.h
@@ -21,7 +21,6 @@ bool IsShowing() const override; bool IsClosing() const override; - // Return |true| if a download was added to this shelf. bool did_add_download() const { return did_add_download_; } protected:
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 33570df..814316e 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//build/config/features.gni") import("//build/config/ui.gni") import("//chrome/common/features.gni") @@ -196,6 +197,8 @@ "api/identity/identity_private_api.h", "api/identity/identity_remove_cached_auth_token_function.cc", "api/identity/identity_remove_cached_auth_token_function.h", + "api/identity/identity_token_cache.cc", + "api/identity/identity_token_cache.h", "api/identity/web_auth_flow.cc", "api/identity/web_auth_flow.h", "api/idltest/idltest_api.cc", @@ -753,6 +756,7 @@ "//apps", "//base/util/values:values_util", "//build:branding_buildflags", + "//build:lacros_buildflags", "//chrome:extra_resources", "//chrome:resources", "//chrome:strings", @@ -923,6 +927,20 @@ deps += [ "//components/autofill_assistant/browser" ] } + if (chromeos_is_browser_only || is_chromeos) { + sources += [ "api/enterprise_platform_keys/enterprise_platform_keys_api.h" ] + if (chromeos_is_browser_only) { + sources += [ + "api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.cc", + "api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h", + ] + deps += [ + "//chromeos/crosapi/mojom", + "//chromeos/lacros", + ] + } + } + if (is_chromeos) { sources += [ "api/certificate_provider/certificate_provider_api.cc", @@ -931,8 +949,8 @@ "api/enterprise_device_attributes/enterprise_device_attributes_api.h", "api/enterprise_networking_attributes/enterprise_networking_attributes_api.cc", "api/enterprise_networking_attributes/enterprise_networking_attributes_api.h", - "api/enterprise_platform_keys/enterprise_platform_keys_api.cc", - "api/enterprise_platform_keys/enterprise_platform_keys_api.h", + "api/enterprise_platform_keys/enterprise_platform_keys_api_ash.cc", + "api/enterprise_platform_keys/enterprise_platform_keys_api_ash.h", "api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc", "api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h", "api/file_handlers/non_native_file_system_delegate_chromeos.cc",
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h index 2da73a2..0f2a6ab 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h
@@ -1,135 +1,20 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. +// 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. +// This file is included from autogenerated files based on +// chrome/common/extensions/api/enterprise_platform_keys_internal.idl and +// chrome/common/extensions/api/enterprise_platform_keys.idl. + #ifndef CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_H_ #define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_H_ -#include <memory> -#include <string> -#include <vector> +#include "build/lacros_buildflags.h" -#include "base/memory/ref_counted.h" -#include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" -#include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h" -#include "extensions/browser/extension_function.h" - -namespace net { -class X509Certificate; -using CertificateList = std::vector<scoped_refptr<X509Certificate>>; -} // namespace net - -namespace extensions { - -class EnterprisePlatformKeysInternalGenerateKeyFunction - : public ExtensionFunction { - private: - ~EnterprisePlatformKeysInternalGenerateKeyFunction() override; - ResponseAction Run() override; - - // Called when the key was generated. If an error occurred, |public_key_der| - // will be empty. - void OnGeneratedKey(const std::string& public_key_der, - chromeos::platform_keys::Status status); - - DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysInternal.generateKey", - ENTERPRISE_PLATFORMKEYSINTERNAL_GENERATEKEY) -}; - -class EnterprisePlatformKeysGetCertificatesFunction : public ExtensionFunction { - private: - ~EnterprisePlatformKeysGetCertificatesFunction() override; - ResponseAction Run() override; - - // Called when the list of certificates was determined. If an error occurred, - // |certs| will be nullptr. - void OnGotCertificates(std::unique_ptr<net::CertificateList> certs, - chromeos::platform_keys::Status status); - - DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.getCertificates", - ENTERPRISE_PLATFORMKEYS_GETCERTIFICATES) -}; - -class EnterprisePlatformKeysImportCertificateFunction - : public ExtensionFunction { - private: - ~EnterprisePlatformKeysImportCertificateFunction() override; - ResponseAction Run() override; - - // Called when the certificate was imported. - void OnImportedCertificate(chromeos::platform_keys::Status status); - - DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.importCertificate", - ENTERPRISE_PLATFORMKEYS_IMPORTCERTIFICATE) -}; - -class EnterprisePlatformKeysRemoveCertificateFunction - : public ExtensionFunction { - private: - ~EnterprisePlatformKeysRemoveCertificateFunction() override; - ResponseAction Run() override; - - // Called when the certificate was removed. - void OnRemovedCertificate(chromeos::platform_keys::Status status); - - DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.removeCertificate", - ENTERPRISE_PLATFORMKEYS_REMOVECERTIFICATE) -}; - -class EnterprisePlatformKeysInternalGetTokensFunction - : public ExtensionFunction { - private: - ~EnterprisePlatformKeysInternalGetTokensFunction() override; - ResponseAction Run() override; - - // Called when the list of tokens was determined. If an error occurred, - // |token_ids| will be nullptr. - void OnGotTokens( - std::unique_ptr<std::vector<chromeos::platform_keys::TokenId>> token_ids, - chromeos::platform_keys::Status status); - - DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysInternal.getTokens", - ENTERPRISE_PLATFORMKEYSINTERNAL_GETTOKENS) -}; - -class EnterprisePlatformKeysChallengeMachineKeyFunction - : public ExtensionFunction { - public: - EnterprisePlatformKeysChallengeMachineKeyFunction(); - - private: - ~EnterprisePlatformKeysChallengeMachineKeyFunction() override; - ResponseAction Run() override; - - // Called when the challenge operation is complete. - void OnChallengedKey( - const chromeos::attestation::TpmChallengeKeyResult& result); - - EPKPChallengeKey impl_; - - DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeMachineKey", - ENTERPRISE_PLATFORMKEYS_CHALLENGEMACHINEKEY) -}; - -class EnterprisePlatformKeysChallengeUserKeyFunction - : public ExtensionFunction { - public: - EnterprisePlatformKeysChallengeUserKeyFunction(); - - private: - ~EnterprisePlatformKeysChallengeUserKeyFunction() override; - ResponseAction Run() override; - - // Called when the challenge operation is complete. - void OnChallengedKey( - const chromeos::attestation::TpmChallengeKeyResult& result); - - EPKPChallengeKey impl_; - - DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeUserKey", - ENTERPRISE_PLATFORMKEYS_CHALLENGEUSERKEY) -}; - -} // namespace extensions +#if BUILDFLAG(IS_LACROS) +#include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h" +#else +#include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_ash.h" +#endif #endif // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_H_
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_ash.cc similarity index 99% rename from chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc rename to chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_ash.cc index 4c603a6..df8bfc03 100644 --- a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.cc +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_ash.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/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" +#include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_ash.h" #include <utility>
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_ash.h b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_ash.h new file mode 100644 index 0000000..782e09ea --- /dev/null +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_ash.h
@@ -0,0 +1,135 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_ASH_H_ +#define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_ASH_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/memory/ref_counted.h" +#include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" +#include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h" +#include "extensions/browser/extension_function.h" + +namespace net { +class X509Certificate; +using CertificateList = std::vector<scoped_refptr<X509Certificate>>; +} // namespace net + +namespace extensions { + +class EnterprisePlatformKeysInternalGenerateKeyFunction + : public ExtensionFunction { + private: + ~EnterprisePlatformKeysInternalGenerateKeyFunction() override; + ResponseAction Run() override; + + // Called when the key was generated. If an error occurred, |public_key_der| + // will be empty. + void OnGeneratedKey(const std::string& public_key_der, + chromeos::platform_keys::Status status); + + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysInternal.generateKey", + ENTERPRISE_PLATFORMKEYSINTERNAL_GENERATEKEY) +}; + +class EnterprisePlatformKeysGetCertificatesFunction : public ExtensionFunction { + private: + ~EnterprisePlatformKeysGetCertificatesFunction() override; + ResponseAction Run() override; + + // Called when the list of certificates was determined. If an error occurred, + // |certs| will be nullptr. + void OnGotCertificates(std::unique_ptr<net::CertificateList> certs, + chromeos::platform_keys::Status status); + + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.getCertificates", + ENTERPRISE_PLATFORMKEYS_GETCERTIFICATES) +}; + +class EnterprisePlatformKeysImportCertificateFunction + : public ExtensionFunction { + private: + ~EnterprisePlatformKeysImportCertificateFunction() override; + ResponseAction Run() override; + + // Called when the certificate was imported. + void OnImportedCertificate(chromeos::platform_keys::Status status); + + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.importCertificate", + ENTERPRISE_PLATFORMKEYS_IMPORTCERTIFICATE) +}; + +class EnterprisePlatformKeysRemoveCertificateFunction + : public ExtensionFunction { + private: + ~EnterprisePlatformKeysRemoveCertificateFunction() override; + ResponseAction Run() override; + + // Called when the certificate was removed. + void OnRemovedCertificate(chromeos::platform_keys::Status status); + + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.removeCertificate", + ENTERPRISE_PLATFORMKEYS_REMOVECERTIFICATE) +}; + +class EnterprisePlatformKeysInternalGetTokensFunction + : public ExtensionFunction { + private: + ~EnterprisePlatformKeysInternalGetTokensFunction() override; + ResponseAction Run() override; + + // Called when the list of tokens was determined. If an error occurred, + // |token_ids| will be nullptr. + void OnGotTokens( + std::unique_ptr<std::vector<chromeos::platform_keys::TokenId>> token_ids, + chromeos::platform_keys::Status status); + + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysInternal.getTokens", + ENTERPRISE_PLATFORMKEYSINTERNAL_GETTOKENS) +}; + +class EnterprisePlatformKeysChallengeMachineKeyFunction + : public ExtensionFunction { + public: + EnterprisePlatformKeysChallengeMachineKeyFunction(); + + private: + ~EnterprisePlatformKeysChallengeMachineKeyFunction() override; + ResponseAction Run() override; + + // Called when the challenge operation is complete. + void OnChallengedKey( + const chromeos::attestation::TpmChallengeKeyResult& result); + + EPKPChallengeKey impl_; + + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeMachineKey", + ENTERPRISE_PLATFORMKEYS_CHALLENGEMACHINEKEY) +}; + +class EnterprisePlatformKeysChallengeUserKeyFunction + : public ExtensionFunction { + public: + EnterprisePlatformKeysChallengeUserKeyFunction(); + + private: + ~EnterprisePlatformKeysChallengeUserKeyFunction() override; + ResponseAction Run() override; + + // Called when the challenge operation is complete. + void OnChallengedKey( + const chromeos::attestation::TpmChallengeKeyResult& result); + + EPKPChallengeKey impl_; + + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeUserKey", + ENTERPRISE_PLATFORMKEYS_CHALLENGEUSERKEY) +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_ASH_H_
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.cc b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.cc new file mode 100644 index 0000000..800fbc212 --- /dev/null +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.cc
@@ -0,0 +1,68 @@ +// 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/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "chrome/browser/extensions/api/platform_keys/platform_keys_api.h" +#include "chrome/common/extensions/api/enterprise_platform_keys.h" +#include "chromeos/lacros/lacros_chrome_service_impl.h" + +namespace extensions { + +namespace { + +namespace api_epk = api::enterprise_platform_keys; + +std::vector<uint8_t> VectorFromString(const std::string& s) { + return std::vector<uint8_t>(s.begin(), s.end()); +} + +std::string StringFromVector(const std::vector<uint8_t>& v) { + return std::string(v.begin(), v.end()); +} + +const char kLacrosNotImplementedError[] = "not-implemented-yet-for-lacros"; + +} // namespace + +ExtensionFunction::ResponseAction LacrosNotImplementedExtensionFunction::Run() { + return RespondNow(Error(kLacrosNotImplementedError)); +} + +ExtensionFunction::ResponseAction +EnterprisePlatformKeysChallengeMachineKeyFunction::Run() { + std::unique_ptr<api_epk::ChallengeMachineKey::Params> params( + api_epk::ChallengeMachineKey::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params); + // TODO(https://crbug.com/1113443): This implementation needs to check if the + // extension is allowlisted via the AttestationExtensionWhitelist policy. + auto c = base::BindOnce( + &EnterprisePlatformKeysChallengeMachineKeyFunction::OnChallengedKeyLacros, + this); + chromeos::LacrosChromeServiceImpl::Get()->attestation_remote()->ChallengeKey( + StringFromVector(params->challenge), + crosapi::mojom::ChallengeKeyType::kDevice, std::move(c)); + return RespondLater(); +} + +void EnterprisePlatformKeysChallengeMachineKeyFunction::OnChallengedKeyLacros( + crosapi::mojom::ChallengeKeyResultPtr result) { + switch (result->which()) { + case crosapi::mojom::ChallengeKeyResult::Tag::ERROR_MESSAGE: + Respond(Error(result->get_error_message())); + return; + case crosapi::mojom::ChallengeKeyResult::Tag::CHALLENGE_RESPONSE: + Respond(ArgumentList(api_epk::ChallengeMachineKey::Results::Create( + VectorFromString(result->get_challenge_response())))); + return; + } +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h new file mode 100644 index 0000000..0ffc65c --- /dev/null +++ b/chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h
@@ -0,0 +1,74 @@ +// 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_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_LACROS_H_ +#define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_LACROS_H_ + +#include "chromeos/crosapi/mojom/attestation.mojom.h" +#include "extensions/browser/extension_function.h" + +namespace extensions { + +class LacrosNotImplementedExtensionFunction : public ExtensionFunction { + protected: + ~LacrosNotImplementedExtensionFunction() override = default; + + private: + ResponseAction Run() override; +}; + +class EnterprisePlatformKeysGetCertificatesFunction + : public LacrosNotImplementedExtensionFunction { + private: + ~EnterprisePlatformKeysGetCertificatesFunction() override = default; + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.getCertificates", + ENTERPRISE_PLATFORMKEYS_GETCERTIFICATES) +}; + +class EnterprisePlatformKeysImportCertificateFunction + : public LacrosNotImplementedExtensionFunction { + private: + ~EnterprisePlatformKeysImportCertificateFunction() override = default; + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.importCertificate", + ENTERPRISE_PLATFORMKEYS_IMPORTCERTIFICATE) +}; + +class EnterprisePlatformKeysRemoveCertificateFunction + : public LacrosNotImplementedExtensionFunction { + private: + ~EnterprisePlatformKeysRemoveCertificateFunction() override = default; + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.removeCertificate", + ENTERPRISE_PLATFORMKEYS_REMOVECERTIFICATE) +}; + +class EnterprisePlatformKeysInternalGetTokensFunction + : public LacrosNotImplementedExtensionFunction { + private: + ~EnterprisePlatformKeysInternalGetTokensFunction() override = default; + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysInternal.getTokens", + ENTERPRISE_PLATFORMKEYSINTERNAL_GETTOKENS) +}; + +class EnterprisePlatformKeysChallengeMachineKeyFunction + : public ExtensionFunction { + private: + ~EnterprisePlatformKeysChallengeMachineKeyFunction() override = default; + ResponseAction Run() override; + + void OnChallengedKeyLacros(crosapi::mojom::ChallengeKeyResultPtr result); + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeMachineKey", + ENTERPRISE_PLATFORMKEYS_CHALLENGEMACHINEKEY) +}; + +class EnterprisePlatformKeysChallengeUserKeyFunction + : public LacrosNotImplementedExtensionFunction { + private: + ~EnterprisePlatformKeysChallengeUserKeyFunction() override = default; + DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeUserKey", + ENTERPRISE_PLATFORMKEYS_CHALLENGEUSERKEY) +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_LACROS_H_
diff --git a/chrome/browser/extensions/api/identity/identity_api.cc b/chrome/browser/extensions/api/identity/identity_api.cc index 9fdcd93..37858091 100644 --- a/chrome/browser/extensions/api/identity/identity_api.cc +++ b/chrome/browser/extensions/api/identity/identity_api.cc
@@ -6,9 +6,7 @@ #include <stddef.h> -#include <algorithm> #include <memory> -#include <set> #include <string> #include <utility> #include <vector> @@ -23,7 +21,6 @@ #include "chrome/browser/app_mode/app_mode_utils.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" -#include "chrome/browser/extensions/api/identity/identity_constants.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/account_consistency_mode_manager.h" @@ -47,99 +44,6 @@ const char kIdentityGaiaIdPref[] = "identity_gaia_id"; } -IdentityTokenCacheValue::IdentityTokenCacheValue() = default; -IdentityTokenCacheValue::IdentityTokenCacheValue( - const IdentityTokenCacheValue& other) = default; -IdentityTokenCacheValue::~IdentityTokenCacheValue() = default; - -// static -IdentityTokenCacheValue IdentityTokenCacheValue::CreateIssueAdvice( - const IssueAdviceInfo& issue_advice) { - IdentityTokenCacheValue cache_value; - cache_value.status_ = CACHE_STATUS_ADVICE; - cache_value.issue_advice_ = issue_advice; - cache_value.expiration_time_ = - base::Time::Now() + base::TimeDelta::FromSeconds( - identity_constants::kCachedIssueAdviceTTLSeconds); - return cache_value; -} - -// static -IdentityTokenCacheValue IdentityTokenCacheValue::CreateRemoteConsent( - const RemoteConsentResolutionData& resolution_data) { - IdentityTokenCacheValue cache_value; - cache_value.status_ = CACHE_STATUS_REMOTE_CONSENT; - cache_value.resolution_data_ = resolution_data; - cache_value.expiration_time_ = - base::Time::Now() + base::TimeDelta::FromSeconds( - identity_constants::kCachedIssueAdviceTTLSeconds); - return cache_value; -} - -// static -IdentityTokenCacheValue IdentityTokenCacheValue::CreateRemoteConsentApproved( - const std::string& consent_result) { - IdentityTokenCacheValue cache_value; - cache_value.status_ = CACHE_STATUS_REMOTE_CONSENT_APPROVED; - cache_value.consent_result_ = consent_result; - cache_value.expiration_time_ = - base::Time::Now() + base::TimeDelta::FromSeconds( - identity_constants::kCachedIssueAdviceTTLSeconds); - return cache_value; -} - -// static -IdentityTokenCacheValue IdentityTokenCacheValue::CreateToken( - const std::string& token, - base::TimeDelta time_to_live) { - IdentityTokenCacheValue cache_value; - cache_value.status_ = CACHE_STATUS_TOKEN; - cache_value.token_ = token; - - // Remove 20 minutes from the ttl so cached tokens will have some time - // to live any time they are returned. - time_to_live -= base::TimeDelta::FromMinutes(20); - - base::TimeDelta zero_delta; - if (time_to_live < zero_delta) - time_to_live = zero_delta; - - cache_value.expiration_time_ = base::Time::Now() + time_to_live; - return cache_value; -} - -IdentityTokenCacheValue::CacheValueStatus IdentityTokenCacheValue::status() - const { - if (is_expired()) - return IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND; - else - return status_; -} - -const IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const { - return issue_advice_; -} - -const RemoteConsentResolutionData& IdentityTokenCacheValue::resolution_data() - const { - return resolution_data_; -} - -const std::string& IdentityTokenCacheValue::consent_result() const { - return consent_result_; -} - -const std::string& IdentityTokenCacheValue::token() const { return token_; } - -bool IdentityTokenCacheValue::is_expired() const { - return status_ == CACHE_STATUS_NOTFOUND || - expiration_time_ < base::Time::Now(); -} - -const base::Time& IdentityTokenCacheValue::expiration_time() const { - return expiration_time_; -} - IdentityAPI::IdentityAPI(content::BrowserContext* context) : IdentityAPI(Profile::FromBrowserContext(context), IdentityManagerFactory::GetForProfile( @@ -151,37 +55,8 @@ IdentityMintRequestQueue* IdentityAPI::mint_queue() { return &mint_queue_; } -void IdentityAPI::SetCachedToken(const ExtensionTokenKey& key, - const IdentityTokenCacheValue& token_data) { - auto it = token_cache_.find(key); - if (it != token_cache_.end() && it->second.status() <= token_data.status()) - token_cache_.erase(it); - - token_cache_.insert(std::make_pair(key, token_data)); -} - -void IdentityAPI::EraseCachedToken(const std::string& extension_id, - const std::string& token) { - CachedTokens::iterator it; - for (it = token_cache_.begin(); it != token_cache_.end(); ++it) { - if (it->first.extension_id == extension_id && - it->second.status() == IdentityTokenCacheValue::CACHE_STATUS_TOKEN && - it->second.token() == token) { - token_cache_.erase(it); - break; - } - } -} - -void IdentityAPI::EraseAllCachedTokens() { token_cache_.clear(); } - -const IdentityTokenCacheValue& IdentityAPI::GetCachedToken( - const ExtensionTokenKey& key) { - return token_cache_[key]; -} - -const IdentityAPI::CachedTokens& IdentityAPI::GetAllCachedTokens() { - return token_cache_; +IdentityTokenCache* IdentityAPI::token_cache() { + return &token_cache_; } void IdentityAPI::SetGaiaIdForExtension(const std::string& extension_id,
diff --git a/chrome/browser/extensions/api/identity/identity_api.h b/chrome/browser/extensions/api/identity/identity_api.h index 57ce9ff..1b9db68 100644 --- a/chrome/browser/extensions/api/identity/identity_api.h +++ b/chrome/browser/extensions/api/identity/identity_api.h
@@ -5,11 +5,8 @@ #ifndef CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_API_H_ #define CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_API_H_ -#include <map> -#include <set> #include <string> #include <utility> -#include <vector> #include "base/callback_list.h" #include "base/feature_list.h" @@ -20,7 +17,6 @@ #include "base/optional.h" #include "build/build_config.h" #include "build/buildflag.h" -#include "chrome/browser/extensions/api/identity/extension_token_key.h" #include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h" #include "chrome/browser/extensions/api/identity/identity_get_accounts_function.h" #include "chrome/browser/extensions/api/identity/identity_get_auth_token_function.h" @@ -28,6 +24,7 @@ #include "chrome/browser/extensions/api/identity/identity_launch_web_auth_flow_function.h" #include "chrome/browser/extensions/api/identity/identity_mint_queue.h" #include "chrome/browser/extensions/api/identity/identity_remove_cached_auth_token_function.h" +#include "chrome/browser/extensions/api/identity/identity_token_cache.h" #include "chrome/browser/extensions/api/identity/web_auth_flow.h" #include "components/signin/public/base/signin_buildflags.h" #include "components/signin/public/identity_manager/identity_manager.h" @@ -42,53 +39,9 @@ namespace extensions { -class IdentityTokenCacheValue { - public: - IdentityTokenCacheValue(); - IdentityTokenCacheValue(const IdentityTokenCacheValue& other); - ~IdentityTokenCacheValue(); - - static IdentityTokenCacheValue CreateIssueAdvice( - const IssueAdviceInfo& issue_advice); - static IdentityTokenCacheValue CreateRemoteConsent( - const RemoteConsentResolutionData& resolution_data); - static IdentityTokenCacheValue CreateRemoteConsentApproved( - const std::string& consent_result); - static IdentityTokenCacheValue CreateToken(const std::string& token, - base::TimeDelta time_to_live); - - // Order of these entries is used to determine whether or not new - // entries supersede older ones in SetCachedToken. - enum CacheValueStatus { - CACHE_STATUS_NOTFOUND, - CACHE_STATUS_ADVICE, - CACHE_STATUS_REMOTE_CONSENT, - CACHE_STATUS_REMOTE_CONSENT_APPROVED, - CACHE_STATUS_TOKEN - }; - - CacheValueStatus status() const; - const IssueAdviceInfo& issue_advice() const; - const RemoteConsentResolutionData& resolution_data() const; - const std::string& consent_result() const; - const std::string& token() const; - const base::Time& expiration_time() const; - - private: - bool is_expired() const; - - CacheValueStatus status_ = CACHE_STATUS_NOTFOUND; - IssueAdviceInfo issue_advice_; - RemoteConsentResolutionData resolution_data_; - std::string consent_result_; - std::string token_; - base::Time expiration_time_; -}; - class IdentityAPI : public BrowserContextKeyedAPI, public signin::IdentityManager::Observer { public: - using CachedTokens = std::map<ExtensionTokenKey, IdentityTokenCacheValue>; using OnSetConsentResultSignature = void(const std::string&, const std::string&); @@ -98,14 +51,7 @@ // Request serialization queue for getAuthToken. IdentityMintRequestQueue* mint_queue(); - // Token cache. - void SetCachedToken(const ExtensionTokenKey& key, - const IdentityTokenCacheValue& token_data); - void EraseCachedToken(const std::string& extension_id, - const std::string& token); - void EraseAllCachedTokens(); - const IdentityTokenCacheValue& GetCachedToken(const ExtensionTokenKey& key); - const CachedTokens& GetAllCachedTokens(); + IdentityTokenCache* token_cache(); // GAIA id cache. void SetGaiaIdForExtension(const std::string& extension_id, @@ -180,7 +126,7 @@ EventRouter* const event_router_; IdentityMintRequestQueue mint_queue_; - CachedTokens token_cache_; + IdentityTokenCache token_cache_; OnSignInChangedCallback on_signin_changed_callback_for_testing_;
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc index 3dae5c09..2eabfc3 100644 --- a/chrome/browser/extensions/api/identity/identity_apitest.cc +++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -940,7 +940,7 @@ void SetCachedTokenForAccount(const CoreAccountId account_id, const IdentityTokenCacheValue& token_data) { ExtensionTokenKey key(extension_id_, account_id, oauth_scopes_); - id_api()->SetCachedToken(key, token_data); + id_api()->token_cache()->SetToken(key, token_data); } void SetCachedGaiaId(const std::string& gaia_id) { @@ -952,7 +952,7 @@ ExtensionTokenKey key( extension_id_, account_id.empty() ? GetPrimaryAccountId() : account_id, oauth_scopes_); - return id_api()->GetCachedToken(key); + return id_api()->token_cache()->GetToken(key); } base::Optional<std::string> GetCachedGaiaId() { @@ -1603,7 +1603,7 @@ func->set_extension(extension.get()); // Make sure we don't get a cached issue_advice result, which would cause // flow to be leaked. - id_api()->EraseAllCachedTokens(); + id_api()->token_cache()->EraseAllTokens(); func->push_mint_token_result(TestOAuth2MintTokenFlow::ISSUE_ADVICE_SUCCESS); func->set_scope_ui_oauth_error(test_case.oauth_error); std::string error = utils::RunFunctionAndReturnError( @@ -2965,11 +2965,11 @@ void SetCachedToken(const IdentityTokenCacheValue& token_data) { ExtensionTokenKey key(kExtensionId, CoreAccountId("test@example.com"), std::set<std::string>()); - id_api()->SetCachedToken(key, token_data); + id_api()->token_cache()->SetToken(key, token_data); } const IdentityTokenCacheValue& GetCachedToken() { - return id_api()->GetCachedToken( + return id_api()->token_cache()->GetToken( ExtensionTokenKey(kExtensionId, CoreAccountId("test@example.com"), std::set<std::string>())); }
diff --git a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc index 0ec37d5..0b05d6d 100644 --- a/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc +++ b/chrome/browser/extensions/api/identity/identity_get_auth_token_function.cc
@@ -376,7 +376,7 @@ // All cached tokens are invalid because the user is not signed in. IdentityAPI* id_api = extensions::IdentityAPI::GetFactoryInstance()->Get(GetProfile()); - id_api->EraseAllCachedTokens(); + id_api->token_cache()->EraseAllTokens(); // If the signin flow fails, don't display the login prompt again. should_prompt_for_signin_ = false; @@ -475,7 +475,8 @@ const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension()); IdentityAPI* id_api = IdentityAPI::GetFactoryInstance()->Get(GetProfile()); - IdentityTokenCacheValue cache_entry = id_api->GetCachedToken(token_key_); + IdentityTokenCacheValue cache_entry = + id_api->token_cache()->GetToken(token_key_); IdentityTokenCacheValue::CacheValueStatus cache_status = cache_entry.status(); if (type == IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE) { @@ -577,7 +578,8 @@ access_token, base::TimeDelta::FromSeconds(time_to_live)); IdentityAPI::GetFactoryInstance() ->Get(GetProfile()) - ->SetCachedToken(token_key_, token); + ->token_cache() + ->SetToken(token_key_, token); CompleteMintTokenFlow(); CompleteFunctionWithResult(access_token, granted_scopes); @@ -617,7 +619,7 @@ IdentityAPI* identity_api = IdentityAPI::GetFactoryInstance()->Get(GetProfile()); - identity_api->SetCachedToken( + identity_api->token_cache()->SetToken( token_key_, IdentityTokenCacheValue::CreateIssueAdvice(issue_advice)); // IssueAdvice doesn't communicate back to Chrome which account has been // chosen by the user. Cached gaia id may contain incorrect information so @@ -639,8 +641,9 @@ IdentityAPI::GetFactoryInstance() ->Get(GetProfile()) - ->SetCachedToken(token_key_, IdentityTokenCacheValue::CreateRemoteConsent( - resolution_data)); + ->token_cache() + ->SetToken(token_key_, + IdentityTokenCacheValue::CreateRemoteConsent(resolution_data)); should_prompt_for_signin_ = false; resolution_data_ = resolution_data; CompleteMintTokenFlow(); @@ -759,7 +762,8 @@ access_token, base::TimeDelta::FromSeconds(time_to_live)); IdentityAPI::GetFactoryInstance() ->Get(GetProfile()) - ->SetCachedToken(token_key_, token_value); + ->token_cache() + ->SetToken(token_key_, token_value); } CompleteMintTokenFlow(); @@ -842,7 +846,7 @@ // as this call may start a new request synchronously and query the cache. ExtensionTokenKey new_token_key(token_key_); new_token_key.account_id = account->account_id; - id_api->SetCachedToken( + id_api->token_cache()->SetToken( new_token_key, IdentityTokenCacheValue::CreateRemoteConsentApproved(consent_result)); CompleteMintTokenFlow();
diff --git a/chrome/browser/extensions/api/identity/identity_remove_cached_auth_token_function.cc b/chrome/browser/extensions/api/identity/identity_remove_cached_auth_token_function.cc index 2432129..3224e690 100644 --- a/chrome/browser/extensions/api/identity/identity_remove_cached_auth_token_function.cc +++ b/chrome/browser/extensions/api/identity/identity_remove_cached_auth_token_function.cc
@@ -26,7 +26,8 @@ EXTENSION_FUNCTION_VALIDATE(params.get()); IdentityAPI::GetFactoryInstance() ->Get(browser_context()) - ->EraseCachedToken(extension()->id(), params->details.token); + ->token_cache() + ->EraseToken(extension()->id(), params->details.token); return RespondNow(NoArguments()); }
diff --git a/chrome/browser/extensions/api/identity/identity_token_cache.cc b/chrome/browser/extensions/api/identity/identity_token_cache.cc new file mode 100644 index 0000000..3f2dc69e --- /dev/null +++ b/chrome/browser/extensions/api/identity/identity_token_cache.cc
@@ -0,0 +1,149 @@ +// 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/extensions/api/identity/identity_token_cache.h" + +#include <algorithm> + +#include "base/stl_util.h" +#include "chrome/browser/extensions/api/identity/identity_constants.h" + +namespace extensions { + +IdentityTokenCacheValue::IdentityTokenCacheValue() = default; +IdentityTokenCacheValue::IdentityTokenCacheValue( + const IdentityTokenCacheValue& other) = default; +IdentityTokenCacheValue& IdentityTokenCacheValue::operator=( + const IdentityTokenCacheValue& other) = default; +IdentityTokenCacheValue::~IdentityTokenCacheValue() = default; + +// static +IdentityTokenCacheValue IdentityTokenCacheValue::CreateIssueAdvice( + const IssueAdviceInfo& issue_advice) { + IdentityTokenCacheValue cache_value; + cache_value.status_ = CACHE_STATUS_ADVICE; + cache_value.issue_advice_ = issue_advice; + cache_value.expiration_time_ = + base::Time::Now() + base::TimeDelta::FromSeconds( + identity_constants::kCachedIssueAdviceTTLSeconds); + return cache_value; +} + +// static +IdentityTokenCacheValue IdentityTokenCacheValue::CreateRemoteConsent( + const RemoteConsentResolutionData& resolution_data) { + IdentityTokenCacheValue cache_value; + cache_value.status_ = CACHE_STATUS_REMOTE_CONSENT; + cache_value.resolution_data_ = resolution_data; + cache_value.expiration_time_ = + base::Time::Now() + base::TimeDelta::FromSeconds( + identity_constants::kCachedIssueAdviceTTLSeconds); + return cache_value; +} + +// static +IdentityTokenCacheValue IdentityTokenCacheValue::CreateRemoteConsentApproved( + const std::string& consent_result) { + IdentityTokenCacheValue cache_value; + cache_value.status_ = CACHE_STATUS_REMOTE_CONSENT_APPROVED; + cache_value.consent_result_ = consent_result; + cache_value.expiration_time_ = + base::Time::Now() + base::TimeDelta::FromSeconds( + identity_constants::kCachedIssueAdviceTTLSeconds); + return cache_value; +} + +// static +IdentityTokenCacheValue IdentityTokenCacheValue::CreateToken( + const std::string& token, + base::TimeDelta time_to_live) { + IdentityTokenCacheValue cache_value; + cache_value.status_ = CACHE_STATUS_TOKEN; + cache_value.token_ = token; + + // Remove 20 minutes from the ttl so cached tokens will have some time + // to live any time they are returned. + time_to_live -= base::TimeDelta::FromMinutes(20); + + base::TimeDelta zero_delta; + if (time_to_live < zero_delta) + time_to_live = zero_delta; + + cache_value.expiration_time_ = base::Time::Now() + time_to_live; + return cache_value; +} + +IdentityTokenCacheValue::CacheValueStatus IdentityTokenCacheValue::status() + const { + if (is_expired()) + return IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND; + else + return status_; +} + +bool IdentityTokenCacheValue::is_expired() const { + return status_ == CACHE_STATUS_NOTFOUND || + expiration_time_ < base::Time::Now(); +} + +const base::Time& IdentityTokenCacheValue::expiration_time() const { + return expiration_time_; +} + +const IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const { + return issue_advice_; +} + +const RemoteConsentResolutionData& IdentityTokenCacheValue::resolution_data() + const { + return resolution_data_; +} + +const std::string& IdentityTokenCacheValue::consent_result() const { + return consent_result_; +} + +const std::string& IdentityTokenCacheValue::token() const { + return token_; +} + +IdentityTokenCache::IdentityTokenCache() = default; +IdentityTokenCache::~IdentityTokenCache() = default; + +void IdentityTokenCache::SetToken(const ExtensionTokenKey& key, + const IdentityTokenCacheValue& token_data) { + auto it = token_cache_.find(key); + if (it != token_cache_.end() && it->second.status() <= token_data.status()) + token_cache_.erase(it); + + token_cache_.insert(std::make_pair(key, token_data)); +} + +void IdentityTokenCache::EraseToken(const std::string& extension_id, + const std::string& token) { + CachedTokens::iterator it; + for (it = token_cache_.begin(); it != token_cache_.end(); ++it) { + if (it->first.extension_id == extension_id && + it->second.status() == IdentityTokenCacheValue::CACHE_STATUS_TOKEN && + it->second.token() == token) { + token_cache_.erase(it); + break; + } + } +} + +void IdentityTokenCache::EraseAllTokens() { + token_cache_.clear(); +} + +const IdentityTokenCacheValue& IdentityTokenCache::GetToken( + const ExtensionTokenKey& key) { + return token_cache_[key]; +} + +const IdentityTokenCache::CachedTokens& IdentityTokenCache::GetAllTokens() { + return token_cache_; +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/api/identity/identity_token_cache.h b/chrome/browser/extensions/api/identity/identity_token_cache.h new file mode 100644 index 0000000..0060c95 --- /dev/null +++ b/chrome/browser/extensions/api/identity/identity_token_cache.h
@@ -0,0 +1,95 @@ +// 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_EXTENSIONS_API_IDENTITY_IDENTITY_TOKEN_CACHE_H_ +#define CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_TOKEN_CACHE_H_ + +#include <map> +#include <set> +#include <string> + +#include "base/time/time.h" +#include "chrome/browser/extensions/api/identity/extension_token_key.h" +#include "google_apis/gaia/oauth2_mint_token_flow.h" + +namespace extensions { + +class IdentityTokenCacheValue { + public: + IdentityTokenCacheValue(); + IdentityTokenCacheValue(const IdentityTokenCacheValue& other); + IdentityTokenCacheValue& operator=(const IdentityTokenCacheValue& other); + ~IdentityTokenCacheValue(); + + static IdentityTokenCacheValue CreateIssueAdvice( + const IssueAdviceInfo& issue_advice); + static IdentityTokenCacheValue CreateRemoteConsent( + const RemoteConsentResolutionData& resolution_data); + static IdentityTokenCacheValue CreateRemoteConsentApproved( + const std::string& consent_result); + static IdentityTokenCacheValue CreateToken(const std::string& token, + base::TimeDelta time_to_live); + + // Order of these entries is used to determine whether or not new + // entries supersede older ones in SetCachedToken. + enum CacheValueStatus { + CACHE_STATUS_NOTFOUND, + CACHE_STATUS_ADVICE, + CACHE_STATUS_REMOTE_CONSENT, + CACHE_STATUS_REMOTE_CONSENT_APPROVED, + CACHE_STATUS_TOKEN + }; + + CacheValueStatus status() const; + const base::Time& expiration_time() const; + + const IssueAdviceInfo& issue_advice() const; + const RemoteConsentResolutionData& resolution_data() const; + const std::string& consent_result() const; + const std::string& token() const; + + private: + bool is_expired() const; + + CacheValueStatus status_ = CACHE_STATUS_NOTFOUND; + base::Time expiration_time_; + + // TODO(alexilin): This class holds at any given time one of the several + // possible types. Consider rewriting using absl::variant + IssueAdviceInfo issue_advice_; + RemoteConsentResolutionData resolution_data_; + std::string consent_result_; + std::string token_; +}; + +// In-memory cache of OAuth2 access tokens that are requested by extensions +// through the `getAuthToken` API. Also caches intermediate short-lived values +// used at different stages of the `getAuthToken` flow before a token is +// obtained. The cache automatically handles token expiration. Extensions can +// manually remove tokens from the cache using `removeCachedAuthToken` API. +// +// chrome://identity-internals provides a view of cache's content for debugging. +class IdentityTokenCache { + public: + IdentityTokenCache(); + ~IdentityTokenCache(); + IdentityTokenCache(const IdentityTokenCache& other) = delete; + IdentityTokenCache& operator=(const IdentityTokenCache& other) = delete; + + using CachedTokens = std::map<ExtensionTokenKey, IdentityTokenCacheValue>; + + void SetToken(const ExtensionTokenKey& key, + const IdentityTokenCacheValue& token_data); + void EraseToken(const std::string& extension_id, const std::string& token); + void EraseAllTokens(); + const IdentityTokenCacheValue& GetToken(const ExtensionTokenKey& key); + const CachedTokens& GetAllTokens(); + + private: + CachedTokens token_cache_; +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_TOKEN_CACHE_H_
diff --git a/chrome/browser/extensions/api/identity/identity_token_cache_unittest.cc b/chrome/browser/extensions/api/identity/identity_token_cache_unittest.cc new file mode 100644 index 0000000..1b1fd6e --- /dev/null +++ b/chrome/browser/extensions/api/identity/identity_token_cache_unittest.cc
@@ -0,0 +1,218 @@ +// 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/extensions/api/identity/identity_token_cache.h" + +#include <set> +#include <string> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace extensions { + +namespace { + +const char kDefaultExtensionId[] = "ext_id"; + +} // namespace + +class IdentityTokenCacheTest : public testing::Test { + public: + void SetAccessToken(const std::string& ext_id, + const std::string& token_string, + const std::set<std::string>& scopes) { + ExtensionTokenKey key(ext_id, CoreAccountId(), scopes); + + IdentityTokenCacheValue token = IdentityTokenCacheValue::CreateToken( + token_string, base::TimeDelta::FromSeconds(3600)); + cache_.SetToken(key, token); + } + + void SetRemoteConsentApprovedToken(const std::string& ext_id, + const std::string& consent_result, + const std::set<std::string>& scopes) { + ExtensionTokenKey key(ext_id, CoreAccountId(), scopes); + IdentityTokenCacheValue token = + IdentityTokenCacheValue::CreateRemoteConsentApproved(consent_result); + cache_.SetToken(key, token); + } + + const IdentityTokenCacheValue& GetToken(const std::string& ext_id, + const std::set<std::string>& scopes) { + ExtensionTokenKey key(ext_id, CoreAccountId(), scopes); + return cache_.GetToken(key); + } + + IdentityTokenCache& cache() { return cache_; } + + private: + IdentityTokenCache cache_; +}; + +TEST_F(IdentityTokenCacheTest, AccessTokenCacheHit) { + std::string token_string = "token"; + std::set<std::string> scopes = {"foo", "bar"}; + SetAccessToken(kDefaultExtensionId, token_string, scopes); + + const IdentityTokenCacheValue& cached_token = + GetToken(kDefaultExtensionId, scopes); + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, cached_token.status()); + EXPECT_EQ(token_string, cached_token.token()); +} + +TEST_F(IdentityTokenCacheTest, IntermediateValueCacheHit) { + std::string consent_result = "result"; + std::set<std::string> scopes = {"foo", "bar"}; + SetRemoteConsentApprovedToken(kDefaultExtensionId, consent_result, scopes); + + const IdentityTokenCacheValue& cached_token = + GetToken(kDefaultExtensionId, scopes); + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_REMOTE_CONSENT_APPROVED, + cached_token.status()); + EXPECT_EQ(consent_result, cached_token.consent_result()); +} + +TEST_F(IdentityTokenCacheTest, CacheHitPriority) { + std::string token_string = "token"; + std::set<std::string> scopes = {"foo", "bar"}; + SetAccessToken(kDefaultExtensionId, token_string, scopes); + SetRemoteConsentApprovedToken(kDefaultExtensionId, "result", scopes); + + // Prioritize access tokens over immediate values. + const IdentityTokenCacheValue& cached_token = + GetToken(kDefaultExtensionId, scopes); + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, cached_token.status()); + EXPECT_EQ(token_string, cached_token.token()); +} + +TEST_F(IdentityTokenCacheTest, AccessTokenCacheMiss) { + std::string ext_1 = "ext_1"; + std::set<std::string> scopes_1 = {"foo", "bar"}; + SetAccessToken(ext_1, "token_1", scopes_1); + + std::string ext_2 = "ext_2"; + std::set<std::string> scopes_2 = {"foo", "foobar"}; + SetAccessToken(ext_2, "token_2", scopes_2); + + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND, + GetToken(ext_2, scopes_1).status()); +} + +TEST_F(IdentityTokenCacheTest, IntermediateValueCacheMiss) { + std::string ext_1 = "ext_1"; + std::set<std::string> scopes_1 = {"foo", "bar"}; + SetRemoteConsentApprovedToken(ext_1, "result_1", scopes_1); + + std::string ext_2 = "ext_2"; + std::set<std::string> scopes_2 = {"foo", "foobar"}; + SetRemoteConsentApprovedToken(ext_2, "result_2", scopes_2); + + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND, + GetToken(ext_2, scopes_1).status()); +} + +TEST_F(IdentityTokenCacheTest, EraseToken) { + std::string token_string = "token"; + std::set<std::string> scopes = {"foo", "bar"}; + SetAccessToken(kDefaultExtensionId, token_string, scopes); + + cache().EraseToken(kDefaultExtensionId, token_string); + + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND, + GetToken(kDefaultExtensionId, scopes).status()); +} + +TEST_F(IdentityTokenCacheTest, EraseTokenOthersUnaffected) { + std::string token_string = "token"; + std::set<std::string> scopes = {"foo", "bar"}; + SetAccessToken(kDefaultExtensionId, token_string, scopes); + + std::string unrelated_token_string = "unrelated_token"; + std::set<std::string> unrelated_scopes = {"foo", "foobar"}; + SetAccessToken(kDefaultExtensionId, unrelated_token_string, unrelated_scopes); + + cache().EraseToken(kDefaultExtensionId, token_string); + + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND, + GetToken(kDefaultExtensionId, scopes).status()); + + const IdentityTokenCacheValue& cached_token = + GetToken(kDefaultExtensionId, unrelated_scopes); + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, cached_token.status()); + EXPECT_EQ(unrelated_token_string, cached_token.token()); +} + +TEST_F(IdentityTokenCacheTest, EraseAllTokens) { + std::string ext_1 = "ext_1"; + std::string token_string = "token_1"; + std::set<std::string> scopes_1 = {"foo", "bar"}; + SetAccessToken(ext_1, token_string, scopes_1); + + std::string ext_2 = "ext_2"; + std::string remote_consent = "approved"; + std::set<std::string> scopes_2 = {"foo", "foobar"}; + SetRemoteConsentApprovedToken(ext_2, remote_consent, scopes_2); + + cache().EraseAllTokens(); + + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND, + GetToken(ext_1, scopes_1).status()); + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND, + GetToken(ext_2, scopes_2).status()); +} + +TEST_F(IdentityTokenCacheTest, GetAllTokens) { + std::string ext_1 = "ext_1"; + std::string token_string_1 = "token_1"; + std::set<std::string> scopes_1 = {"foo", "bar"}; + SetAccessToken(ext_1, token_string_1, scopes_1); + + std::string ext_2 = "ext_2"; + std::string token_string_2 = "token_2"; + std::set<std::string> scopes_2 = {"foobar"}; + SetAccessToken(ext_2, token_string_2, scopes_2); + + IdentityTokenCache::CachedTokens cached_tokens = cache().GetAllTokens(); + EXPECT_EQ(2ul, cached_tokens.size()); + + ExtensionTokenKey key_1(ext_1, CoreAccountId(), scopes_1); + const IdentityTokenCacheValue& cached_token_1 = cached_tokens[key_1]; + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, + cached_token_1.status()); + EXPECT_EQ(token_string_1, cached_token_1.token()); + + ExtensionTokenKey key_2(ext_2, CoreAccountId(), scopes_2); + const IdentityTokenCacheValue& cached_token_2 = cached_tokens[key_2]; + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_TOKEN, + cached_token_2.status()); + EXPECT_EQ(token_string_2, cached_token_2.token()); +} + +// Newly cached access tokens should override previously cached values with the +// same scopes. +TEST_F(IdentityTokenCacheTest, OverrideAccessToken) { + std::set<std::string> scopes = {"foo", "bar", "foobar"}; + SetAccessToken(kDefaultExtensionId, "token1", scopes); + + std::string override_token = "token_2"; + SetAccessToken(kDefaultExtensionId, override_token, scopes); + cache().EraseToken(kDefaultExtensionId, override_token); + + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND, + GetToken(kDefaultExtensionId, scopes).status()); +} + +TEST_F(IdentityTokenCacheTest, OverrideIntermediateToken) { + std::set<std::string> scopes = {"foo", "bar", "foobar"}; + SetRemoteConsentApprovedToken(kDefaultExtensionId, "result", scopes); + + std::string override_token = "token"; + SetAccessToken(kDefaultExtensionId, override_token, scopes); + cache().EraseToken(kDefaultExtensionId, override_token); + + EXPECT_EQ(IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND, + GetToken(kDefaultExtensionId, scopes).status()); +} + +} // namespace extensions
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.h b/chrome/browser/extensions/api/input_ime/input_ime_api.h index 934a51ef..d8a8f0a5 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_api.h +++ b/chrome/browser/extensions/api/input_ime/input_ime_api.h
@@ -25,8 +25,8 @@ #include "extensions/browser/extension_registry_factory.h" #include "extensions/browser/extension_registry_observer.h" #include "extensions/common/extension.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/ime_bridge_observer.h" -#include "ui/base/ime/ime_engine_handler_interface.h" #include "ui/base/ime/text_input_flags.h" #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc index 2cb76218..c5e46c4 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc +++ b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
@@ -29,8 +29,8 @@ #include "extensions/common/manifest_handlers/background_info.h" #include "ui/base/ime/chromeos/component_extension_ime_manager.h" #include "ui/base/ime/chromeos/extension_ime_util.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/chromeos/input_method_manager.h" -#include "ui/base/ime/ime_engine_handler_interface.h" #include "ui/base/ui_base_features.h" namespace input_ime = extensions::api::input_ime;
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_event_router_base.h b/chrome/browser/extensions/api/input_ime/input_ime_event_router_base.h index 6d3edec..9c9d5ec 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_event_router_base.h +++ b/chrome/browser/extensions/api/input_ime/input_ime_event_router_base.h
@@ -12,7 +12,7 @@ #include "base/macros.h" #include "chrome/browser/chromeos/input_method/input_method_engine_base.h" #include "chrome/browser/profiles/profile.h" -#include "ui/base/ime/ime_engine_handler_interface.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" namespace extensions {
diff --git a/chrome/browser/extensions/extension_csp_bypass_browsertest.cc b/chrome/browser/extensions/extension_csp_bypass_browsertest.cc index a12abc6b..3c2ea1ab 100644 --- a/chrome/browser/extensions/extension_csp_bypass_browsertest.cc +++ b/chrome/browser/extensions/extension_csp_bypass_browsertest.cc
@@ -131,7 +131,7 @@ EXPECT_TRUE(CanLoadScript(ext_without_permission)); // chrome-extension:-URLs can never bypass CSP in WebUI. - ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIVersionURL)); + ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUISettingsURL)); EXPECT_FALSE(CanLoadScript(component_ext_with_permission)); EXPECT_FALSE(CanLoadScript(component_ext_without_permission));
diff --git a/chrome/browser/extensions/extension_protocols_unittest.cc b/chrome/browser/extensions/extension_protocols_unittest.cc index 5e250fbe..966e571 100644 --- a/chrome/browser/extensions/extension_protocols_unittest.cc +++ b/chrome/browser/extensions/extension_protocols_unittest.cc
@@ -54,6 +54,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/loader/previews_state.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h" #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" #include "third_party/blink/public/common/privacy_budget/scoped_identifiability_test_sample_collector.h" @@ -150,7 +151,7 @@ net::SiteForCookies::FromUrl(url); // bypass third-party cookie blocking. request.request_initiator = url::Origin::Create(url); // ensure initiator set. - request.referrer_policy = content::Referrer::GetDefaultReferrerPolicy(); + request.referrer_policy = blink::ReferrerUtils::GetDefaultNetReferrerPolicy(); request.resource_type = static_cast<int>(resource_type); request.is_main_frame = resource_type == blink::mojom::ResourceType::kMainFrame;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 0bdb22a..4643c06 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -743,13 +743,13 @@ }, { "name": "d3d11-video-decoder", - "owners": [ "liberato", "tmathmeyer", "videostack-eng" ], + "owners": [ "liberato", "tmathmeyer", "//media/OWNERS" ], "expiry_milestone": 78 }, { "name": "darken-websites-checkbox-in-themes-setting", "owners": [ "lazzzis@google.com", "twellington" ], - "expiry_milestone": 83 + "expiry_milestone": 92 }, { "name": "dcheck-is-fatal", @@ -911,11 +911,6 @@ "expiry_milestone": -1 }, { - "name": "disable-touch-adjustment", - "owners": [ "eirage", "input-dev" ], - "expiry_milestone": 76 - }, - { "name": "disable-webrtc-hw-decoding", "owners": [ "hiroh", "chromeos-video-eng@google.com" ], // This flag does not expire because it allows users to disable HW video @@ -998,11 +993,6 @@ "expiry_milestone": 86 }, { - "name": "draw-vertically-edge-to-edge", - "owners": [ "chrome-android-app@chromium.org" ], - "expiry_milestone": 88 - }, - { "name": "dynamic-color-gamut", "owners": [ "cblume", "khushalsagar", "ccameron" ], "expiry_milestone": 90 @@ -1035,6 +1025,11 @@ "expiry_milestone": -1 }, { + "name": "enable-accelerated-video-decode", + "owners": [ "videostack-eng@google.com" ], + "expiry_milestone": 90 + }, + { "name": "enable-accessibility-expose-aria-annotations", "owners": [ "aleventhal@chromium.org", "//third_party/blink/renderer/modules/accessibility/OWNERS", "//ui/accessibility/OWNERS" ], "expiry_milestone": 85 @@ -1175,6 +1170,11 @@ "expiry_milestone": 82 }, { + "name": "enable-auto-select", + "owners": ["croissant-eng"], + "expiry_milestone": 88 + }, + { "name": "enable-autofill-account-wallet-storage", "owners": [ "treib", "jsaul@google.com", "butter-team@google.com" ], "expiry_milestone": 88 @@ -1609,11 +1609,6 @@ "expiry_milestone": 80 }, { - "name": "enable-high-resolution-mouse-scrolling", - "owners": [ "hcutts", "chromeos-tango@google.com" ], - "expiry_milestone": 85 - }, - { "name": "enable-history-manipulation-intervention", "owners": [ "shivanisha" ], "expiry_milestone": 76 @@ -2471,9 +2466,19 @@ "expiry_milestone": 87 }, { - "name": "files-zip-no-nacl", + "name": "files-zip-mount", "owners": [ "fdegros", "jboulic", "dats" ], - "expiry_milestone": 88 + "expiry_milestone": 90 + }, + { + "name": "files-zip-pack", + "owners": [ "fdegros", "jboulic", "dats" ], + "expiry_milestone": 90 + }, + { + "name": "files-zip-unpack", + "owners": [ "fdegros", "jboulic", "dats" ], + "expiry_milestone": 90 }, { "name": "fill-on-account-select", @@ -3286,6 +3291,11 @@ "expiry_milestone": 85 }, { + "name": "omnibox-focus-gesture-triggers-contextual-web-zero-suggest", + "owners": [ "tommycli", "chrome-omnibox-team@google.com" ], + "expiry_milestone": 95 + }, + { "name": "omnibox-history-quick-provider-allow-but-do-not-score-midword-terms", "owners": [ "manukh", "chrome-omnibox-team@google.com" ], "expiry_milestone": 88 @@ -3461,7 +3471,7 @@ }, { "name": "overlay-new-layout", - "owners": [ "donnd", "jinsukkim", "contextual-search-eng" ], + "owners": [ "donnd", "jinsukkim", "contextual-search-eng@google.com" ], "expiry_milestone": 81 }, {
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index b6cd69f..d3eac89e 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -185,11 +185,6 @@ "try to use a secure HTTPS connection to look up the addresses of websites " "and other web resources."; -const char kDrawVerticallyEdgeToEdgeName[] = - "Draw contents vertically from edge to edge."; -const char kDrawVerticallyEdgeToEdgeDescription[] = - "Draw contents vertically from edge to edge."; - const char kAutofillAlwaysReturnCloudTokenizedCardName[] = "Return cloud token details for server credit cards when possible"; const char kAutofillAlwaysReturnCloudTokenizedCardDescription[] = @@ -1488,6 +1483,16 @@ "enabled on the proper page classification (either by default or via a " "separate flag), or else this flag will do nothing."; +const char kOmniboxFocusGestureTriggersContextualWebZeroSuggestName[] = + "Omnibox Focus Gesture Triggers Contextual Web ZeroSuggest"; +const char kOmniboxFocusGestureTriggersContextualWebZeroSuggestDescription[] = + "Disable this flag to prevent focus gestures (e.g. clicks, taps, Ctrl+L) " + "from triggering ZeroSuggest for the OTHER page classification (contextual " + "web). This is used to experiment with alternate ZeroSuggest triggers like " + "clobber. Note, this flag is Enabled by default, as on-focus is the " + "standard ZeroSuggest trigger. This flag doesn't affect the NTP or SERP. " + "We don't want to accidentally unlaunch on-focus NTP ZeroSuggest."; + const char kOmniboxCompactSuggestionsName[] = "Omnibox: Compact suggestions"; const char kOmniboxCompactSuggestionsDescription[] = "Conserve the space for Omnibox Suggestions by slightly reducing their " @@ -2308,22 +2313,11 @@ "this can dramatically hurt scrolling performance of most websites and is " "intended for testing purposes only."; -const char kTouchAdjustmentName[] = "Touch adjustment"; -const char kTouchAdjustmentDescription[] = - "Refine the position of a touch gesture in order to compensate for touches " - "having poor resolution compared to a mouse."; - const char kTouchDragDropName[] = "Touch initiated drag and drop"; const char kTouchDragDropDescription[] = "Touch drag and drop can be initiated through long press on a draggable " "element."; -const char kTouchEventsName[] = "Touch Events API"; -const char kTouchEventsDescription[] = - "Force Touch Events API feature detection to always be enabled or " - "disabled, or to be enabled when a touchscreen is detected on startup " - "(Automatic)."; - const char kTouchSelectionStrategyName[] = "Touch text selection strategy"; const char kTouchSelectionStrategyDescription[] = "Controls how text selection granularity changes when touch text selection " @@ -3786,6 +3780,10 @@ const char kEnableAssistantTimersV2Description[] = "Enables v2 of Assistant timers."; +const char kEnableAutoSelectName[] = "Auto Select"; +const char kEnableAutoSelectDescription[] = + "Automatically select the word under cursor on contextual menu click."; + const char kEnableBackgroundBlurName[] = "Enable background blur."; const char kEnableBackgroundBlurDescription[] = "Enables background blur for the Launcher, Shelf, Unified System Tray etc."; @@ -3857,12 +3855,6 @@ "Enable additional heuristic palm rejection logic when interacting with " "stylus usage. Not intended for all devices."; -const char kEnableHighResolutionMouseScrollingName[] = - "Enable high resolution mouse scrolling"; -const char kEnableHighResolutionMouseScrollingDescription[] = - "Enable use of high-resolution scrolling events from supported mice (those " - "which report REL_WHEEL_HI_RES from the Linux kernel)."; - const char kNewDragSpecInLauncherName[] = "Enable Launcher App Paging"; const char kNewDragSpecInLauncherDescription[] = "Show visual affordance of launcher app pages and enable page previews " @@ -3999,9 +3991,17 @@ const char kFilesTransferDetailsDescription[] = "Enable transfer details like remaining time in the progress center panel."; -const char kFilesZipNoNaClName[] = "New ZIP handling in Files App"; -const char kFilesZipNoNaClDescription[] = - "Enable new ZIP archive handling in Files App which does not rely on NaCl."; +const char kFilesZipMountName[] = "New ZIP mounting in Files App"; +const char kFilesZipMountDescription[] = + "Enable new ZIP archive mounting system in File Manager."; + +const char kFilesZipPackName[] = "New ZIP packing in Files App"; +const char kFilesZipPackDescription[] = + "Enable new ZIP archive creation system in File Manager."; + +const char kFilesZipUnpackName[] = "New ZIP unpacking in Files App"; +const char kFilesZipUnpackDescription[] = + "Enable new ZIP archive extraction system in File Manager."; extern const char kFiltersInRecentsName[] = "Enable filters in Recents"; extern const char kFiltersInRecentsDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index b2bfb1a..dafd34d 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -248,9 +248,6 @@ extern const char kDnsHttpssvcName[]; extern const char kDnsHttpssvcDescription[]; -extern const char kDrawVerticallyEdgeToEdgeName[]; -extern const char kDrawVerticallyEdgeToEdgeDescription[]; - extern const char kEnablePasswordsAccountStorageName[]; extern const char kEnablePasswordsAccountStorageDescription[]; @@ -871,6 +868,10 @@ extern const char kOmniboxClobberIsZeroSuggestEntrypointName[]; extern const char kOmniboxClobberIsZeroSuggestEntrypointDescription[]; +extern const char kOmniboxFocusGestureTriggersContextualWebZeroSuggestName[]; +extern const char + kOmniboxFocusGestureTriggersContextualWebZeroSuggestDescription[]; + extern const char kOmniboxCompactSuggestionsName[]; extern const char kOmniboxCompactSuggestionsDescription[]; @@ -1337,9 +1338,6 @@ extern const char kTouchDragDropName[]; extern const char kTouchDragDropDescription[]; -extern const char kTouchEventsName[]; -extern const char kTouchEventsDescription[]; - extern const char kTouchSelectionStrategyName[]; extern const char kTouchSelectionStrategyDescription[]; extern const char kTouchSelectionStrategyCharacter[]; @@ -2189,6 +2187,9 @@ extern const char kEnableAssistantTimersV2Name[]; extern const char kEnableAssistantTimersV2Description[]; +extern const char kEnableAutoSelectName[]; +extern const char kEnableAutoSelectDescription[]; + extern const char kEnableBackgroundBlurName[]; extern const char kEnableBackgroundBlurDescription[]; @@ -2225,9 +2226,6 @@ extern const char kEnableHeuristicStylusPalmRejectionName[]; extern const char kEnableHeuristicStylusPalmRejectionDescription[]; -extern const char kEnableHighResolutionMouseScrollingName[]; -extern const char kEnableHighResolutionMouseScrollingDescription[]; - extern const char kNewDragSpecInLauncherName[]; extern const char kNewDragSpecInLauncherDescription[]; @@ -2322,8 +2320,14 @@ extern const char kFilesTransferDetailsName[]; extern const char kFilesTransferDetailsDescription[]; -extern const char kFilesZipNoNaClName[]; -extern const char kFilesZipNoNaClDescription[]; +extern const char kFilesZipMountName[]; +extern const char kFilesZipMountDescription[]; + +extern const char kFilesZipPackName[]; +extern const char kFilesZipPackDescription[]; + +extern const char kFilesZipUnpackName[]; +extern const char kFilesZipUnpackDescription[]; extern const char kFiltersInRecentsName[]; extern const char kFiltersInRecentsDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 790e0a9..7aff958 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -157,7 +157,6 @@ &kDownloadNotificationBadge, &kDownloadProgressInfoBar, &kDownloadRename, - &kDrawVerticallyEdgeToEdge, &kDuetTabStripIntegrationAndroid, &kEphemeralTabUsingBottomSheet, &kExploreSites, @@ -447,9 +446,6 @@ const base::Feature kDirectActions{"DirectActions", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kDrawVerticallyEdgeToEdge{ - "DrawVerticallyEdgeToEdge", base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kDownloadAutoResumptionThrottling{ "DownloadAutoResumptionThrottling", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index 2024370b..2613c74 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -72,7 +72,6 @@ extern const base::Feature kDownloadNotificationBadge; extern const base::Feature kDownloadProgressInfoBar; extern const base::Feature kDownloadRename; -extern const base::Feature kDrawVerticallyEdgeToEdge; extern const base::Feature kDuetTabStripIntegrationAndroid; extern const base::Feature kEphemeralTabUsingBottomSheet; extern const base::Feature kExploreSites;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 5b5741d..2ea5bf9 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -288,7 +288,6 @@ "UseDownloadOfflineContentProvider"; public static final String DOWNLOADS_LOCATION_CHANGE = "DownloadsLocationChange"; public static final String DOWNLOAD_LATER = "DownloadLater"; - public static final String DRAW_VERTICALLY_EDGE_TO_EDGE = "DrawVerticallyEdgeToEdge"; public static final String DUET_TABSTRIP_INTEGRATION_ANDROID = "DuetTabStripIntegrationAndroid"; public static final String EPHEMERAL_TAB_USING_BOTTOM_SHEET = "EphemeralTabUsingBottomSheet"; public static final String EXPLICIT_LANGUAGE_ASK = "ExplicitLanguageAsk";
diff --git a/chrome/browser/lite_video/lite_video_decider.cc b/chrome/browser/lite_video/lite_video_decider.cc index 7c16124..c3ced706 100644 --- a/chrome/browser/lite_video/lite_video_decider.cc +++ b/chrome/browser/lite_video/lite_video_decider.cc
@@ -209,7 +209,9 @@ void LiteVideoDecider::ClearBlocklist(const base::Time& delete_begin, const base::Time& delete_end) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - user_blocklist_->ClearBlockList(delete_begin, delete_end); + if (user_blocklist_) { + user_blocklist_->ClearBlockList(delete_begin, delete_end); + } } void LiteVideoDecider::OnBlocklistCleared(base::Time time) { @@ -219,9 +221,10 @@ void LiteVideoDecider::DidMediaRebuffer(const GURL& mainframe_url, base::Optional<GURL> subframe_url, bool opt_out) { - if (user_blocklist_) + if (user_blocklist_) { user_blocklist_->AddRebufferToBlocklist(mainframe_url, subframe_url, opt_out); + } } } // namespace lite_video
diff --git a/chrome/browser/lite_video/lite_video_keyed_service.cc b/chrome/browser/lite_video/lite_video_keyed_service.cc index dc667cd..7edeab4 100644 --- a/chrome/browser/lite_video/lite_video_keyed_service.cc +++ b/chrome/browser/lite_video/lite_video_keyed_service.cc
@@ -45,5 +45,6 @@ void LiteVideoKeyedService::ClearData(const base::Time& delete_begin, const base::Time& delete_end) { - decider_->ClearBlocklist(delete_begin, delete_end); + if (decider_) + decider_->ClearBlocklist(delete_begin, delete_end); }
diff --git a/chrome/browser/media/history/media_history_store.cc b/chrome/browser/media/history/media_history_store.cc index 6acbf7a..96f95860 100644 --- a/chrome/browser/media/history/media_history_store.cc +++ b/chrome/browser/media/history/media_history_store.cc
@@ -160,6 +160,9 @@ const char MediaHistoryStore::kInitResultHistogramName[] = "Media.History.Init.Result"; +const char MediaHistoryStore::kInitResultAfterDeleteHistogramName[] = + "Media.History.Init.ResultAfterDelete"; + const char MediaHistoryStore::kPlaybackWriteResultHistogramName[] = "Media.History.Playback.WriteResult"; @@ -308,6 +311,19 @@ base::UmaHistogramEnumeration(MediaHistoryStore::kInitResultHistogramName, result); + + // In some edge cases the DB might be corrupted and unrecoverable so we should + // delete the database and recreate it. + if (result != InitResult::kSuccess) { + if (db_->is_open()) + db_->Close(); + + sql::Database::Delete(db_path_); + + base::UmaHistogramEnumeration( + MediaHistoryStore::kInitResultAfterDeleteHistogramName, + InitializeInternal()); + } } MediaHistoryStore::InitResult MediaHistoryStore::InitializeInternal() {
diff --git a/chrome/browser/media/history/media_history_store.h b/chrome/browser/media/history/media_history_store.h index 26e66e78..71d00dc 100644 --- a/chrome/browser/media/history/media_history_store.h +++ b/chrome/browser/media/history/media_history_store.h
@@ -59,6 +59,7 @@ const base::TimeDelta& position)>; static const char kInitResultHistogramName[]; + static const char kInitResultAfterDeleteHistogramName[]; static const char kPlaybackWriteResultHistogramName[]; static const char kSessionWriteResultHistogramName[]; static const char kDatabaseSizeKbHistogramName[];
diff --git a/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.cc b/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.cc index 1a1dd9e..5303883 100644 --- a/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.cc +++ b/chrome/browser/media/kaleidoscope/kaleidoscope_data_provider_impl.cc
@@ -81,17 +81,30 @@ } identity_manager_ = IdentityManagerFactory::GetForProfile(profile); - DCHECK(identity_manager_); } KaleidoscopeDataProviderImpl::~KaleidoscopeDataProviderImpl() = default; void KaleidoscopeDataProviderImpl::GetCredentials(GetCredentialsCallback cb) { + // If the profile is incognito then disable Kaleidoscope. + if (profile_->IsOffTheRecord()) { + std::move(cb).Run(nullptr, + media::mojom::CredentialsResult::kFailedIncognito); + return; + } + + // If the profile is a child then disable Kaleidoscope. + if (profile_->IsSupervised() || profile_->IsChild()) { + std::move(cb).Run(nullptr, media::mojom::CredentialsResult::kFailedChild); + return; + } + // If the user is not signed in, return the credentials without an access // token. Sync consent is not required to use Kaleidoscope. if (!identity_manager_->HasPrimaryAccount( signin::ConsentLevel::kNotRequired)) { - std::move(cb).Run(credentials_.Clone()); + std::move(cb).Run(credentials_.Clone(), + media::mojom::CredentialsResult::kSuccess); return; } @@ -183,8 +196,10 @@ if (error.state() == GoogleServiceAuthError::State::NONE) credentials_->access_token = access_token_info.token; - for (auto& callback : pending_callbacks_) - std::move(callback).Run(credentials_.Clone()); + for (auto& callback : pending_callbacks_) { + std::move(callback).Run(credentials_.Clone(), + media::mojom::CredentialsResult::kSuccess); + } pending_callbacks_.clear(); }
diff --git a/chrome/browser/media/kaleidoscope/mojom/kaleidoscope.mojom b/chrome/browser/media/kaleidoscope/mojom/kaleidoscope.mojom index 88f8f69..7d766a3 100644 --- a/chrome/browser/media/kaleidoscope/mojom/kaleidoscope.mojom +++ b/chrome/browser/media/kaleidoscope/mojom/kaleidoscope.mojom
@@ -7,6 +7,13 @@ import "chrome/browser/media/feeds/media_feeds_store.mojom"; import "url/mojom/origin.mojom"; +// The result of getting the credentials. +enum CredentialsResult { + kSuccess, + kFailedIncognito, + kFailedChild, +}; + // The credentials required to make Google API calls from JS. struct Credentials { // Chrome's API Key. @@ -43,7 +50,7 @@ GetContinueWatchingMediaFeedItems(KaleidoscopeTab tab) => (array<media_feeds.mojom.MediaFeedItem> items); // Retrieves the current credentials. - GetCredentials() => (Credentials credentials); + GetCredentials() => (Credentials? credentials, CredentialsResult result); // Returns all the watch time origins from media history store that have // watch time above a threshold.
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc index 430f2ee..8857b7a 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc
@@ -121,6 +121,9 @@ MOCK_METHOD(void, CreateMojoBindings, (mojom::MediaRouter * media_router)); MOCK_METHOD(void, OnSessionSet, (const CastSession& session)); + MOCK_METHOD(void, + SendStopSessionMessageToClients, + (const std::string& hash_token)); }; } // namespace @@ -155,7 +158,7 @@ ON_CALL(message_handler_, StopSession) .WillByDefault(WithArg<3>([this](auto callback) { - stop_session_callback_ = std::move(callback); + std::move(callback).Run(stop_session_callback_arg_); })); RunUntilIdle(); @@ -178,8 +181,8 @@ const MediaRoute& route, const std::string& app_id) override { auto activity = std::make_unique<MockAppActivity>(route, app_id); - cast_activity_ = activity.get(); - cast_activity_callback_.Run(activity.get()); + app_activity_ = activity.get(); + app_activity_callback_.Run(activity.get()); return activity; } @@ -243,12 +246,12 @@ MakeSourceId(app_id, app_params, client_id)); ASSERT_TRUE(source); - cast_activity_callback_ = + app_activity_callback_ = base::BindLambdaForTesting([this](MockAppActivity* activity) { // TODO(jrw): Check parameters. EXPECT_CALL(*activity, AddClient); EXPECT_CALL(*activity, SendMessageToClient).RetiresOnSaturation(); - cast_activity_callback_ = base::DoNothing(); + app_activity_callback_ = base::DoNothing(); }); // Callback will be invoked synchronously. @@ -261,15 +264,16 @@ RunUntilIdle(); } - cast_channel::LaunchSessionResponse GetSuccessLaunchResponse() { + cast_channel::LaunchSessionResponse GetSuccessLaunchResponse( + const std::string& app_id = kAppId1) { cast_channel::LaunchSessionResponse response; response.result = cast_channel::LaunchSessionResponse::Result::kOk; - response.receiver_status = MakeReceiverStatus(kAppId1); + response.receiver_status = MakeReceiverStatus(app_id); return response; } - void LaunchCastAppSession(const std::string& app_id = kAppId1, - const std::string& app_params = "") { + void LaunchAppSession(const std::string& app_id = kAppId1, + const std::string& app_params = "") { CallLaunchSession(app_id, app_params); // 3 things will happen: @@ -278,15 +282,15 @@ // (3) Route list will be updated. // TODO(jrw): Check more params. - EXPECT_CALL(*cast_activity_, SendMessageToClient("theClientId", _)); - EXPECT_CALL(*cast_activity_, OnSessionSet).WillOnce([this]() { - EXPECT_EQ(sink_, cast_activity_->sink()); + EXPECT_CALL(*app_activity_, SendMessageToClient("theClientId", _)); + EXPECT_CALL(*app_activity_, OnSessionSet).WillOnce([this]() { + EXPECT_EQ(sink_, app_activity_->sink()); }); EXPECT_CALL(message_handler_, EnsureConnection(kChannelId, "theClientId", "theTransportId")); - auto response = GetSuccessLaunchResponse(); + auto response = GetSuccessLaunchResponse(app_id); session_tracker_->SetSessionForTest( route_->media_sink_id(), CastSession::From(sink_, *response.receiver_status)); @@ -295,8 +299,8 @@ RunUntilIdle(); } - void ExpectCastActivityStopped(int times = 1) { - EXPECT_CALL(*cast_activity_, SendStopSessionMessageToClients).Times(times); + void ExpectAppActivityStoppedTimes(int times) { + EXPECT_CALL(*app_activity_, SendStopSessionMessageToClients).Times(times); if (times == 0) { EXPECT_CALL(message_handler_, StopSession).Times(0); @@ -307,27 +311,26 @@ } } - void TerminateSession(bool expect_success) { - ExpectCastActivityStopped(); - - if (expect_success) { - ExpectEmptyRouteUpdate(); - } else { - ExpectNoRouteUpdate(); - } - manager_->TerminateSession(route_->media_route_id(), - MakeTerminateRouteCallback(expect_success)); - std::move(stop_session_callback_) - .Run(expect_success ? cast_channel::Result::kOk - : cast_channel::Result::kFailed); + void LaunchMirroringSession() { + CallLaunchSession(kCastStreamingAppId); + auto response = GetSuccessLaunchResponse(); + SetSessionForTest(route_->media_sink_id(), + CastSession::From(sink_, *response.receiver_status)); + std::move(launch_session_callback_).Run(std::move(response)); + DCHECK(mirroring_activity_); } - void TerminateNoSession() { - // Stop session message not sent because session has not launched yet. - ExpectCastActivityStopped(0); - ExpectNoRouteUpdate(); + void ExpectMirroringActivityStopped() { + DCHECK(mirroring_activity_); + EXPECT_CALL(message_handler_, StopSession).Times(1); + EXPECT_CALL(*mirroring_activity_, SendStopSessionMessageToClients).Times(1); + } + + void TerminateSession(bool expect_success) { + stop_session_callback_arg_ = expect_success ? cast_channel::Result::kOk + : cast_channel::Result::kFailed; manager_->TerminateSession(route_->media_route_id(), - MakeTerminateRouteCallback(true)); + MakeTerminateRouteCallback(expect_success)); } mojom::MediaRouteProvider::TerminateRouteCallback MakeTerminateRouteCallback( @@ -400,29 +403,29 @@ MockCastAppDiscoveryService app_discovery_service_; std::unique_ptr<CastActivityManager> manager_; std::unique_ptr<CastSessionTracker> session_tracker_; - MockAppActivity* cast_activity_ = nullptr; + MockAppActivity* app_activity_ = nullptr; MockMirroringActivity* mirroring_activity_ = nullptr; - MockAppActivityCallback cast_activity_callback_ = base::DoNothing(); + MockAppActivityCallback app_activity_callback_ = base::DoNothing(); const url::Origin origin_ = url::Origin::Create(GURL(kOrigin)); const MediaSource::Id route_query_ = "theRouteQuery"; base::Optional<MediaRoute> updated_route_; - cast_channel::ResultCallback stop_session_callback_; + cast_channel::Result stop_session_callback_arg_ = cast_channel::Result::kOk; MockLogger logger_; mojom::RoutePresentationConnectionPtr presentation_connections_; }; -TEST_F(CastActivityManagerTest, LaunchCastAppSession) { - LaunchCastAppSession(); +TEST_F(CastActivityManagerTest, LaunchAppSession) { + LaunchAppSession(); EXPECT_EQ(RouteControllerType::kGeneric, route_->controller_type()); } -TEST_F(CastActivityManagerTest, LaunchCastAppSessionWithAppParams) { - LaunchCastAppSession(kAppId1, kAppParams); +TEST_F(CastActivityManagerTest, LaunchAppSessionWithAppParams) { + LaunchAppSession(kAppId1, kAppParams); EXPECT_EQ(RouteControllerType::kGeneric, route_->controller_type()); } TEST_F(CastActivityManagerTest, LaunchMirroringSession) { - CallLaunchSession(kCastStreamingAppId); + LaunchMirroringSession(); EXPECT_EQ(RouteControllerType::kMirroring, route_->controller_type()); } @@ -435,16 +438,8 @@ } TEST_F(CastActivityManagerTest, MirroringSessionStopped) { - CallLaunchSession(kCastStreamingAppId); - auto response = GetSuccessLaunchResponse(); - - SetSessionForTest(route_->media_sink_id(), - CastSession::From(sink_, *response.receiver_status)); - std::move(launch_session_callback_).Run(std::move(response)); - RunUntilIdle(); - - ASSERT_TRUE(mirroring_activity_); - EXPECT_CALL(message_handler_, StopSession).Times(1); + LaunchMirroringSession(); + ExpectMirroringActivityStopped(); mirroring_activity_->DidStop(); } @@ -458,7 +453,7 @@ CallLaunchSession(); EXPECT_CALL( - *cast_activity_, + *app_activity_, ClosePresentationConnections( blink::mojom::PresentationConnectionCloseReason::CONNECTION_ERROR)); @@ -471,7 +466,7 @@ RunUntilIdle(); } -TEST_F(CastActivityManagerTest, LaunchCastAppSessionFailsWithAppParams) { +TEST_F(CastActivityManagerTest, LaunchAppSessionFailsWithAppParams) { auto source = CastMediaSource::FromMediaSourceId(MakeSourceId(kAppId1, "invalidjson")); ASSERT_TRUE(source); @@ -487,8 +482,8 @@ } TEST_F(CastActivityManagerTest, LaunchSessionTerminatesExistingSessionOnSink) { - LaunchCastAppSession(); - ExpectCastActivityStopped(); + LaunchAppSession(); + ExpectAppActivityStoppedTimes(1); { testing::InSequence dummy; @@ -513,7 +508,6 @@ base::BindOnce(&CastActivityManagerTest::ExpectLaunchSessionSuccess, base::Unretained(this)), data_decoder::DataDecoder::ValueOrError()); - std::move(stop_session_callback_).Run(cast_channel::Result::kOk); // LaunchSession() should not be called until we notify |mananger_| that the // previous session was removed. @@ -527,8 +521,8 @@ } TEST_F(CastActivityManagerTest, LaunchSessionTerminatesExistingSessionFromTab) { - LaunchCastAppSession(); - ExpectCastActivityStopped(); + LaunchAppSession(); + ExpectAppActivityStoppedTimes(1); // Launch a new session on the same sink. auto source = CastMediaSource::FromMediaSourceId(MakeSourceId(kAppId2)); @@ -555,10 +549,10 @@ } TEST_F(CastActivityManagerTest, UpdateNewlyCreatedSession) { - LaunchCastAppSession(); + LaunchAppSession(); - EXPECT_CALL(*cast_activity_, OnSessionUpdated).WillOnce([this]() { - EXPECT_EQ(sink_, cast_activity_->sink()); + EXPECT_CALL(*app_activity_, OnSessionUpdated).WillOnce([this]() { + EXPECT_EQ(sink_, app_activity_->sink()); }); auto session = MakeSession(kAppId1); ExpectSingleRouteUpdate(); @@ -592,50 +586,57 @@ } TEST_F(CastActivityManagerTest, OnSessionAddedOrUpdated) { - LaunchCastAppSession(); + LaunchAppSession(); auto session = MakeSession(kAppId1); ExpectSingleRouteUpdate(); - EXPECT_CALL(*cast_activity_, OnSessionUpdated(_, "theHashToken")); + EXPECT_CALL(*app_activity_, OnSessionUpdated(_, "theHashToken")); manager_->OnSessionAddedOrUpdated(sink_, *session); } // TODO(takumif): Add a test case to terminate a session and launch another. TEST_F(CastActivityManagerTest, TerminateSession) { - LaunchCastAppSession(); + LaunchAppSession(); + ExpectAppActivityStoppedTimes(1); + ExpectEmptyRouteUpdate(); TerminateSession(true); } TEST_F(CastActivityManagerTest, TerminateSessionFails) { - LaunchCastAppSession(); + LaunchAppSession(); + ExpectAppActivityStoppedTimes(1); + ExpectNoRouteUpdate(); TerminateSession(false); } TEST_F(CastActivityManagerTest, TerminateSessionBeforeLaunchResponse) { CallLaunchSession(); - TerminateNoSession(); + // Stop session message not sent because session has not launched yet. + ExpectAppActivityStoppedTimes(0); + ExpectNoRouteUpdate(); + TerminateSession(true); ExpectEmptyRouteUpdate(); std::move(launch_session_callback_).Run(GetSuccessLaunchResponse()); } TEST_F(CastActivityManagerTest, AppMessageFromReceiver) { - LaunchCastAppSession(); + LaunchAppSession(); // Destination ID matches client ID. cast::channel::CastMessage message = cast_channel::CreateCastMessage( "urn:x-cast:com.google.foo", base::Value(base::Value::Type::DICTIONARY), "sourceId", "theClientId"); - EXPECT_CALL(*cast_activity_, OnAppMessage(IsCastChannelMessage(message))); + EXPECT_CALL(*app_activity_, OnAppMessage(IsCastChannelMessage(message))); manager_->OnAppMessage(kChannelId, message); } TEST_F(CastActivityManagerTest, OnMediaStatusUpdated) { - LaunchCastAppSession(); + LaunchAppSession(); const char status[] = R"({"foo": "bar"})"; base::Optional<int> request_id(345); - EXPECT_CALL(*cast_activity_, + EXPECT_CALL(*app_activity_, SendMediaStatusToClients(IsJson(status), request_id)); manager_->OnMediaStatusUpdated(sink_, ParseJson(status), request_id); }
diff --git a/chrome/browser/metrics/chrome_metrics_service_accessor.h b/chrome/browser/metrics/chrome_metrics_service_accessor.h index 2e421c79..2b88d11 100644 --- a/chrome/browser/metrics/chrome_metrics_service_accessor.h +++ b/chrome/browser/metrics/chrome_metrics_service_accessor.h
@@ -120,6 +120,7 @@ friend class NavigationMetricsRecorder; friend class ChromeBrowserMainExtraPartsGpu; friend class Browser; + friend class OptimizationGuideKeyedService; #if defined(OS_CHROMEOS) friend class ChromeCameraAppUIDelegate;
diff --git a/chrome/browser/native_file_system/chrome_native_file_system_permission_context_unittest.cc b/chrome/browser/native_file_system/chrome_native_file_system_permission_context_unittest.cc index 4c57db47..0bbbe19 100644 --- a/chrome/browser/native_file_system/chrome_native_file_system_permission_context_unittest.cc +++ b/chrome/browser/native_file_system/chrome_native_file_system_permission_context_unittest.cc
@@ -61,13 +61,6 @@ NOTREACHED(); return nullptr; } - void ConfirmDirectoryReadAccess( - const url::Origin& origin, - const base::FilePath& path, - content::GlobalFrameRoutingId frame_id, - base::OnceCallback<void(PermissionStatus)> callback) override { - NOTREACHED(); - } // ChromeNativeFileSystemPermissionContext: Grants GetPermissionGrants(const url::Origin& origin) override {
diff --git a/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context.cc b/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context.cc index fab17cc..3bc2546e 100644 --- a/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context.cc +++ b/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context.cc
@@ -19,6 +19,7 @@ #endif namespace { +using blink::mojom::PermissionStatus; using permissions::PermissionAction; enum class GrantType { kRead, kWrite }; @@ -52,15 +53,8 @@ PermissionStatus GetStatus() override { return status_; } void RequestPermission( content::GlobalFrameRoutingId frame_id, + UserActivationState user_activation_state, base::OnceCallback<void(PermissionRequestOutcome)> callback) override { - RequestPermissionImpl(frame_id, - /*require_user_gesture=*/true, std::move(callback)); - } - - void RequestPermissionImpl( - content::GlobalFrameRoutingId frame_id, - bool require_user_gesture, - base::OnceCallback<void(PermissionRequestOutcome)> callback) { // Check if a permission request has already been processed previously. This // check is done first because we don't want to reset the status of a // permission if it has already been granted. @@ -102,7 +96,8 @@ return; } - if (require_user_gesture && !rfh->HasTransientUserActivation()) { + if (user_activation_state == UserActivationState::kRequired && + !rfh->HasTransientUserActivation()) { // No permission prompts without user activation. RunCallbackAndRecordPermissionRequestOutcome( std::move(callback), PermissionRequestOutcome::kNoUserActivation); @@ -416,30 +411,6 @@ return existing_grant; } -void OriginScopedNativeFileSystemPermissionContext::ConfirmDirectoryReadAccess( - const url::Origin& origin, - const base::FilePath& path, - content::GlobalFrameRoutingId frame_id, - base::OnceCallback<void(PermissionStatus)> callback) { - // TODO(mek): Once tab-scoped permission model is no longer used we can - // refactor the calling code of this method to just do what this - // implementation does directly. - scoped_refptr<content::NativeFileSystemPermissionGrant> grant = - GetReadPermissionGrant(origin, path, HandleType::kDirectory, - UserAction::kOpen); - static_cast<PermissionGrantImpl*>(grant.get()) - ->RequestPermissionImpl( - frame_id, /*require_user_gesture=*/false, - base::BindOnce( - [](base::OnceCallback<void(PermissionStatus)> callback, - scoped_refptr<content::NativeFileSystemPermissionGrant> grant, - content::NativeFileSystemPermissionGrant:: - PermissionRequestOutcome outcome) { - std::move(callback).Run(grant->GetStatus()); - }, - std::move(callback), grant)); -} - ChromeNativeFileSystemPermissionContext::Grants OriginScopedNativeFileSystemPermissionContext::GetPermissionGrants( const url::Origin& origin) {
diff --git a/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context.h b/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context.h index a1ea5330e..813e88a7 100644 --- a/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context.h +++ b/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context.h
@@ -35,11 +35,6 @@ const base::FilePath& path, HandleType handle_type, UserAction user_action) override; - void ConfirmDirectoryReadAccess( - const url::Origin& origin, - const base::FilePath& path, - content::GlobalFrameRoutingId frame_id, - base::OnceCallback<void(PermissionStatus)> callback) override; // ChromeNativeFileSystemPermissionContext: Grants GetPermissionGrants(const url::Origin& origin) override;
diff --git a/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context_unittest.cc b/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context_unittest.cc index 825d4b1..213a4be 100644 --- a/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context_unittest.cc +++ b/chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context_unittest.cc
@@ -42,6 +42,8 @@ using SensitiveDirectoryResult = ChromeNativeFileSystemPermissionContext::SensitiveDirectoryResult; using HandleType = content::NativeFileSystemPermissionContext::HandleType; +using UserActivationState = + content::NativeFileSystemPermissionGrant::UserActivationState; class OriginScopedNativeFileSystemPermissionContextTest : public testing::Test { public: @@ -318,7 +320,7 @@ base::RunLoop loop; grant->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kUserDismissed, outcome); loop.Quit(); @@ -340,7 +342,7 @@ base::RunLoop loop; grant->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kUserGranted, outcome); loop.Quit(); @@ -361,7 +363,7 @@ base::RunLoop loop; grant->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kUserDenied, outcome); loop.Quit(); @@ -380,7 +382,7 @@ base::RunLoop loop; grant->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kNoUserActivation, outcome); loop.Quit(); @@ -391,6 +393,26 @@ } TEST_F(OriginScopedNativeFileSystemPermissionContextTest, + RequestPermission_NoUserActivation_UserActivationNotRequired) { + NativeFileSystemPermissionRequestManager::FromWebContents(web_contents_.get()) + ->set_auto_response_for_test(PermissionAction::GRANTED); + + auto grant = permission_context()->GetWritePermissionGrant( + kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen); + + base::RunLoop loop; + grant->RequestPermission( + frame_id(), UserActivationState::kNotRequired, + base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { + EXPECT_EQ(PermissionRequestOutcome::kUserGranted, outcome); + loop.Quit(); + })); + loop.Run(); + // No user activation, so status should not change. + EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus()); +} + +TEST_F(OriginScopedNativeFileSystemPermissionContextTest, RequestPermission_AlreadyGranted) { // If the permission has already been granted, a call to RequestPermission() // should call the passed-in callback and return immediately without showing a @@ -400,7 +422,7 @@ base::RunLoop loop; grant->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kRequestAborted, outcome); loop.Quit(); @@ -422,7 +444,7 @@ base::RunLoop loop; grant->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kRequestAborted, outcome); loop.Quit(); @@ -435,7 +457,7 @@ base::RunLoop loop2; grant2->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kRequestAborted, outcome); loop2.Quit(); @@ -453,7 +475,7 @@ base::RunLoop loop3; grant2->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kNoUserActivation, outcome); loop3.Quit(); @@ -477,7 +499,7 @@ base::RunLoop loop; grant->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kBlockedByContentSetting, outcome); loop.Quit(); @@ -487,7 +509,7 @@ base::RunLoop loop2; grant2->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kBlockedByContentSetting, outcome); loop2.Quit(); @@ -508,7 +530,7 @@ base::RunLoop loop3; grant->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kNoUserActivation, outcome); loop3.Quit(); @@ -518,7 +540,7 @@ base::RunLoop loop4; grant2->RequestPermission( - frame_id(), + frame_id(), UserActivationState::kRequired, base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) { EXPECT_EQ(PermissionRequestOutcome::kRequestAborted, outcome); loop4.Quit();
diff --git a/chrome/browser/nearby_sharing/incoming_share_target_info.cc b/chrome/browser/nearby_sharing/incoming_share_target_info.cc index 1e77be52..313e1702 100644 --- a/chrome/browser/nearby_sharing/incoming_share_target_info.cc +++ b/chrome/browser/nearby_sharing/incoming_share_target_info.cc
@@ -4,23 +4,12 @@ #include "chrome/browser/nearby_sharing/incoming_share_target_info.h" -#include "chrome/browser/nearby_sharing/nearby_connection.h" - IncomingShareTargetInfo::IncomingShareTargetInfo() = default; -IncomingShareTargetInfo::~IncomingShareTargetInfo() = default; IncomingShareTargetInfo::IncomingShareTargetInfo(IncomingShareTargetInfo&&) = default; + IncomingShareTargetInfo& IncomingShareTargetInfo::operator=( IncomingShareTargetInfo&&) = default; -std::ostream& operator<<(std::ostream& out, - const IncomingShareTargetInfo& share_target) { - out << "IncomingShareTargetInfo<endpoint_id: " - << (share_target.endpoint_id().has_value() - ? share_target.endpoint_id().value() - : "") - << ", has_certificate: " << (share_target.certificate().has_value()) - << ", has_connection: " << (share_target.connection() != nullptr) << ">"; - return out; -} +IncomingShareTargetInfo::~IncomingShareTargetInfo() = default;
diff --git a/chrome/browser/nearby_sharing/incoming_share_target_info.h b/chrome/browser/nearby_sharing/incoming_share_target_info.h index 4bb9559f..a1a1d8eb 100644 --- a/chrome/browser/nearby_sharing/incoming_share_target_info.h +++ b/chrome/browser/nearby_sharing/incoming_share_target_info.h
@@ -5,65 +5,14 @@ #ifndef CHROME_BROWSER_NEARBY_SHARING_INCOMING_SHARE_TARGET_INFO_H_ #define CHROME_BROWSER_NEARBY_SHARING_INCOMING_SHARE_TARGET_INFO_H_ -#include <memory> -#include <string> +#include "chrome/browser/nearby_sharing/share_target_info.h" -#include "base/optional.h" -#include "chrome/browser/nearby_sharing/certificates/nearby_share_decrypted_public_certificate.h" -#include "chrome/browser/nearby_sharing/incoming_frames_reader.h" - -class NearbyConnection; - -class IncomingShareTargetInfo { +class IncomingShareTargetInfo : public ShareTargetInfo { public: IncomingShareTargetInfo(); - ~IncomingShareTargetInfo(); - - IncomingShareTargetInfo(const IncomingShareTargetInfo&) = delete; - IncomingShareTargetInfo& operator=(const IncomingShareTargetInfo&) = delete; - IncomingShareTargetInfo(IncomingShareTargetInfo&&); IncomingShareTargetInfo& operator=(IncomingShareTargetInfo&&); - - void set_endpoint_id(std::string endpoint_id) { - endpoint_id_ = std::move(endpoint_id); - } - - const base::Optional<std::string>& endpoint_id() const { - return endpoint_id_; - } - - void set_certificate(NearbyShareDecryptedPublicCertificate certificate) { - certificate_ = std::move(certificate); - } - - const base::Optional<NearbyShareDecryptedPublicCertificate>& certificate() - const { - return certificate_; - } - - void set_connection(NearbyConnection* connection) { - connection_ = connection; - } - - NearbyConnection* connection() const { return connection_; } - - void set_token(std::string token) { token_ = std::move(token); } - - const base::Optional<std::string>& token() const { return token_; } - - IncomingFramesReader* frames_reader() { return frames_reader_.get(); } - - void set_frames_reader(std::unique_ptr<IncomingFramesReader> frames_reader) { - frames_reader_ = std::move(frames_reader); - } - - private: - base::Optional<std::string> endpoint_id_; - base::Optional<NearbyShareDecryptedPublicCertificate> certificate_; - NearbyConnection* connection_ = nullptr; - base::Optional<std::string> token_; - std::unique_ptr<IncomingFramesReader> frames_reader_; + ~IncomingShareTargetInfo() override; }; #endif // CHROME_BROWSER_NEARBY_SHARING_INCOMING_SHARE_TARGET_INFO_H_
diff --git a/chrome/browser/nearby_sharing/outgoing_share_target_info.cc b/chrome/browser/nearby_sharing/outgoing_share_target_info.cc index 0f382fa..d7172da 100644 --- a/chrome/browser/nearby_sharing/outgoing_share_target_info.cc +++ b/chrome/browser/nearby_sharing/outgoing_share_target_info.cc
@@ -3,23 +3,13 @@ // found in the LICENSE file. #include "chrome/browser/nearby_sharing/outgoing_share_target_info.h" -#include "chrome/browser/nearby_sharing/nearby_connection.h" OutgoingShareTargetInfo::OutgoingShareTargetInfo() = default; -OutgoingShareTargetInfo::~OutgoingShareTargetInfo() = default; OutgoingShareTargetInfo::OutgoingShareTargetInfo(OutgoingShareTargetInfo&&) = default; + OutgoingShareTargetInfo& OutgoingShareTargetInfo::operator=( OutgoingShareTargetInfo&&) = default; -std::ostream& operator<<(std::ostream& out, - const OutgoingShareTargetInfo& share_target) { - out << "OutgoingShareTargetInfo<endpoint_id: " - << (share_target.endpoint_id().has_value() - ? share_target.endpoint_id().value() - : "") - << ", has_certificate: " << (share_target.certificate().has_value()) - << ", has_connection: " << (share_target.connection() != nullptr) << ">"; - return out; -} +OutgoingShareTargetInfo::~OutgoingShareTargetInfo() = default;
diff --git a/chrome/browser/nearby_sharing/outgoing_share_target_info.h b/chrome/browser/nearby_sharing/outgoing_share_target_info.h index e00db25..5d111e1 100644 --- a/chrome/browser/nearby_sharing/outgoing_share_target_info.h +++ b/chrome/browser/nearby_sharing/outgoing_share_target_info.h
@@ -9,67 +9,47 @@ #include <vector> #include "base/optional.h" -#include "chrome/browser/nearby_sharing/certificates/nearby_share_decrypted_public_certificate.h" - -class NearbyConnection; +#include "chrome/browser/nearby_sharing/share_target_info.h" +#include "chrome/services/sharing/public/mojom/nearby_connections_types.mojom.h" // A description of the outgoing connection to a remote device. -class OutgoingShareTargetInfo { +class OutgoingShareTargetInfo : public ShareTargetInfo { public: + using PayloadPtr = location::nearby::connections::mojom::PayloadPtr; + OutgoingShareTargetInfo(); - ~OutgoingShareTargetInfo(); - - OutgoingShareTargetInfo(const OutgoingShareTargetInfo&) = delete; - OutgoingShareTargetInfo& operator=(const OutgoingShareTargetInfo&) = delete; - OutgoingShareTargetInfo(OutgoingShareTargetInfo&&); OutgoingShareTargetInfo& operator=(OutgoingShareTargetInfo&&); - - void set_endpoint_id(std::string endpoint_id) { - endpoint_id_ = std::move(endpoint_id); - } - - const base::Optional<std::string>& endpoint_id() const { - return endpoint_id_; - } - - void set_certificate(NearbyShareDecryptedPublicCertificate certificate) { - certificate_ = std::move(certificate); - } - - const base::Optional<NearbyShareDecryptedPublicCertificate>& certificate() - const { - return certificate_; - } - void set_connection(NearbyConnection* connection) { - connection_ = connection; - } - - NearbyConnection* connection() const { return connection_; } - - void set_obfuscated_gaia_id(std::string obfuscated_gaia_id) { - obfuscated_gaia_id_ = std::move(obfuscated_gaia_id); - } + ~OutgoingShareTargetInfo() override; const base::Optional<std::string>& obfuscated_gaia_id() const { return obfuscated_gaia_id_; } - void set_token(std::string token) { token_ = std::move(token); } + void set_obfuscated_gaia_id(std::string obfuscated_gaia_id) { + obfuscated_gaia_id_ = std::move(obfuscated_gaia_id); + } - const base::Optional<std::string>& token() const { return token_; } + const std::vector<PayloadPtr>& text_payloads() const { + return text_payloads_; + } - void set_is_connected(bool is_connected) { is_connected_ = is_connected; } + void set_text_payloads(std::vector<PayloadPtr> payloads) { + text_payloads_ = std::move(payloads); + } - bool is_connected() const { return is_connected_; } + const std::vector<PayloadPtr>& file_payloads() const { + return file_payloads_; + } + + void set_file_payloads(std::vector<PayloadPtr> payloads) { + file_payloads_ = std::move(payloads); + } private: - base::Optional<std::string> endpoint_id_; - base::Optional<NearbyShareDecryptedPublicCertificate> certificate_; - NearbyConnection* connection_ = nullptr; base::Optional<std::string> obfuscated_gaia_id_; - base::Optional<std::string> token_; - bool is_connected_ = false; + std::vector<PayloadPtr> text_payloads_; + std::vector<PayloadPtr> file_payloads_; }; #endif // CHROME_BROWSER_NEARBY_SHARING_OUTGOING_SHARE_TARGET_INFO_H_
diff --git a/chrome/browser/nearby_sharing/share_target_info.cc b/chrome/browser/nearby_sharing/share_target_info.cc new file mode 100644 index 0000000..d044181 --- /dev/null +++ b/chrome/browser/nearby_sharing/share_target_info.cc
@@ -0,0 +1,14 @@ +// 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/nearby_sharing/share_target_info.h" +#include "chrome/browser/nearby_sharing/nearby_connection.h" + +ShareTargetInfo::ShareTargetInfo() = default; + +ShareTargetInfo::ShareTargetInfo(ShareTargetInfo&&) = default; + +ShareTargetInfo& ShareTargetInfo::operator=(ShareTargetInfo&&) = default; + +ShareTargetInfo::~ShareTargetInfo() = default;
diff --git a/chrome/browser/nearby_sharing/share_target_info.h b/chrome/browser/nearby_sharing/share_target_info.h new file mode 100644 index 0000000..38833893 --- /dev/null +++ b/chrome/browser/nearby_sharing/share_target_info.h
@@ -0,0 +1,66 @@ +// 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_NEARBY_SHARING_SHARE_TARGET_INFO_H_ +#define CHROME_BROWSER_NEARBY_SHARING_SHARE_TARGET_INFO_H_ + +#include <memory> +#include <string> + +#include "base/optional.h" +#include "chrome/browser/nearby_sharing/certificates/nearby_share_decrypted_public_certificate.h" +#include "chrome/browser/nearby_sharing/incoming_frames_reader.h" + +class NearbyConnection; + +// Additional information about the connection to a remote device. +class ShareTargetInfo { + public: + ShareTargetInfo(); + ShareTargetInfo(ShareTargetInfo&&); + ShareTargetInfo& operator=(ShareTargetInfo&&); + virtual ~ShareTargetInfo(); + + const base::Optional<std::string>& endpoint_id() const { + return endpoint_id_; + } + + void set_endpoint_id(std::string endpoint_id) { + endpoint_id_ = std::move(endpoint_id); + } + + const base::Optional<NearbyShareDecryptedPublicCertificate>& certificate() + const { + return certificate_; + } + + void set_certificate(NearbyShareDecryptedPublicCertificate certificate) { + certificate_ = std::move(certificate); + } + + NearbyConnection* connection() const { return connection_; } + + void set_connection(NearbyConnection* connection) { + connection_ = connection; + } + + const base::Optional<std::string>& token() const { return token_; } + + void set_token(std::string token) { token_ = std::move(token); } + + IncomingFramesReader* frames_reader() const { return frames_reader_.get(); } + + void set_frames_reader(std::unique_ptr<IncomingFramesReader> frames_reader) { + frames_reader_ = std::move(frames_reader); + } + + private: + base::Optional<std::string> endpoint_id_; + base::Optional<NearbyShareDecryptedPublicCertificate> certificate_; + NearbyConnection* connection_ = nullptr; + base::Optional<std::string> token_; + std::unique_ptr<IncomingFramesReader> frames_reader_; +}; + +#endif // CHROME_BROWSER_NEARBY_SHARING_SHARE_TARGET_INFO_H_
diff --git a/chrome/browser/net/variations_http_headers_browsertest.cc b/chrome/browser/net/variations_http_headers_browsertest.cc index 51943f5..ec575b06 100644 --- a/chrome/browser/net/variations_http_headers_browsertest.cc +++ b/chrome/browser/net/variations_http_headers_browsertest.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" #include "chrome/browser/predictors/predictors_features.h" +#include "chrome/browser/predictors/predictors_switches.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/browser.h" @@ -625,6 +626,12 @@ feature_list_.InitWithFeaturesAndParameters(enabled, disabled); } + void SetUpCommandLine(base::CommandLine* command_line) override { + VariationsHttpHeadersBrowserTest::SetUpCommandLine(command_line); + command_line->AppendSwitch( + switches::kLoadingPredictorAllowLocalRequestForTesting); + } + std::unique_ptr<content::TestNavigationManager> NavigateToURLAsync( const GURL& url) { chrome::NewTab(browser());
diff --git a/chrome/browser/optimization_guide/android/BUILD.gn b/chrome/browser/optimization_guide/android/BUILD.gn index 991c5c8a..f31f043 100644 --- a/chrome/browser/optimization_guide/android/BUILD.gn +++ b/chrome/browser/optimization_guide/android/BUILD.gn
@@ -20,7 +20,7 @@ "//components/optimization_guide/proto:optimization_guide_proto_java", "//content/public/android:content_java", "//third_party/android_deps:androidx_annotation_annotation_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", ] srcjar_deps =
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc b/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc index 3746f1c..f2fb8ac 100644 --- a/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc +++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc
@@ -10,6 +10,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/optional.h" +#include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/browser/optimization_guide/optimization_guide_hints_manager.h" #include "chrome/browser/optimization_guide/optimization_guide_navigation_data.h" #include "chrome/browser/optimization_guide/optimization_guide_session_statistic.h" @@ -111,8 +112,12 @@ Profile* profile = Profile::FromBrowserContext(browser_context_); top_host_provider_ = GetTopHostProviderIfUserPermitted(browser_context_); + bool optimization_guide_fetching_enabled = top_host_provider_ != nullptr; UMA_HISTOGRAM_BOOLEAN("OptimizationGuide.RemoteFetchingEnabled", - top_host_provider_ != nullptr); + optimization_guide_fetching_enabled); + ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial( + "SyntheticOptimizationGuideRemoteFetching", + optimization_guide_fetching_enabled ? "Enabled" : "Disabled"); scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory = content::BrowserContext::GetDefaultStoragePartition(profile) ->GetURLLoaderFactoryForBrowserProcess();
diff --git a/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc b/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc index 5098f70..e482b31a 100644 --- a/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc +++ b/chrome/browser/optimization_guide/optimization_guide_keyed_service_browsertest.cc
@@ -29,6 +29,8 @@ #include "components/prefs/pref_service.h" #include "components/previews/core/previews_switches.h" #include "components/ukm/test_ukm_recorder.h" +#include "components/variations/active_field_trials.h" +#include "components/variations/hashing.h" #include "content/public/browser/navigation_handle.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -242,6 +244,19 @@ consumer_->set_callback(std::move(callback)); } + // Returns whether the synthetic trial |trial_name| has been logged and is in + // the |trial_group| for the trial. + bool IsInSyntheticTrialGroup(const std::string& trial_name, + const std::string& trial_group) { + std::vector<std::string> synthetic_trials; + variations::GetSyntheticTrialGroupIdsAsString(&synthetic_trials); + std::string expected_entry = + base::StringPrintf("%x-%x", variations::HashName(trial_name), + variations::HashName(trial_group)); + return std::find(synthetic_trials.begin(), synthetic_trials.end(), + expected_entry) != synthetic_trials.end(); + } + // Returns the last decision from the CanApplyOptimization() method seen by // the consumer of the OptimizationGuideKeyedService. optimization_guide::OptimizationGuideDecision @@ -301,6 +316,8 @@ #if !defined(OS_CHROMEOS) histogram_tester()->ExpectUniqueSample( "OptimizationGuide.RemoteFetchingEnabled", false, 1); + EXPECT_TRUE(IsInSyntheticTrialGroup( + "SyntheticOptimizationGuideRemoteFetching", "Disabled")); #endif } @@ -595,6 +612,8 @@ #if !defined(OS_CHROMEOS) histogram_tester()->ExpectUniqueSample( "OptimizationGuide.RemoteFetchingEnabled", true, 1); + EXPECT_TRUE(IsInSyntheticTrialGroup( + "SyntheticOptimizationGuideRemoteFetching", "Enabled")); #endif } @@ -627,5 +646,7 @@ #if !defined(OS_CHROMEOS) histogram_tester()->ExpectUniqueSample( "OptimizationGuide.RemoteFetchingEnabled", true, 1); + EXPECT_TRUE(IsInSyntheticTrialGroup( + "SyntheticOptimizationGuideRemoteFetching", "Enabled")); #endif }
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc index c853051..94f9a9d 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer.cc
@@ -453,9 +453,12 @@ client->GetThrottleManager()->LoadPolicyForLastCommittedNavigation( frame_host); - // If there is not load policy use |is_adframe| solely. + // Only un-tag frames as ads if the navigation has committed. This prevents + // frames from being untagged that have an aborted navigation to allowlist + // urls. if (restricted_navigation_ad_tagging_enabled_ && load_policy && - navigation_handle->GetNetErrorCode() == net::OK) { + navigation_handle->GetNetErrorCode() == net::OK && + navigation_handle->HasCommitted()) { // If a filter list explicitly allows the rule, we should ignore a detected // ad. bool navigation_is_explicitly_allowed =
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc index 3e6b819..9a76fc25 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_unittest.cc
@@ -110,6 +110,7 @@ const char kAdUrl[] = "https://ads.com/ad/disallowed.html"; const char kNonAdUrl[] = "https://foo.com/"; const char kNonAdUrlSameOrigin[] = "https://ads.com/foo"; +const char kAllowedUrl[] = "https://foo.com/ad/not_disallowed.html"; const int kMaxHeavyAdNetworkBytes = heavy_ad_thresholds::kMaxNetworkBytes + @@ -1378,6 +1379,45 @@ 0 /* non_ad_cached_kb */, 10 /* non_ad_uncached_kb */); } +TEST_F(AdsPageLoadMetricsObserverTest, + FrameAbortsCommitMatchingAllowedRule_FrameTracked) { + RenderFrameHost* main_frame = NavigateMainFrame(kAdUrl); + + // Create a frame that is tagged as ad. + RenderFrameHost* subframe = + RenderFrameHostTester::For(main_frame)->AppendChild("frame_name"); + auto navigation_simulator = NavigationSimulator::CreateRendererInitiated( + GURL("https://foo.com"), subframe); + OnAdSubframeDetected(subframe); + navigation_simulator->Commit(); + + subframe = navigation_simulator->GetFinalRenderFrameHost(); + + RenderFrameHost* nested_subframe = + CreateAndNavigateSubFrame(kNonAdUrl, subframe); + + // Navigate the frame same-origin to a url matching an allowlist rule, but + // abort the navigation so it does not commit. + auto navigation_simulator2 = + NavigationSimulator::CreateRendererInitiated(GURL(kAllowedUrl), subframe); + navigation_simulator2->ReadyToCommit(); + navigation_simulator2->AbortCommit(); + + // Verify per-frame metrics were not flushed. + histogram_tester().ExpectTotalCount( + SuffixedHistogram("FrameCounts.IgnoredByRestrictedAdTagging"), 0); + + // Update the nested subframe. If the frame was untracked the underlying + // object would be deleted. + ResourceDataUpdate(nested_subframe, ResourceCached::kNotCached, 10); + + NavigateMainFrame(kNonAdUrl); + + // Verify histograms for the frame. + TestHistograms(histogram_tester(), test_ukm_recorder(), {{0, 10}}, + 0 /* non_ad_cached_kb */, 0 /* non_ad_uncached_kb */); +} + // Tests that a non ad frame that is deleted does not cause any unspecified // behavior (see https://crbug.com/973954). TEST_F(AdsPageLoadMetricsObserverTest, NonAdFrameDestroyed_FrameDeleted) {
diff --git a/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_item.xml b/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_item.xml index df04cc49..f141ef69 100644 --- a/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_item.xml +++ b/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_item.xml
@@ -49,6 +49,15 @@ android:text="@string/password_check_credential_row_change_button_caption" style="@style/FilledButton.Flat" /> + <TextView + android:id="@+id/credential_change_hint" + android:text="@string/password_check_credential_row_change_button_hint" + android:layout_marginTop="@dimen/compromised_credential_row_button_margin_top" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:textAppearance="@style/TextAppearance.TextMedium.Secondary" + android:visibility="gone" /> + </LinearLayout> <org.chromium.components.browser_ui.widget.listmenu.ListMenuButton
diff --git a/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_with_script_item.xml b/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_with_script_item.xml index de7fb8e..96cd250 100644 --- a/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_with_script_item.xml +++ b/chrome/browser/password_check/android/internal/java/res/layout/password_check_compromised_credential_with_script_item.xml
@@ -67,6 +67,15 @@ android:text="@string/password_check_credential_row_change_manually_button_caption" style="@style/TextButton"/> + <TextView + android:id="@+id/credential_change_hint" + android:text="@string/password_check_credential_row_change_button_hint" + android:layout_marginTop="@dimen/compromised_credential_row_button_margin_top" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:textAppearance="@style/TextAppearance.TextMedium.Secondary" + android:visibility="gone" /> + </LinearLayout> <org.chromium.components.browser_ui.widget.listmenu.ListMenuButton
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckBridge.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckBridge.java index 3ff351d..180e73df 100644 --- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckBridge.java +++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckBridge.java
@@ -54,13 +54,15 @@ // TODO(crbug.com/1102025): Add call from native. void onCompromisedCredentialFound(String signonRealm, GURL origin, String username, - String displayOrigin, String displayUsername, String password, boolean hasScript) { + String displayOrigin, String displayUsername, String password, String passwordChangeUrl, + String associatedApp, boolean hasScript) { assert signonRealm != null; assert displayOrigin != null; assert username != null; assert password != null; mPasswordCheckObserver.onCompromisedCredentialFound(new CompromisedCredential(signonRealm, - origin, username, displayOrigin, displayUsername, password, false, hasScript)); + origin, username, displayOrigin, displayUsername, password, passwordChangeUrl, + associatedApp, false, hasScript)); } @CalledByNative @@ -81,9 +83,10 @@ @CalledByNative private static void insertCredential(CompromisedCredential[] credentials, int index, String signonRealm, GURL origin, String username, String displayOrigin, - String displayUsername, String password, boolean phished, boolean hasScript) { + String displayUsername, String password, String passwordChangeUrl, String associatedApp, + boolean phished, boolean hasScript) { credentials[index] = new CompromisedCredential(signonRealm, origin, username, displayOrigin, - displayUsername, password, phished, hasScript); + displayUsername, password, passwordChangeUrl, associatedApp, phished, hasScript); } /**
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckCoordinator.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckCoordinator.java index bd025f27..3a26739 100644 --- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckCoordinator.java +++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckCoordinator.java
@@ -12,9 +12,7 @@ import androidx.annotation.VisibleForTesting; import androidx.browser.customtabs.CustomTabsIntent; -import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; -import androidx.lifecycle.OnLifecycleEvent; import org.chromium.base.IntentUtils; import org.chromium.chrome.browser.IntentHandler; @@ -24,12 +22,14 @@ import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; +import java.util.Objects; + /** * Creates the PasswordCheckComponentUi. This class is responsible for managing the UI for the check * of the leaked password. */ -class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObserver { - private static final String WELL_KNOWN_URL_PATH = "/.well-known/change-password"; +class PasswordCheckCoordinator implements PasswordCheckComponentUi, LifecycleObserver, + PasswordCheckComponentUi.ChangePasswordDelegate { private static final String AUTOFILL_ASSISTANT_PACKAGE = "org.chromium.chrome.browser.autofill_assistant."; private static final String AUTOFILL_ASSISTANT_ENABLED_KEY = @@ -39,8 +39,7 @@ private static final String INTENT = "PASSWORD_CHANGE"; private final PasswordCheckFragmentView mFragmentView; - private final PasswordCheckMediator mMediator = new PasswordCheckMediator( - this::launchCctWithChangePasswordUrl, this::launchCctWithScript); + private final PasswordCheckMediator mMediator = new PasswordCheckMediator(this); private PropertyModel mModel; /** @@ -77,11 +76,14 @@ mFragmentView = fragmentView; // TODO(crbug.com/1101256): If help is part of the view, make mediator the delegate. mFragmentView.setComponentDelegate(this); - mFragmentView.getLifecycle().addObserver(this); + + // TODO(crbug.com/1092444): Ideally, the following replaces the lifecycle event forwarding. + // Figure out why it isn't working and use the following lifecycle observer once it does: + // mFragmentView.getLifecycle().addObserver(this); } - @OnLifecycleEvent(Lifecycle.Event.ON_START) - public void connectToModelWhenViewIsReady() { + @Override + public void onStartFragment() { // In the rare case of a restarted activity, don't recreate the model and mediator. if (mModel == null) { mModel = PasswordCheckProperties.createDefaultModel(); @@ -91,10 +93,14 @@ } } - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) - public void stopCheck() { + @Override + public void onDestroyFragment() { PasswordCheck check = PasswordCheckFactory.getPasswordCheckInstance(); if (check != null) check.stopCheck(); + if (mFragmentView.getActivity() == null || mFragmentView.getActivity().isFinishing()) { + mMediator.destroy(); + mModel = null; + } } // TODO(crbug.com/1101256): Move to view code. @@ -112,7 +118,6 @@ @Override public void destroy() { - mMediator.destroy(); PasswordCheckFactory.destroy(); } @@ -129,25 +134,41 @@ /** * Launches a CCT that points to the change password form or home page of |origin|. - * @param origin Origin of the site to be opened in a CCT. + * @param credential A {@link CompromisedCredential} to be changed in an App or in a CCT. */ - private void launchCctWithChangePasswordUrl(String origin) { - // TODO(crbug.com/1092444): Handle the case when an app should be opened. Consider to set - // |browser_fallback_url|, it is used in case of error while opening a CCT. - Intent intent = buildIntent(origin + WELL_KNOWN_URL_PATH); - IntentUtils.safeStartActivity(mFragmentView.getActivity(), intent); + @Override + public void launchAppOrCctWithChangePasswordUrl(CompromisedCredential credential) { + // TODO(crbug.com/1092444): Always launch the URL if possible and let Android handle the + // match to open it. + IntentUtils.safeStartActivity(mFragmentView.getActivity(), + credential.getAssociatedApp().isEmpty() + ? buildIntent(credential.getPasswordChangeUrl()) + : getPackageLaunchIntent(credential.getAssociatedApp())); + } + + @Override + public boolean canManuallyChangeCredential(CompromisedCredential credential) { + return !credential.getPasswordChangeUrl().isEmpty() + || getPackageLaunchIntent(credential.getAssociatedApp()) != null; } /** * Launches a CCT that starts a password change script for a {@link CompromisedCredential}. * @param credential A {@link CompromisedCredential} to be changed with a script. */ - private void launchCctWithScript(CompromisedCredential credential) { + @Override + public void launchCctWithScript(CompromisedCredential credential) { Intent intent = buildIntent(credential.getOrigin().getSpec()); populateAutofillAssistantExtras(intent, credential.getUsername()); IntentUtils.safeStartActivity(mFragmentView.getActivity(), intent); } + private Intent getPackageLaunchIntent(String packageName) { + return Objects.requireNonNull(mFragmentView.getActivity()) + .getPackageManager() + .getLaunchIntentForPackage(packageName); + } + /** * Builds an intent to launch a CCT. * @param initialUrl Initial URL to launch a CCT.
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java index 245506b..3284d30 100644 --- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java +++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckMediator.java
@@ -6,6 +6,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.COMPROMISED_CREDENTIAL; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.CREDENTIAL_HANDLER; +import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.HAS_MANUAL_CHANGE_BUTTON; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.DELETION_CONFIRMATION_HANDLER; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.DELETION_ORIGIN; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_PROGRESS; @@ -21,7 +22,6 @@ import androidx.appcompat.app.AlertDialog; -import org.chromium.base.Consumer; import org.chromium.ui.modelutil.ListModel; import org.chromium.ui.modelutil.MVCListAdapter.ListItem; import org.chromium.ui.modelutil.PropertyModel; @@ -32,15 +32,12 @@ */ class PasswordCheckMediator implements PasswordCheckCoordinator.CredentialEventHandler, PasswordCheck.Observer { + private final PasswordCheckComponentUi.ChangePasswordDelegate mChangePasswordDelegate; private PropertyModel mModel; private PasswordCheckComponentUi.Delegate mDelegate; - private final Consumer<String> mLaunchCctWithChangePasswordUrl; - private final Consumer<CompromisedCredential> mLaunchCctWithScript; - PasswordCheckMediator(Consumer<String> launchCctWithChangePasswordUrl, - Consumer<CompromisedCredential> launchCctWithScript) { - this.mLaunchCctWithChangePasswordUrl = launchCctWithChangePasswordUrl; - this.mLaunchCctWithScript = launchCctWithScript; + PasswordCheckMediator(PasswordCheckCoordinator.ChangePasswordDelegate changePasswordDelegate) { + mChangePasswordDelegate = changePasswordDelegate; } void initialize(PropertyModel model, PasswordCheckComponentUi.Delegate delegate, @@ -76,15 +73,7 @@ if (items.size() > 1) items.removeRange(1, items.size() - 1); for (CompromisedCredential credential : credentials) { - items.add(new ListItem(credential.hasScript() - ? PasswordCheckProperties.ItemType.COMPROMISED_CREDENTIAL_WITH_SCRIPT - : PasswordCheckProperties.ItemType.COMPROMISED_CREDENTIAL, - new PropertyModel - .Builder(PasswordCheckProperties.CompromisedCredentialProperties - .ALL_KEYS) - .with(COMPROMISED_CREDENTIAL, credential) - .with(CREDENTIAL_HANDLER, this) - .build())); + items.add(createEntryForCredential(credential)); } } @@ -141,14 +130,7 @@ assert leakedCredential != null; ListModel<ListItem> items = mModel.get(ITEMS); assert items.size() >= 1 : "Needs to initialize list with header before adding items!"; - items.add(new ListItem(leakedCredential.hasScript() - ? PasswordCheckProperties.ItemType.COMPROMISED_CREDENTIAL_WITH_SCRIPT - : PasswordCheckProperties.ItemType.COMPROMISED_CREDENTIAL, - new PropertyModel - .Builder(PasswordCheckProperties.CompromisedCredentialProperties.ALL_KEYS) - .with(COMPROMISED_CREDENTIAL, leakedCredential) - .with(CREDENTIAL_HANDLER, this) - .build())); + items.add(createEntryForCredential(leakedCredential)); } @Override @@ -178,13 +160,13 @@ @Override public void onChangePasswordButtonClick(CompromisedCredential credential) { - mLaunchCctWithChangePasswordUrl.accept(credential.getSignonRealm()); + mChangePasswordDelegate.launchAppOrCctWithChangePasswordUrl(credential); } @Override public void onChangePasswordWithScriptButtonClick(CompromisedCredential credential) { assert credential.hasScript(); - mLaunchCctWithScript.accept(credential); + mChangePasswordDelegate.launchCctWithScript(credential); } private void runCheck() { @@ -196,4 +178,17 @@ assert passwordCheck != null : "Password Check UI component needs native counterpart!"; return passwordCheck; } + + private ListItem createEntryForCredential(CompromisedCredential credential) { + return new ListItem(credential.hasScript() + ? PasswordCheckProperties.ItemType.COMPROMISED_CREDENTIAL_WITH_SCRIPT + : PasswordCheckProperties.ItemType.COMPROMISED_CREDENTIAL, + new PropertyModel + .Builder(PasswordCheckProperties.CompromisedCredentialProperties.ALL_KEYS) + .with(COMPROMISED_CREDENTIAL, credential) + .with(HAS_MANUAL_CHANGE_BUTTON, + mChangePasswordDelegate.canManuallyChangeCredential(credential)) + .with(CREDENTIAL_HANDLER, this) + .build()); + } }
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckProperties.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckProperties.java index bab2d93..6cff4fd 100644 --- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckProperties.java +++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckProperties.java
@@ -44,8 +44,11 @@ static final PropertyModel.ReadableObjectPropertyKey< PasswordCheckCoordinator.CredentialEventHandler> CREDENTIAL_HANDLER = new PropertyModel.ReadableObjectPropertyKey<>("credential_handler"); + static final PropertyModel.ReadableBooleanPropertyKey HAS_MANUAL_CHANGE_BUTTON = + new PropertyModel.ReadableBooleanPropertyKey("has_change_button"); - static final PropertyKey[] ALL_KEYS = {COMPROMISED_CREDENTIAL, CREDENTIAL_HANDLER}; + static final PropertyKey[] ALL_KEYS = { + COMPROMISED_CREDENTIAL, CREDENTIAL_HANDLER, HAS_MANUAL_CHANGE_BUTTON}; private CompromisedCredentialProperties() {} }
diff --git a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java index 176ca85..facc2be 100644 --- a/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java +++ b/chrome/browser/password_check/android/internal/java/src/org/chromium/chrome/browser/password_check/PasswordCheckViewBinder.java
@@ -6,6 +6,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.COMPROMISED_CREDENTIAL; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.CREDENTIAL_HANDLER; +import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.HAS_MANUAL_CHANGE_BUTTON; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.DELETION_CONFIRMATION_HANDLER; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.DELETION_ORIGIN; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_PROGRESS; @@ -153,6 +154,13 @@ } else if (propertyKey == CREDENTIAL_HANDLER) { assert model.get(CREDENTIAL_HANDLER) != null; // Is read-only and must therefore be bound initially, so no action required. + } else if (propertyKey == HAS_MANUAL_CHANGE_BUTTON) { + ButtonCompat button = view.findViewById(R.id.credential_change_button); + button.setVisibility(model.get(HAS_MANUAL_CHANGE_BUTTON) ? View.VISIBLE : View.GONE); + TextView changeHint = view.findViewById(R.id.credential_change_hint); + changeHint.setVisibility(model.get(HAS_MANUAL_CHANGE_BUTTON) || credential.hasScript() + ? View.GONE + : View.VISIBLE); } else { assert false : "Unhandled update to property:" + propertyKey; }
diff --git a/chrome/browser/password_check/android/internal/java/strings/android_password_check_strings.grd b/chrome/browser/password_check/android/internal/java/strings/android_password_check_strings.grd index f5c528d..53e9d0a2 100644 --- a/chrome/browser/password_check/android/internal/java/strings/android_password_check_strings.grd +++ b/chrome/browser/password_check/android/internal/java/strings/android_password_check_strings.grd
@@ -175,6 +175,9 @@ <message name="IDS_PASSWORD_CHECK_CREDENTIAL_ROW_CHANGE_BUTTON_CAPTION" desc="Caption for the primary button in the list of compromised credentials."> Change password </message> + <message name="IDS_PASSWORD_CHECK_CREDENTIAL_ROW_CHANGE_BUTTON_HINT" desc="Small hint text explaining that the user needs to manually change the password in an external app."> + Change the password in the app + </message> <message name="IDS_PASSWORD_CHECK_CREDENTIAL_ROW_CHANGE_MANUALLY_BUTTON_CAPTION" desc="Caption for the secondary button in the list of compromised credentials."> Change manually </message>
diff --git a/chrome/browser/password_check/android/internal/java/strings/android_password_check_strings_grd/IDS_PASSWORD_CHECK_CREDENTIAL_ROW_CHANGE_BUTTON_HINT.png.sha1 b/chrome/browser/password_check/android/internal/java/strings/android_password_check_strings_grd/IDS_PASSWORD_CHECK_CREDENTIAL_ROW_CHANGE_BUTTON_HINT.png.sha1 new file mode 100644 index 0000000..835ae3cb --- /dev/null +++ b/chrome/browser/password_check/android/internal/java/strings/android_password_check_strings_grd/IDS_PASSWORD_CHECK_CREDENTIAL_ROW_CHANGE_BUTTON_HINT.png.sha1
@@ -0,0 +1 @@ +2a20fe1de9852cd461b6ad7da110e3ff49ecac5a \ No newline at end of file
diff --git a/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/CompromisedCredential.java b/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/CompromisedCredential.java index 8ae10f3..0b20f34 100644 --- a/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/CompromisedCredential.java +++ b/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/CompromisedCredential.java
@@ -20,6 +20,8 @@ private final String mDisplayOrigin; private final String mDisplayUsername; private final String mPassword; + private final String mPasswordChangeUrl; + private final String mAssociatedApp; private final boolean mPhished; private final boolean mHasScript; @@ -31,20 +33,29 @@ * missing scheme). * @param displayUsername The username displayed to the user (substituted if empty). * @param password The compromised password. + * @param passwordChangeUrl A URL that links to the password change form of the affected site. + * @param associatedApp The associated app if the password originates from it. * @param phished True iff the credential was entered on an unsafe site. * @param hasScript True iff the credential can be automatically fixed. */ public CompromisedCredential(String signonRealm, GURL origin, String username, - String displayOrigin, String displayUsername, String password, boolean phished, - boolean hasScript) { + String displayOrigin, String displayUsername, String password, String passwordChangeUrl, + String associatedApp, boolean phished, boolean hasScript) { assert origin != null : "Credential origin is null! Pass an empty one instead."; assert signonRealm != null; + assert passwordChangeUrl != null : "Change URL may be empty but not null!"; + assert associatedApp != null : "App package name may be empty but not null!"; + assert !passwordChangeUrl.isEmpty() + || !associatedApp.isEmpty() + : "Change URL and app name may not be empty at the same time!"; mSignonRealm = signonRealm; mOrigin = origin; mUsername = username; mDisplayOrigin = displayOrigin; mDisplayUsername = displayUsername; mPassword = password; + mPasswordChangeUrl = passwordChangeUrl; + mAssociatedApp = associatedApp; mPhished = phished; mHasScript = hasScript; } @@ -74,6 +85,13 @@ public boolean isPhished() { return mPhished; } + public String getAssociatedApp() { + return mAssociatedApp; + } + + public String getPasswordChangeUrl() { + return mPasswordChangeUrl; + } public boolean hasScript() { return mHasScript; } @@ -86,7 +104,9 @@ return mSignonRealm.equals(that.mSignonRealm) && mOrigin.equals(that.mOrigin) && mUsername.equals(that.mUsername) && mDisplayOrigin.equals(that.mDisplayOrigin) && mDisplayUsername.equals(that.mDisplayUsername) - && mPassword.equals(that.mPassword) && mPhished == that.mPhished + && mPassword.equals(that.mPassword) + && mPasswordChangeUrl.equals(that.mPasswordChangeUrl) + && mAssociatedApp.equals(that.mAssociatedApp) && mPhished == that.mPhished && mHasScript == that.mHasScript; } @@ -96,12 +116,14 @@ + "signonRealm='" + mSignonRealm + ", origin='" + mOrigin + '\'' + '\'' + ", username='" + mUsername + '\'' + ", displayOrigin='" + mDisplayOrigin + '\'' + ", displayUsername='" + mDisplayUsername + '\'' + ", password='" + mPassword - + '\'' + ", phished=" + mPhished + ", hasScript=" + mHasScript + '}'; + + '\'' + ", passwordChangeUrl='" + mPasswordChangeUrl + '\'' + ", associatedApp='" + + mAssociatedApp + '\'' + ", phished=" + mPhished + ", hasScript=" + mHasScript + + '}'; } @Override public int hashCode() { return Objects.hash(mSignonRealm, mOrigin, mUsername, mDisplayOrigin, mDisplayUsername, - mPassword, mPhished, mHasScript); + mPassword, mPasswordChangeUrl, mAssociatedApp, mPhished, mHasScript); } }
diff --git a/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckComponentUi.java b/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckComponentUi.java index 35121d6..fcd9879 100644 --- a/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckComponentUi.java +++ b/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckComponentUi.java
@@ -22,12 +22,47 @@ } /** + * Implementers of this delegate are expected to launch apps or Chrome Custom tabs that enable + * the user to change a compromised password. + */ + interface ChangePasswordDelegate { + /** + * @param credential A {@link CompromisedCredential}. + * @return True iff there is a valid URL to navigate to or an app that can be opened. + */ + boolean canManuallyChangeCredential(CompromisedCredential credential); + + /** + * Launches an app (if available) or a CCT with the site the given credential was used on. + * @param credential A {@link CompromisedCredential}. + */ + void launchAppOrCctWithChangePasswordUrl(CompromisedCredential credential); + + /** + * Launches a CCT with the site the given credential was used on and invokes the script that + * fixes the compromised credential automatically. + * @param credential A {@link CompromisedCredential}. + */ + void launchCctWithScript(CompromisedCredential credential); + } + + /** * Handle the request of the user to show the help page for the Check Passwords view. * @param item A {@link MenuItem}. */ boolean handleHelp(MenuItem item); /** + * Forwards the signal that the fragment was started. + */ + void onStartFragment(); + + /** + * Forwards the signal that the fragment is being destroyed. + */ + void onDestroyFragment(); + + /** * Tears down the component when it's no longer needed. */ void destroy();
diff --git a/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckFragmentView.java b/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckFragmentView.java index 0efc013c..84a27a4 100644 --- a/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckFragmentView.java +++ b/chrome/browser/password_check/android/java/src/org/chromium/chrome/browser/password_check/PasswordCheckFragmentView.java
@@ -38,6 +38,12 @@ mPasswordCheckReferrer = getReferrerFromInstanceStateOrLaunchBundle(savedInstanceState); } + @Override + public void onStart() { + super.onStart(); + mComponentDelegate.onStartFragment(); + } + private @PasswordCheckReferrer int getReferrerFromInstanceStateOrLaunchBundle( Bundle savedInstanceState) { if (savedInstanceState != null && savedInstanceState.containsKey(PASSWORD_CHECK_REFERRER)) { @@ -56,6 +62,7 @@ // The component should only be destroyed when the activity has been closed by the user // (e.g. by pressing on the back button) and not when the activity is temporarily destroyed // by the system. + mComponentDelegate.onDestroyFragment(); if (getActivity().isFinishing() && mPasswordCheckReferrer == PasswordCheckReferrer.LEAK_DIALOG) { mComponentDelegate.destroy();
diff --git a/chrome/browser/password_check/android/javatests/src/org/chromium/chrome/browser/password_check/PasswordCheckViewTest.java b/chrome/browser/password_check/android/javatests/src/org/chromium/chrome/browser/password_check/PasswordCheckViewTest.java index 3558f14d..f65d110 100644 --- a/chrome/browser/password_check/android/javatests/src/org/chromium/chrome/browser/password_check/PasswordCheckViewTest.java +++ b/chrome/browser/password_check/android/javatests/src/org/chromium/chrome/browser/password_check/PasswordCheckViewTest.java
@@ -15,14 +15,13 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.COMPROMISED_CREDENTIAL; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.CREDENTIAL_HANDLER; +import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.HAS_MANUAL_CHANGE_BUTTON; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.DELETION_CONFIRMATION_HANDLER; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.DELETION_ORIGIN; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_PROGRESS; @@ -43,6 +42,7 @@ import static org.chromium.content_public.browser.test.util.CriteriaHelper.pollUiThread; import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; +import android.content.DialogInterface; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -56,7 +56,6 @@ import android.widget.TextView; import androidx.annotation.IdRes; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.content.res.AppCompatResources; import androidx.recyclerview.widget.RecyclerView; import androidx.test.filters.MediumTest; @@ -85,24 +84,29 @@ import org.chromium.ui.widget.ButtonCompat; import org.chromium.url.GURL; +import java.util.concurrent.atomic.AtomicInteger; + /** * View tests for the Password Check component ensure model changes are reflected in the check UI. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class PasswordCheckViewTest { - private static final CompromisedCredential ANA = new CompromisedCredential( - "https://some-url.com/signin", new GURL("https://some-url.com/"), "Ana", "some-url.com", - "Ana", "password", false, false); + private static final CompromisedCredential ANA = + new CompromisedCredential("https://some-url.com/signin", + new GURL("https://some-url.com/"), "Ana", "some-url.com", "Ana", "password", + "https://some-url.com/.well-known/change-password", "", false, false); private static final CompromisedCredential PHISHED = new CompromisedCredential("http://example.com/signin", new GURL("http://example.com/"), - "", "http://example.com", "(No username)", "DoSomething", true, false); - private static final CompromisedCredential LEAKED = new CompromisedCredential( - "https://some-other-url.com/signin", new GURL("https://some-other-url.com/"), - "AZiegler", "some-other-url.com", "AZiegler", "N0M3rcy", false, false); - private static final CompromisedCredential SCRIPTED = - new CompromisedCredential("https://script.com/signin", new GURL("https://script.com/"), - "Charlie", "script.com", "Charlie", "secret", false, true); + "", "http://example.com", "(No username)", "DoSomething", + "http://example.com/.well-known/change-password", "", true, false); + private static final CompromisedCredential LEAKED = + new CompromisedCredential("https://some-other-url.com/signin", + new GURL("https://some-other-url.com/"), "AZiegler", "some-other-url.com", + "AZiegler", "N0M3rcy", "", "com.other.package", false, false); + private static final CompromisedCredential SCRIPTED = new CompromisedCredential( + "https://script.com/signin", new GURL("https://script.com/"), "Charlie", "script.com", + "Charlie", "secret", "https://script.com/.well-known/change-password", "", false, true); private static final int LEAKS_COUNT = 2; @@ -390,7 +394,7 @@ @Test @MediumTest - public void testCrendentialDisplaysNameOriginAndReason() { + public void testCredentialDisplaysNameOriginAndReason() { runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildCredentialItem(PHISHED)); mModel.get(ITEMS).add(buildCredentialItem(LEAKED)); @@ -402,17 +406,44 @@ assertThat(getCredentialUserAt(0).getText(), is(PHISHED.getDisplayUsername())); assertThat(getCredentialReasonAt(0).getText(), is(getString(R.string.password_check_credential_row_reason_phished))); + assertThat(getCredentialChangeButtonAt(0).getVisibility(), is(View.VISIBLE)); + assertThat(getCredentialChangeHintAt(0).getVisibility(), is(View.GONE)); // The leaked credential is rendered second: assertThat(getCredentialOriginAt(1).getText(), is(LEAKED.getDisplayOrigin())); assertThat(getCredentialUserAt(1).getText(), is(LEAKED.getDisplayUsername())); assertThat(getCredentialReasonAt(1).getText(), is(getString(R.string.password_check_credential_row_reason_leaked))); + assertThat(getCredentialChangeButtonAt(1).getVisibility(), is(View.VISIBLE)); + assertThat(getCredentialChangeHintAt(1).getVisibility(), is(View.GONE)); } @Test @MediumTest - public void testCrendentialDisplaysChangeButtonWithScript() { + public void testHidesCredentialChangeButtonWithoutValidEntryPoint() { + runOnUiThreadBlocking( + () + -> mModel.get(ITEMS).add(new MVCListAdapter.ListItem( + PasswordCheckProperties.ItemType.COMPROMISED_CREDENTIAL, + new PropertyModel + .Builder(PasswordCheckProperties + .CompromisedCredentialProperties.ALL_KEYS) + .with(COMPROMISED_CREDENTIAL, ANA) + .with(HAS_MANUAL_CHANGE_BUTTON, false) + .with(CREDENTIAL_HANDLER, mMockHandler) + .build()))); + waitForListViewToHaveLength(1); + + // The credential has no change button: + assertThat(getCredentialOriginAt(0).getText(), is(ANA.getDisplayOrigin())); + assertThat(getCredentialUserAt(0).getText(), is(ANA.getDisplayUsername())); + assertThat(getCredentialChangeButtonAt(0).getVisibility(), is(View.GONE)); + assertThat(getCredentialChangeHintAt(0).getVisibility(), is(View.VISIBLE)); + } + + @Test + @MediumTest + public void testCredentialDisplaysChangeButtonWithScript() { runOnUiThreadBlocking(() -> { mModel.get(ITEMS).add(buildCredentialItem(SCRIPTED)); }); pollUiThread(() -> Criteria.checkThat(getPasswordCheckViewList().getChildCount(), is(1))); @@ -439,6 +470,7 @@ assertThat(getCredentialChangeButtonAt(0).getText(), is(getString( R.string.password_check_credential_row_change_manually_button_caption))); + assertThat(getCredentialChangeHintAt(0).getVisibility(), is(View.GONE)); } @Test @@ -512,17 +544,25 @@ @Test @MediumTest public void testConfirmingDeletionDialogTriggersHandler() { - PasswordCheckDeletionDialogFragment.Handler mockHandler = - mock(PasswordCheckDeletionDialogFragment.Handler.class); + final AtomicInteger recordedConfirmation = new AtomicInteger(0); + PasswordCheckDeletionDialogFragment.Handler fakeHandler = + new PasswordCheckDeletionDialogFragment.Handler() { + @Override + public void onDismiss() {} + @Override + public void onClick(DialogInterface dialogInterface, int i) { + recordedConfirmation.incrementAndGet(); + } + }; mModel.set(DELETION_ORIGIN, ANA.getDisplayOrigin()); - runOnUiThreadBlocking(() -> mModel.set(DELETION_CONFIRMATION_HANDLER, mockHandler)); + runOnUiThreadBlocking(() -> mModel.set(DELETION_CONFIRMATION_HANDLER, fakeHandler)); onView(withText(R.string.password_check_delete_credential_dialog_confirm)) .inRoot(withDecorView( not(is(mPasswordCheckView.getActivity().getWindow().getDecorView())))) .perform(click()); - verify(mockHandler).onClick(any(), eq(AlertDialog.BUTTON_POSITIVE)); + assertThat(recordedConfirmation.get(), is(1)); } private MVCListAdapter.ListItem buildHeader(@PasswordCheckUIStatus int status, @@ -559,6 +599,7 @@ new PropertyModel .Builder(PasswordCheckProperties.CompromisedCredentialProperties.ALL_KEYS) .with(COMPROMISED_CREDENTIAL, credential) + .with(HAS_MANUAL_CHANGE_BUTTON, true) .with(CREDENTIAL_HANDLER, mMockHandler) .build()); } @@ -648,6 +689,11 @@ R.id.credential_change_button); } + private TextView getCredentialChangeHintAt(int index) { + return getPasswordCheckViewList().getChildAt(index).findViewById( + R.id.credential_change_hint); + } + private ButtonCompat getCredentialChangeButtonWithScriptAt(int index) { return getPasswordCheckViewList().getChildAt(index).findViewById( R.id.credential_change_button_with_script);
diff --git a/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java b/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java index 683f5b6..450f11c 100644 --- a/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java +++ b/chrome/browser/password_check/android/junit/src/org/chromium/chrome/browser/password_check/PasswordCheckControllerTest.java
@@ -18,6 +18,7 @@ import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.COMPROMISED_CREDENTIAL; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.CREDENTIAL_HANDLER; +import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.CompromisedCredentialProperties.HAS_MANUAL_CHANGE_BUTTON; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.DELETION_CONFIRMATION_HANDLER; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_PROGRESS; import static org.chromium.chrome.browser.password_check.PasswordCheckProperties.HeaderProperties.CHECK_STATUS; @@ -43,7 +44,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.chromium.base.Consumer; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.password_check.PasswordCheckProperties.ItemType; @@ -63,10 +63,10 @@ public class PasswordCheckControllerTest { private static final CompromisedCredential ANA = new CompromisedCredential("https://m.a.xyz/signin", mock(GURL.class), "Ana", "m.a.xyz", - "Ana", "password", false, false); - private static final CompromisedCredential BOB = - new CompromisedCredential("http://www.b.ch/signin", mock(GURL.class), "", - "http://www.b.ch", "(No username)", "DoneSth", false, true); + "Ana", "password", "", "xyz.a.some.package", false, false); + private static final CompromisedCredential BOB = new CompromisedCredential( + "http://www.b.ch/signin", mock(GURL.class), "", "http://www.b.ch", "(No username)", + "DoneSth", "http://www.b.ch/.well-known/change-password", "", false, true); @Rule public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor(); @@ -76,9 +76,7 @@ @Mock private PasswordCheckComponentUi.Delegate mDelegate; @Mock - private Consumer<String> mLaunchCctWithChangePasswordUrlConsumer; - @Mock - private Consumer<CompromisedCredential> mLaunchCctWithScriptConsumer; + private PasswordCheckComponentUi.ChangePasswordDelegate mChangePasswordDelegate; @Mock private PasswordCheck mPasswordCheck; @@ -90,8 +88,7 @@ public void setUp() { MockitoAnnotations.initMocks(this); mModel = PasswordCheckProperties.createDefaultModel(); - mMediator = new PasswordCheckMediator( - mLaunchCctWithChangePasswordUrlConsumer, mLaunchCctWithScriptConsumer); + mMediator = new PasswordCheckMediator(mChangePasswordDelegate); PasswordCheckFactory.setPasswordCheckForTesting(mPasswordCheck); mMediator.initialize(mModel, mDelegate, PasswordCheckReferrer.PASSWORD_SETTINGS); } @@ -165,6 +162,7 @@ public void testCreatesEntryForExistingCredentials() { when(mPasswordCheck.getCompromisedCredentials()) .thenReturn(new CompromisedCredential[] {ANA}); + when(mChangePasswordDelegate.canManuallyChangeCredential(eq(ANA))).thenReturn(true); mMediator.onPasswordCheckStatusChanged(IDLE); mMediator.onCompromisedCredentialsFetchCompleted(); @@ -172,12 +170,29 @@ assertThat(mModel.get(ITEMS).get(1).type, is(ItemType.COMPROMISED_CREDENTIAL)); assertThat(mModel.get(ITEMS).get(1).model.get(COMPROMISED_CREDENTIAL), equalTo(ANA)); assertThat(mModel.get(ITEMS).get(1).model.get(CREDENTIAL_HANDLER), is(mMediator)); + assertThat(mModel.get(ITEMS).get(1).model.get(HAS_MANUAL_CHANGE_BUTTON), is(true)); + } + + @Test + public void testHidesChangeButtonIfManualChangeIsNotPossible() { + when(mPasswordCheck.getCompromisedCredentials()) + .thenReturn(new CompromisedCredential[] {BOB}); + when(mChangePasswordDelegate.canManuallyChangeCredential(eq(BOB))).thenReturn(false); + + mMediator.onPasswordCheckStatusChanged(IDLE); + mMediator.onCompromisedCredentialsFetchCompleted(); + + assertThat(mModel.get(ITEMS).get(1).type, is(ItemType.COMPROMISED_CREDENTIAL_WITH_SCRIPT)); + assertThat(mModel.get(ITEMS).get(1).model.get(COMPROMISED_CREDENTIAL), equalTo(BOB)); + assertThat(mModel.get(ITEMS).get(1).model.get(CREDENTIAL_HANDLER), is(mMediator)); + assertThat(mModel.get(ITEMS).get(1).model.get(HAS_MANUAL_CHANGE_BUTTON), is(false)); } @Test public void testAppendsEntryForNewlyFoundCredentials() { when(mPasswordCheck.getCompromisedCredentials()) .thenReturn(new CompromisedCredential[] {ANA}); + when(mChangePasswordDelegate.canManuallyChangeCredential(eq(BOB))).thenReturn(true); mMediator.onPasswordCheckStatusChanged(IDLE); mMediator.onCompromisedCredentialsFetchCompleted(); assertThat(mModel.get(ITEMS).size(), is(2)); // Header + existing credentials. @@ -187,6 +202,7 @@ assertThat(mModel.get(ITEMS).get(2).type, is(ItemType.COMPROMISED_CREDENTIAL_WITH_SCRIPT)); assertThat(mModel.get(ITEMS).get(2).model.get(COMPROMISED_CREDENTIAL), equalTo(BOB)); assertThat(mModel.get(ITEMS).get(2).model.get(CREDENTIAL_HANDLER), is(mMediator)); + assertThat(mModel.get(ITEMS).get(2).model.get(HAS_MANUAL_CHANGE_BUTTON), is(true)); } @Test @@ -225,13 +241,13 @@ @Test public void testOnChangePasswordButtonClick() { mMediator.onChangePasswordButtonClick(ANA); - verify(mLaunchCctWithChangePasswordUrlConsumer).accept(eq(ANA.getSignonRealm())); + verify(mChangePasswordDelegate).launchAppOrCctWithChangePasswordUrl(eq(ANA)); } @Test public void testOnChangePasswordWithScriptButtonClick() { mMediator.onChangePasswordWithScriptButtonClick(BOB); - verify(mLaunchCctWithScriptConsumer).accept(eq(BOB)); + verify(mChangePasswordDelegate).launchCctWithScript(eq(BOB)); } private void assertIdleHeader(MVCListAdapter.ListItem header) {
diff --git a/chrome/browser/password_check/android/password_check_bridge.cc b/chrome/browser/password_check/android/password_check_bridge.cc index 4bcbd54..5acd906 100644 --- a/chrome/browser/password_check/android/password_check_bridge.cc +++ b/chrome/browser/password_check/android/password_check_bridge.cc
@@ -76,6 +76,9 @@ base::android::ConvertUTF16ToJavaString(env, credential.display_username), base::android::ConvertUTF16ToJavaString(env, credential.password), + base::android::ConvertUTF8ToJavaString(env, + credential.change_password_url), + base::android::ConvertUTF8ToJavaString(env, credential.package_name), (credential.compromise_type == password_manager::CompromiseTypeFlags::kCredentialPhished), credential.has_script);
diff --git a/chrome/browser/password_check/android/password_check_manager.cc b/chrome/browser/password_check/android/password_check_manager.cc index 29e1e01..2e480a4 100644 --- a/chrome/browser/password_check/android/password_check_manager.cc +++ b/chrome/browser/password_check/android/password_check_manager.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/password_check/android/password_check_manager.h" +#include "base/feature_list.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/password_check/android/password_check_bridge.h" #include "chrome/browser/sync/profile_sync_service_factory.h" @@ -13,6 +14,7 @@ #include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/browser/ui/compromised_credentials_manager.h" +#include "components/password_manager/core/common/password_manager_features.h" #include "components/strings/grit/components_strings.h" #include "components/sync/driver/profile_sync_service.h" #include "components/url_formatter/url_formatter.h" @@ -20,12 +22,22 @@ namespace { +constexpr char kWellKnownUrlPath[] = ".well-known/change-password"; + base::string16 GetDisplayUsername(const base::string16& username) { return username.empty() ? l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_EMPTY_LOGIN) : username; } +std::string CreateChangeUrl(const GURL& url) { + if (base::FeatureList::IsEnabled( + password_manager::features::kWellKnownChangePassword)) { + return url.GetOrigin().spec() + kWellKnownUrlPath; + } + return url.GetOrigin().spec(); +} + } // namespace using autofill::PasswordForm; @@ -183,7 +195,7 @@ url_formatter::kFormatUrlOmitTrivialSubdomains | url_formatter::kFormatUrlTrimAfterHost, net::UnescapeRule::SPACES, nullptr, nullptr, nullptr); - ui_credential.change_password_url = ui_credential.url.GetOrigin().spec(); + ui_credential.change_password_url = CreateChangeUrl(ui_credential.url); } return ui_credential;
diff --git a/chrome/browser/performance_manager/observers/isolation_context_metrics_unittest.cc b/chrome/browser/performance_manager/observers/isolation_context_metrics_unittest.cc index 9388c31..e031013 100644 --- a/chrome/browser/performance_manager/observers/isolation_context_metrics_unittest.cc +++ b/chrome/browser/performance_manager/observers/isolation_context_metrics_unittest.cc
@@ -81,8 +81,8 @@ FrameNodeImpl* parent_frame_node = nullptr) { return CreateNode<FrameNodeImpl>( process_node, page_node, parent_frame_node, 0 /* frame_tree_node_id */, - ++next_render_frame_id_, FrameToken(base::UnguessableToken::Create()), - browsing_instance_id, site_instance_id); + ++next_render_frame_id_, blink::LocalFrameToken(), browsing_instance_id, + site_instance_id); } // Advance time until the timer fires.
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 1112812..f47006e 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -1671,12 +1671,17 @@ handlers->AddHandler( std::make_unique<LoginScreenPowerManagementPolicyHandler>(chrome_schema)); // Handler for another policy with JSON strings, lenient but shows warnings. - handlers->AddHandler( + handlers->AddHandler(std::make_unique<policy::SimpleDeprecatingPolicyHandler>( std::make_unique<SimpleJsonStringSchemaValidatingPolicyHandler>( - key::kNativePrinters, prefs::kRecommendedNativePrinters, + key::kNativePrinters, prefs::kRecommendedPrinters, chrome_schema.GetValidationSchema(), SimpleSchemaValidatingPolicyHandler::RECOMMENDED_ALLOWED, - SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED)); + SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED), + std::make_unique<SimpleJsonStringSchemaValidatingPolicyHandler>( + key::kPrinters, prefs::kRecommendedPrinters, + chrome_schema.GetValidationSchema(), + SimpleSchemaValidatingPolicyHandler::RECOMMENDED_ALLOWED, + SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED))); handlers->AddHandler(std::make_unique<SimpleDeprecatingPolicyHandler>( std::make_unique<SimplePolicyHandler>(key::kUserNativePrintersAllowed, prefs::kUserPrintersAllowed, @@ -1714,7 +1719,7 @@ handlers->AddHandler( std::make_unique<ExternalDataPolicyHandler>(key::kWallpaperImage)); handlers->AddHandler(std::make_unique<ExternalDataPolicyHandler>( - key::kNativePrintersBulkConfiguration)); + key::kPrintersBulkConfiguration)); handlers->AddHandler( std::make_unique<ExternalDataPolicyHandler>(key::kExternalPrintServers)); handlers->AddHandler(std::make_unique<ExternalDataPolicyHandler>(
diff --git a/chrome/browser/policy/extension_policy_browsertest.cc b/chrome/browser/policy/extension_policy_browsertest.cc index cb924f7..91530b9a 100644 --- a/chrome/browser/policy/extension_policy_browsertest.cc +++ b/chrome/browser/policy/extension_policy_browsertest.cc
@@ -1622,6 +1622,27 @@ EXPECT_TRUE(registry->enabled_extensions().GetByID(kGoodCrxId)); } +// Verifies that the browser doesn't crash on shutdown. If the extensions are +// being installed, and the browser is shutdown, it should not lead to a crash +// as in (crbug/1114191). +IN_PROC_BROWSER_TEST_F(ExtensionPolicyTest, + ExtensionInstallForcelistShutdownBeforeInstall) { + ExtensionRequestInterceptor interceptor; + + extensions::ExtensionRegistry* registry = extension_registry(); + ASSERT_FALSE(registry->GetExtensionById( + kGoodCrxId, extensions::ExtensionRegistry::EVERYTHING)); + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url = + embedded_test_server()->GetURL("/extensions/good_v1_update_manifest.xml"); + + PolicyMap policies; + AddExtensionToForceList(&policies, kGoodCrxId, url); + UpdateProviderPolicy(policies); + // The extension is not yet installed, shutdown the browser now and there + // should be no crash. +} + IN_PROC_BROWSER_TEST_F(ExtensionPolicyTest, ExtensionRecommendedInstallationMode) { // Verifies that extensions that are recommended-installed by policies are
diff --git a/chrome/browser/policy/profile_policy_connector.cc b/chrome/browser/policy/profile_policy_connector.cc index a3e0903..bca0c3ae 100644 --- a/chrome/browser/policy/profile_policy_connector.cc +++ b/chrome/browser/policy/profile_policy_connector.cc
@@ -229,6 +229,9 @@ policy::key::kNoteTakingAppsLockScreenAllowlist)); migrators.push_back(std::make_unique<LegacyChromePolicyMigrator>( policy::key::kDeviceUserWhitelist, policy::key::kDeviceUserAllowlist)); + migrators.push_back(std::make_unique<LegacyChromePolicyMigrator>( + policy::key::kNativePrintersBulkConfiguration, + policy::key::kPrintersBulkConfiguration)); ConfigurationPolicyProvider* user_policy_delegate_candidate = configuration_policy_provider ? configuration_policy_provider
diff --git a/chrome/browser/predictors/loading_predictor_browsertest.cc b/chrome/browser/predictors/loading_predictor_browsertest.cc index 203ddb74..113f7da 100644 --- a/chrome/browser/predictors/loading_predictor_browsertest.cc +++ b/chrome/browser/predictors/loading_predictor_browsertest.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/predictors/preconnect_manager.h" #include "chrome/browser/predictors/predictors_enums.h" #include "chrome/browser/predictors/predictors_features.h" +#include "chrome/browser/predictors/predictors_switches.h" #include "chrome/browser/prerender/prerender_manager_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -281,8 +282,8 @@ class TestPreconnectManagerObserver : public PreconnectManager::Observer { public: explicit TestPreconnectManagerObserver( - PreconnectManager* preconnect_manager_) { - preconnect_manager_->SetObserverForTesting(this); + PreconnectManager* preconnect_manager) { + preconnect_manager->SetObserverForTesting(this); } void OnPreconnectUrl(const GURL& url, @@ -452,6 +453,56 @@ std::set<GURL> preconnect_url_attempts_; }; +struct PrefetchResult { + PrefetchResult(const GURL& prefetch_url, + const network::URLLoaderCompletionStatus& status) + : prefetch_url(prefetch_url), status(status) {} + + GURL prefetch_url; + network::URLLoaderCompletionStatus status; +}; + +class TestPrefetchManagerObserver : public PrefetchManager::Observer { + public: + explicit TestPrefetchManagerObserver(PrefetchManager& manager) { + manager.set_observer_for_testing(this); + } + + void OnPrefetchFinished( + const GURL& url, + const GURL& prefetch_url, + const network::URLLoaderCompletionStatus& status) override { + prefetches_.emplace_back(prefetch_url, status); + } + + void OnAllPrefetchesFinished(const GURL& url) override { + done_urls_.insert(url); + if (waiting_url_ == url) { + waiting_url_ = GURL(); + std::move(done_callback_).Run(); + } + } + + void WaitForPrefetchesForNavigation(const GURL& url) { + DCHECK(waiting_url_.is_empty()); + DCHECK(!url.is_empty()); + if (done_urls_.find(url) != done_urls_.end()) + return; + waiting_url_ = url; + base::RunLoop loop; + done_callback_ = loop.QuitClosure(); + loop.Run(); + } + + const std::vector<PrefetchResult>& results() const { return prefetches_; } + + private: + std::vector<PrefetchResult> prefetches_; + std::set<GURL> done_urls_; + GURL waiting_url_; + base::OnceClosure done_callback_; +}; + class LoadingPredictorBrowserTest : public InProcessBrowserTest { public: LoadingPredictorBrowserTest() { @@ -504,6 +555,11 @@ preconnect_manager_observer_ = std::make_unique<TestPreconnectManagerObserver>( loading_predictor_->preconnect_manager()); + if (loading_predictor_->prefetch_manager()) { + prefetch_manager_observer_ = + std::make_unique<TestPrefetchManagerObserver>( + *loading_predictor_->prefetch_manager()); + } PredictorInitializer initializer( loading_predictor_->resource_prefetch_predictor()); initializer.EnsurePredictorInitialized(); @@ -563,6 +619,10 @@ return preconnect_manager_observer_.get(); } + TestPrefetchManagerObserver* prefetch_manager_observer() { + return prefetch_manager_observer_.get(); + } + ConnectionTracker* connection_tracker() { return connection_tracker_.get(); } ConnectionTracker* preconnecting_server_connection_tracker() const { @@ -620,6 +680,7 @@ std::unique_ptr<ConnectionListener> preconnecting_server_connection_listener_; std::unique_ptr<ConnectionTracker> preconnecting_server_connection_tracker_; std::unique_ptr<TestPreconnectManagerObserver> preconnect_manager_observer_; + std::unique_ptr<TestPrefetchManagerObserver> prefetch_manager_observer_; base::test::ScopedFeatureList scoped_feature_list_; DISALLOW_COPY_AND_ASSIGN(LoadingPredictorBrowserTest); @@ -1948,6 +2009,11 @@ LoadingPredictorBrowserTestWithOptimizationGuide::SetUp(); } + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch( + switches::kLoadingPredictorAllowLocalRequestForTesting); + } + protected: // Sets the requests to expect in WaitForRequests(). void SetExpectedRequests(base::flat_set<GURL> requests) { @@ -2117,6 +2183,47 @@ } } +// A fixture for testing prefetching with the local resource check not bypassed. +// The normal fixture bypasses the check so that the embedded test server can be +// used. +class LoadingPredictorPrefetchBrowserTestWithBlockedLocalRequest + : public LoadingPredictorPrefetchBrowserTest { + public: + LoadingPredictorPrefetchBrowserTestWithBlockedLocalRequest() = default; + + // Override to prevent adding kLoadingPredictorAllowLocalRequestForTesting + // here. + void SetUpCommandLine(base::CommandLine* command_line) override {} +}; + +// Test that prefetches to local resources are blocked. +IN_PROC_BROWSER_TEST_P( + LoadingPredictorPrefetchBrowserTestWithBlockedLocalRequest, + PrepareForPageLoadWithPredictionForPrefetch) { + GURL url = embedded_test_server()->GetURL( + "test.com", GetPathWithPortReplacement(kHtmlSubresourcesPath, + embedded_test_server()->port())); + + GURL hint_url = embedded_test_server()->GetURL("subresource.com", "/css"); + + // Set up one optimization hint. + std::vector<Subresource> hints = { + {hint_url.spec(), optimization_guide::proto::RESOURCE_TYPE_CSS}, + }; + SetUpOptimizationHint(url, hints); + + // Start a navigation which triggers prefetch. + auto observer = NavigateToURLAsync(url); + EXPECT_TRUE(observer->WaitForRequestStart()); + + // The prefetch should have failed. + prefetch_manager_observer()->WaitForPrefetchesForNavigation(url); + auto results = prefetch_manager_observer()->results(); + ASSERT_EQ(results.size(), 1u); + EXPECT_EQ(results[0].status.error_code, + net::ERR_INSECURE_PRIVATE_NETWORK_REQUEST); +} + INSTANTIATE_TEST_SUITE_P( , LoadingPredictorPrefetchBrowserTest, @@ -2126,4 +2233,16 @@ testing::Values(true), /*GetSubresourceType()=*/testing::Values("all", "css", "js_css"))); +// For the "BlockedLocalRequest" test, the params largely don't matter. We just +// need to enable prefetching and test one configuration, since the test passes +// if the prefetch is blocked. +INSTANTIATE_TEST_SUITE_P( + , + LoadingPredictorPrefetchBrowserTestWithBlockedLocalRequest, + testing::Combine( + /*IsLocalPredictionEnabled()=*/testing::Values(false), + /*ShouldUseOptimizationGuidePredictions()=*/ + testing::Values(true), + /*GetSubresourceType()=*/testing::Values("all"))); + } // namespace predictors
diff --git a/chrome/browser/predictors/predictors_switches.cc b/chrome/browser/predictors/predictors_switches.cc new file mode 100644 index 0000000..058ad43 --- /dev/null +++ b/chrome/browser/predictors/predictors_switches.cc
@@ -0,0 +1,14 @@ +// 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/predictors/predictors_switches.h" + +namespace switches { + +// Allows the loading predictor to do prefetches to local IP addresses. This is +// needed for testing as such requests are blocked by default for security. +const char kLoadingPredictorAllowLocalRequestForTesting[] = + "loading-predictor-allow-local-request-for-testing"; + +} // namespace switches
diff --git a/chrome/browser/predictors/predictors_switches.h b/chrome/browser/predictors/predictors_switches.h new file mode 100644 index 0000000..555f253 --- /dev/null +++ b/chrome/browser/predictors/predictors_switches.h
@@ -0,0 +1,14 @@ +// 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_PREDICTORS_PREDICTORS_SWITCHES_H_ +#define CHROME_BROWSER_PREDICTORS_PREDICTORS_SWITCHES_H_ + +namespace switches { + +extern const char kLoadingPredictorAllowLocalRequestForTesting[]; + +} // namespace switches + +#endif // CHROME_BROWSER_PREDICTORS_PREDICTORS_SWITCHES_H_
diff --git a/chrome/browser/predictors/prefetch_manager.cc b/chrome/browser/predictors/prefetch_manager.cc index 41f35419..5e2d639 100644 --- a/chrome/browser/predictors/prefetch_manager.cc +++ b/chrome/browser/predictors/prefetch_manager.cc
@@ -7,7 +7,9 @@ #include <utility> #include "base/bind.h" +#include "base/command_line.h" #include "chrome/browser/predictors/predictors_features.h" +#include "chrome/browser/predictors/predictors_switches.h" #include "chrome/browser/predictors/resource_prefetch_predictor.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/browser_thread.h" @@ -249,13 +251,20 @@ ++inflight_jobs_count_; + // Since the CORS-RFC1918 check is skipped when the client security state is + // unknown, just block any local request to be safe for now. + int options = base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kLoadingPredictorAllowLocalRequestForTesting) + ? network::mojom::kURLLoadOptionNone + : network::mojom::kURLLoadOptionBlockLocalRequest; + std::unique_ptr<blink::ThrottlingURLLoader> loader = blink::ThrottlingURLLoader::CreateLoaderAndStart( std::move(factory), std::move(throttles), /*routing_id is not needed*/ -1, - content::GlobalRequestID::MakeBrowserInitiated().request_id, - network::mojom::kURLLoadOptionNone, &request, client.get(), - kPrefetchTrafficAnnotation, base::ThreadTaskRunnerHandle::Get(), + content::GlobalRequestID::MakeBrowserInitiated().request_id, options, + &request, client.get(), kPrefetchTrafficAnnotation, + base::ThreadTaskRunnerHandle::Get(), /*cors_exempt_header_list=*/base::nullopt); delegate_->PrefetchInitiated(info.url, job->url); @@ -269,14 +278,19 @@ std::move(loader), std::move(client))); } -// The params are just bound to this function to keep them alive -// until the load finishes. +// Some params are unused but bound to this function to keep them alive until +// the load finishes. void PrefetchManager::OnPrefetchFinished( std::unique_ptr<PrefetchJob> job, std::unique_ptr<blink::ThrottlingURLLoader> loader, - std::unique_ptr<network::mojom::URLLoaderClient> client) { + std::unique_ptr<network::mojom::URLLoaderClient> client, + const network::URLLoaderCompletionStatus& status) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + PrefetchInfo& info = *job->info; + if (observer_for_testing_) + observer_for_testing_->OnPrefetchFinished(info.url, job->url, status); + loader.reset(); client.reset(); job.reset(); @@ -322,6 +336,8 @@ if (delegate_) delegate_->PrefetchFinished(std::move(info.stats)); + if (observer_for_testing_) + observer_for_testing_->OnAllPrefetchesFinished(info.url); prefetch_info_.erase(it); }
diff --git a/chrome/browser/predictors/prefetch_manager.h b/chrome/browser/predictors/prefetch_manager.h index 4ad86bd8..9c6c60b9 100644 --- a/chrome/browser/predictors/prefetch_manager.h +++ b/chrome/browser/predictors/prefetch_manager.h
@@ -74,6 +74,18 @@ virtual void PrefetchFinished(std::unique_ptr<PrefetchStats> stats) = 0; }; + // For testing. + class Observer { + public: + virtual ~Observer() = default; + + virtual void OnPrefetchFinished( + const GURL& url, + const GURL& prefetch_url, + const network::URLLoaderCompletionStatus& status) {} + virtual void OnAllPrefetchesFinished(const GURL& url) {} + }; + PrefetchManager(base::WeakPtr<Delegate> delegate, Profile* profile); ~PrefetchManager(); @@ -94,6 +106,10 @@ // Called by PrefetchInfo. void AllPrefetchJobsForUrlFinished(PrefetchInfo& info); + void set_observer_for_testing(Observer* observer) { + observer_for_testing_ = observer; + } + private: friend class PrefetchManagerTest; @@ -102,7 +118,8 @@ void OnPrefetchFinished( std::unique_ptr<PrefetchJob> job, std::unique_ptr<blink::ThrottlingURLLoader> loader, - std::unique_ptr<network::mojom::URLLoaderClient> client); + std::unique_ptr<network::mojom::URLLoaderClient> client, + const network::URLLoaderCompletionStatus& status); void TryToLaunchPrefetchJobs(); base::WeakPtr<Delegate> delegate_; @@ -118,6 +135,8 @@ // across all main frame URLs. size_t inflight_jobs_count_ = 0; + Observer* observer_for_testing_ = nullptr; + base::WeakPtrFactory<PrefetchManager> weak_factory_{this}; };
diff --git a/chrome/browser/predictors/prefetch_manager_unittest.cc b/chrome/browser/predictors/prefetch_manager_unittest.cc index 2732ee2..27ed80d 100644 --- a/chrome/browser/predictors/prefetch_manager_unittest.cc +++ b/chrome/browser/predictors/prefetch_manager_unittest.cc
@@ -17,6 +17,7 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/predictors/loading_test_util.h" #include "chrome/browser/predictors/predictors_features.h" +#include "chrome/browser/predictors/predictors_switches.h" #include "chrome/test/base/testing_profile.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/navigation_ui_data.h" @@ -128,6 +129,8 @@ std::make_unique<PrefetchManager>(fake_delegate_->AsWeakPtr(), profile_.get())) { features_.InitAndEnableFeature(features::kLoadingPredictorPrefetch); + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kLoadingPredictorAllowLocalRequestForTesting); } // Tests prefetching a single URL.
diff --git a/chrome/browser/prerender/isolated/isolated_prerender_tab_helper_unittest.cc b/chrome/browser/prerender/isolated/isolated_prerender_tab_helper_unittest.cc index 62d71e4..38b89a2 100644 --- a/chrome/browser/prerender/isolated/isolated_prerender_tab_helper_unittest.cc +++ b/chrome/browser/prerender/isolated/isolated_prerender_tab_helper_unittest.cc
@@ -1592,9 +1592,6 @@ GURL doc_url("https://www.google.com/search?q=cats"); GURL prediction_url("https://www.cat-food.com/"); - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); - MakeNavigationPrediction(web_contents(), doc_url, {prediction_url}); VerifyCommonRequestState(prediction_url); @@ -1604,13 +1601,9 @@ } }; -// Fails on TSAN builders: https://crbug.com/1078965. -#if defined(THREAD_SANITIZER) -#define MAYBE_NoRedirect_Cookies DISABLED_NoRedirect_Cookies -#else -#define MAYBE_NoRedirect_Cookies NoRedirect_Cookies -#endif -TEST_F(IsolatedPrerenderTabHelperRedirectTest, MAYBE_NoRedirect_Cookies) { +TEST_F(IsolatedPrerenderTabHelperRedirectTest, NoRedirect_Cookies) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); NavigateSomewhere(); GURL site_with_cookies("https://cookies.com"); @@ -1632,6 +1625,8 @@ } TEST_F(IsolatedPrerenderTabHelperRedirectTest, NoRedirect_Insecure) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); NavigateSomewhere(); GURL url("http://insecure.com"); @@ -1653,6 +1648,8 @@ } TEST_F(IsolatedPrerenderTabHelperRedirectTest, NoRedirect_Insecure_Continued) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); NavigateSomewhere(); GURL url("http://insecure.com"); @@ -1690,6 +1687,8 @@ } TEST_F(IsolatedPrerenderTabHelperRedirectTest, NoRedirect_Google) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); NavigateSomewhere(); GURL url("https://www.google.com"); @@ -1711,6 +1710,8 @@ } TEST_F(IsolatedPrerenderTabHelperRedirectTest, NoRedirect_ServiceWorker) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders); NavigateSomewhere(); GURL site_with_worker("https://service-worker.com"); @@ -1735,18 +1736,18 @@ } TEST_F(IsolatedPrerenderTabHelperRedirectTest, SuccessfulRedirect) { - base::HistogramTester histogram_tester; - NavigateSomewhere(); - GURL doc_url("https://www.google.com/search?q=cats"); - GURL prediction_url("https://www.cat-food.com/"); - GURL redirect_url("https://redirect-here.com"); - // Enable unlimited prefetches so we can follow the redirect chain all the // way. base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeatureWithParameters( features::kIsolatePrerenders, {{"max_srp_prefetches", "-1"}}); + base::HistogramTester histogram_tester; + NavigateSomewhere(); + GURL doc_url("https://www.google.com/search?q=cats"); + GURL prediction_url("https://www.cat-food.com/"); + GURL redirect_url("https://redirect-here.com"); + MakeNavigationPrediction(web_contents(), doc_url, {prediction_url}); VerifyCommonRequestState(prediction_url);
diff --git a/chrome/browser/prerender/prerender_tab_helper.cc b/chrome/browser/prerender/prerender_tab_helper.cc index c36373b..e5402cc 100644 --- a/chrome/browser/prerender/prerender_tab_helper.cc +++ b/chrome/browser/prerender/prerender_tab_helper.cc
@@ -4,14 +4,9 @@ #include "chrome/browser/prerender/prerender_tab_helper.h" -#include "base/bind.h" -#include "base/metrics/histogram_macros.h" -#include "base/time/time.h" #include "chrome/browser/prerender/prerender_manager_factory.h" -#include "chrome/browser/profiles/profile.h" #include "components/prerender/browser/prerender_manager.h" #include "content/public/browser/navigation_handle.h" -#include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" using content::WebContents; @@ -31,7 +26,9 @@ return; } - PrerenderManager* prerender_manager = MaybeGetPrerenderManager(); + PrerenderManager* prerender_manager = + PrerenderManagerFactory::GetForBrowserContext( + web_contents()->GetBrowserContext()); if (!prerender_manager) return; if (prerender_manager->IsWebContentsPrerendering(web_contents(), nullptr)) @@ -39,30 +36,6 @@ prerender_manager->RecordNavigation(navigation_handle->GetURL()); } -PrerenderManager* PrerenderTabHelper::MaybeGetPrerenderManager() const { - return PrerenderManagerFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()); -} - -base::TimeTicks PrerenderTabHelper::GetTimeTicksFromPrerenderManager() const { - // Prerender browser tests should always have a PrerenderManager when mocking - // out tick clock. - PrerenderManager* prerender_manager = MaybeGetPrerenderManager(); - if (prerender_manager) - return prerender_manager->GetCurrentTimeTicks(); - - // Fall back to returning the same value as PrerenderManager would have - // returned in production. - return base::TimeTicks::Now(); -} - -bool PrerenderTabHelper::IsPrerendering() { - PrerenderManager* prerender_manager = MaybeGetPrerenderManager(); - if (!prerender_manager) - return false; - return prerender_manager->IsWebContentsPrerendering(web_contents(), nullptr); -} - WEB_CONTENTS_USER_DATA_KEY_IMPL(PrerenderTabHelper) } // namespace prerender
diff --git a/chrome/browser/prerender/prerender_tab_helper.h b/chrome/browser/prerender/prerender_tab_helper.h index 483b687..622491c 100644 --- a/chrome/browser/prerender/prerender_tab_helper.h +++ b/chrome/browser/prerender/prerender_tab_helper.h
@@ -5,15 +5,9 @@ #ifndef CHROME_BROWSER_PRERENDER_PRERENDER_TAB_HELPER_H_ #define CHROME_BROWSER_PRERENDER_PRERENDER_TAB_HELPER_H_ -#include <memory> - #include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "components/prerender/common/prerender_origin.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" -#include "url/gurl.h" namespace prerender { @@ -26,34 +20,18 @@ public content::WebContentsUserData<PrerenderTabHelper> { public: ~PrerenderTabHelper() override; + PrerenderTabHelper(const PrerenderTabHelper&) = delete; + PrerenderTabHelper& operator=(const PrerenderTabHelper&) = delete; // content::WebContentsObserver implementation. void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; - base::TimeTicks swap_ticks() const { return swap_ticks_; } - private: explicit PrerenderTabHelper(content::WebContents* web_contents); friend class content::WebContentsUserData<PrerenderTabHelper>; - // Retrieves the PrerenderManager, or NULL, if none was found. - PrerenderManager* MaybeGetPrerenderManager() const; - - // Returns the current TimeTicks synchronized with PrerenderManager ticks. In - // tests the clock can be mocked out in PrerenderManager, but in production - // this should be always TimeTicks::Now(). - base::TimeTicks GetTimeTicksFromPrerenderManager() const; - - // Returns whether the WebContents being observed is currently prerendering. - bool IsPrerendering(); - - // Record the most recent swap time. - base::TimeTicks swap_ticks_; - WEB_CONTENTS_USER_DATA_KEY_DECL(); - - DISALLOW_COPY_AND_ASSIGN(PrerenderTabHelper); }; } // namespace prerender
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc index 37bdfd9..2917e93c 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -217,7 +217,7 @@ } // Post task so that the query has time to reset the callback before calling - // OnDidGetPrintedPagesCount(). + // DidGetPrintedPagesCount(). int cookie = printer_query->cookie(); queue_->QueuePrinterQuery(std::move(printer_query)); content::GetUIThreadTaskRunner({})->PostTask( @@ -233,7 +233,7 @@ PrinterHandler::PrintCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - OnDidGetPrintedPagesCount(cookie, page_count); + DidGetPrintedPagesCount(cookie, page_count); if (!PrintJobHasDocument(cookie)) { std::move(callback).Run(base::Value("Failed to print")); @@ -275,9 +275,9 @@ return name; } -void PrintViewManagerBase::OnDidGetPrintedPagesCount(int cookie, - int number_pages) { - PrintManager::OnDidGetPrintedPagesCount(cookie, number_pages); +void PrintViewManagerBase::DidGetPrintedPagesCount(int32_t cookie, + int32_t number_pages) { + PrintManager::DidGetPrintedPagesCount(cookie, number_pages); OpportunisticallyCreatePrintJob(cookie); } @@ -318,12 +318,12 @@ void PrintViewManagerBase::OnDidPrintDocument( content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPrintDocument_Params& params, + const mojom::DidPrintDocumentParams& params, std::unique_ptr<DelayedFrameDispatchHelper> helper) { if (!PrintJobHasDocument(params.document_cookie)) return; - const mojom::DidPrintContentParams& content = params.content; + const mojom::DidPrintContentParams& content = *params.content; if (!content.metafile_data_region.IsValid()) { NOTREACHED() << "invalid memory handle"; web_contents()->Stop();
diff --git a/chrome/browser/printing/print_view_manager_base.h b/chrome/browser/printing/print_view_manager_base.h index 94b65e8..9ad03ae 100644 --- a/chrome/browser/printing/print_view_manager_base.h +++ b/chrome/browser/printing/print_view_manager_base.h
@@ -17,6 +17,7 @@ #include "chrome/browser/ui/webui/print_preview/printer_handler.h" #include "components/prefs/pref_member.h" #include "components/printing/browser/print_manager.h" +#include "components/printing/common/print.mojom-forward.h" #include "components/services/print_compositor/public/mojom/print_compositor.mojom.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -70,6 +71,9 @@ return printing_rfh_; } + // mojom::PrintManagerHost: + void DidGetPrintedPagesCount(int32_t cookie, int32_t number_pages) override; + protected: explicit PrintViewManagerBase(content::WebContents* web_contents); @@ -113,10 +117,9 @@ void NavigationStopped() override; // printing::PrintManager: - void OnDidGetPrintedPagesCount(int cookie, int number_pages) override; void OnDidPrintDocument( content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPrintDocument_Params& params, + const mojom::DidPrintDocumentParams& params, std::unique_ptr<DelayedFrameDispatchHelper> helper) override; void OnGetDefaultPrintSettings(content::RenderFrameHost* render_frame_host, IPC::Message* reply_msg) override;
diff --git a/chrome/browser/printing/print_view_manager_basic_unittest.cc b/chrome/browser/printing/print_view_manager_basic_unittest.cc index d7f6728..77ef83d 100644 --- a/chrome/browser/printing/print_view_manager_basic_unittest.cc +++ b/chrome/browser/printing/print_view_manager_basic_unittest.cc
@@ -62,9 +62,8 @@ auto cookie = query->cookie(); queue->QueuePrinterQuery(std::move(query)); - // Fake GetPrintedPagesCount message to cause print_job to be created - content::RenderFrameHostTester::TestOnMessageReceived( - main_rfh(), PrintHostMsg_DidGetPrintedPagesCount(0, cookie, 1)); + // Fake DidGetPrintedPagesCount() call to cause print_job to be created + print_view_manager->DidGetPrintedPagesCount(cookie, 1); DeleteContents(); }
diff --git a/chrome/browser/printing/print_view_manager_unittest.cc b/chrome/browser/printing/print_view_manager_unittest.cc index 1040cf63..82c165d 100644 --- a/chrome/browser/printing/print_view_manager_unittest.cc +++ b/chrome/browser/printing/print_view_manager_unittest.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "components/printing/common/print.mojom.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/test_renderer_host.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" @@ -141,6 +142,9 @@ browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_TRUE(web_contents); + content::RemoveWebContentsReceiverSet(web_contents, + mojom::PrintManagerHost::Name_); + std::unique_ptr<TestPrintViewManager> print_view_manager = std::make_unique<TestPrintViewManager>(web_contents);
diff --git a/chrome/browser/promo_browser_command/promo_browser_command.mojom b/chrome/browser/promo_browser_command/promo_browser_command.mojom index 90e01f97..63ebe496 100644 --- a/chrome/browser/promo_browser_command/promo_browser_command.mojom +++ b/chrome/browser/promo_browser_command/promo_browser_command.mojom
@@ -15,6 +15,7 @@ // Please update enums.xml upon addition of new commands. enum Command { kUnknownCommand = 0, + kOpenSafetyCheck = 1, }; // Click information needed to determine user's desired window disposition using
diff --git a/chrome/browser/referrer_policy_browsertest.cc b/chrome/browser/referrer_policy_browsertest.cc index a1f0111..4bcd8e0 100644 --- a/chrome/browser/referrer_policy_browsertest.cc +++ b/chrome/browser/referrer_policy_browsertest.cc
@@ -38,6 +38,7 @@ #include "net/base/features.h" #include "net/test/embedded_test_server/http_request.h" #include "services/network/public/mojom/referrer_policy.mojom-shared.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/input/web_mouse_event.h" #include "ui/base/page_transition_types.h" @@ -788,7 +789,7 @@ ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER, }, { - .feature_to_enable = features::kReducedReferrerGranularity, + .feature_to_enable = blink::features::kReducedReferrerGranularity, .force_no_referrer_when_downgrade_default = false, .baseline_policy = network::mojom::ReferrerPolicy::kDefault, // kDefault gets resolved into a concrete policy when making requests @@ -806,7 +807,7 @@ ReferrerPolicyTest::EXPECT_ORIGIN_AS_REFERRER, }, { - .feature_to_enable = features::kReducedReferrerGranularity, + .feature_to_enable = blink::features::kReducedReferrerGranularity, .force_no_referrer_when_downgrade_default = true, .baseline_policy = network::mojom::ReferrerPolicy::kDefault, // kDefault gets resolved into a concrete policy when making requests
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index dcb85308..50d7586 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -86,6 +86,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/context_menu_data/media_type.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -796,7 +797,7 @@ // Set up referrer URL with fragment. const GURL kReferrerWithFragment("http://foo.com/test#fragment"); const std::string kCorrectReferrer( - base::FeatureList::IsEnabled(features::kReducedReferrerGranularity) + base::FeatureList::IsEnabled(blink::features::kReducedReferrerGranularity) ? "http://foo.com/" : "http://foo.com/test");
diff --git a/chrome/browser/reputation/safety_tip_ui_helper.cc b/chrome/browser/reputation/safety_tip_ui_helper.cc index c2f6e0d..48f684e 100644 --- a/chrome/browser/reputation/safety_tip_ui_helper.cc +++ b/chrome/browser/reputation/safety_tip_ui_helper.cc
@@ -92,17 +92,10 @@ return l10n_util::GetStringUTF16( IDS_PAGE_INFO_SAFETY_TIP_BAD_REPUTATION_TITLE); case security_state::SafetyTipStatus::kLookalike: -#if defined(OS_ANDROID) - return l10n_util::GetStringFUTF16( - IDS_SAFETY_TIP_ANDROID_LOOKALIKE_TITLE, - security_interstitials::common_string_util::GetFormattedHostName( - suggested_url)); -#else return l10n_util::GetStringFUTF16( IDS_PAGE_INFO_SAFETY_TIP_LOOKALIKE_TITLE, security_interstitials::common_string_util::GetFormattedHostName( suggested_url)); -#endif case security_state::SafetyTipStatus::kBadReputationIgnored: case security_state::SafetyTipStatus::kLookalikeIgnored: case security_state::SafetyTipStatus::kBadKeyword: @@ -123,17 +116,10 @@ return l10n_util::GetStringUTF16( IDS_PAGE_INFO_SAFETY_TIP_BAD_REPUTATION_DESCRIPTION); case security_state::SafetyTipStatus::kLookalike: -#if defined(OS_ANDROID) - return l10n_util::GetStringFUTF16( - IDS_SAFETY_TIP_ANDROID_LOOKALIKE_DESCRIPTION, - security_interstitials::common_string_util::GetFormattedHostName( - suggested_url)); -#else return l10n_util::GetStringFUTF16( IDS_PAGE_INFO_SAFETY_TIP_LOOKALIKE_DESCRIPTION, security_interstitials::common_string_util::GetFormattedHostName( suggested_url)); -#endif case security_state::SafetyTipStatus::kBadReputationIgnored: case security_state::SafetyTipStatus::kLookalikeIgnored: case security_state::SafetyTipStatus::kBadKeyword: @@ -147,17 +133,10 @@ int GetSafetyTipLeaveButtonId(security_state::SafetyTipStatus warning_type) { switch (warning_type) { -#if defined(OS_ANDROID) - case security_state::SafetyTipStatus::kBadReputation: - return IDS_SAFETY_TIP_ANDROID_BAD_REPUTATION_LEAVE_BUTTON; - case security_state::SafetyTipStatus::kLookalike: - return IDS_SAFETY_TIP_ANDROID_LOOKALIKE_LEAVE_BUTTON; -#else case security_state::SafetyTipStatus::kBadReputation: return IDS_PAGE_INFO_SAFETY_TIP_BAD_REPUTATION_LEAVE_BUTTON; case security_state::SafetyTipStatus::kLookalike: return IDS_PAGE_INFO_SAFETY_TIP_LOOKALIKE_LEAVE_BUTTON; -#endif case security_state::SafetyTipStatus::kBadReputationIgnored: case security_state::SafetyTipStatus::kLookalikeIgnored: case security_state::SafetyTipStatus::kBadKeyword:
diff --git a/chrome/browser/resources/chrome_urls_disabled_page/app.html b/chrome/browser/resources/chromeos/chrome_urls_disabled_page/app.html similarity index 100% rename from chrome/browser/resources/chrome_urls_disabled_page/app.html rename to chrome/browser/resources/chromeos/chrome_urls_disabled_page/app.html
diff --git a/chrome/browser/resources/nearby_internals/contact_object.html b/chrome/browser/resources/nearby_internals/contact_object.html index 42f50cea..2235ea6 100644 --- a/chrome/browser/resources/nearby_internals/contact_object.html +++ b/chrome/browser/resources/nearby_internals/contact_object.html
@@ -20,7 +20,7 @@ margin: 10px; padding: 10px; text-align: left; - white-space: pre-line; + white-space: pre-wrap; width: 100%; }
diff --git a/chrome/browser/resources/nearby_internals/http_message_object.html b/chrome/browser/resources/nearby_internals/http_message_object.html index d2879dc..d636534 100644 --- a/chrome/browser/resources/nearby_internals/http_message_object.html +++ b/chrome/browser/resources/nearby_internals/http_message_object.html
@@ -17,7 +17,7 @@ margin: 10px; padding: 5px; text-align: left; - white-space: pre-line; + white-space: pre-wrap; width: 100%; }
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 6fa2e86..df5a633 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -275,7 +275,7 @@ #"os_about_page:closure_compile_module", #"os_apps_page:closure_compile_module", #"os_apps_page/app_management_page/plugin_vm_page:closure_compile_module", - #"os_files_page:closure_compile_module", + "os_files_page:closure_compile_module", "os_languages_page:closure_compile_module", "os_people_page:closure_compile_module",
diff --git a/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.html b/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.html index 564b4f9..c4c424e 100644 --- a/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.html +++ b/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.html
@@ -18,6 +18,8 @@ } #rowContainer { + /* Set height to 100% of parent to always capture click events. */ + height: 100%; padding-inline-end: var(--cr-icon-ripple-padding); padding-inline-start: var(--cr-section-padding); }
diff --git a/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js b/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js index 5e9a4fb..194d874 100644 --- a/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js +++ b/chrome/browser/resources/settings/chromeos/ensure_lazy_loaded.m.js
@@ -16,6 +16,8 @@ 'os-settings-powerwash-dialog', 'os-settings-privacy-page', 'os-settings-reset-page', + 'os-settings-files-page', + 'settings-smb-shares-page', ].map(name => customElements.whenDefined(name))); } return lazyLoadPromise;
diff --git a/chrome/browser/resources/settings/chromeos/lazy_load.js b/chrome/browser/resources/settings/chromeos/lazy_load.js index 2540903..2c621179 100644 --- a/chrome/browser/resources/settings/chromeos/lazy_load.js +++ b/chrome/browser/resources/settings/chromeos/lazy_load.js
@@ -6,9 +6,11 @@ import './date_time_page/date_time_page.m.js'; import './date_time_page/timezone_selector.m.js'; // import './os_a11y_page/os_a11y_page.m.js'; -// import './os_files_page/os_files_page.m.js'; +import './os_files_page/os_files_page.m.js'; import './os_languages_page/input_method_options_page.m.js'; +import './os_languages_page/input_page.m.js'; import './os_languages_page/os_languages_page.m.js'; +import './os_languages_page/os_languages_page_v2.m.js'; import './os_languages_page/os_languages_section.m.js'; import './os_languages_page/smart_inputs_page.m.js'; // import './os_printing_page/os_printing_page.m.js'; @@ -16,9 +18,11 @@ import './os_reset_page/os_reset_page.m.js'; import './os_reset_page/os_powerwash_dialog.m.js'; import './os_reset_page/os_reset_page.m.js'; +import './os_files_page/smb_shares_page.m.js'; export {LanguagesBrowserProxy, LanguagesBrowserProxyImpl} from '../languages_page/languages_browser_proxy.m.js'; export {TimeZoneAutoDetectMethod} from './date_time_page/date_time_types.m.js'; export {TimeZoneBrowserProxyImpl} from './date_time_page/timezone_browser_proxy.m.js'; export {LanguagesMetricsProxy, LanguagesMetricsProxyImpl, LanguagesPageInteraction} from './os_languages_page/languages_metrics_proxy.m.js'; export {OsResetBrowserProxyImpl} from './os_reset_page/os_reset_browser_proxy.m.js'; +export {SmbMountResult, SmbBrowserProxyImpl} from 'chrome://resources/cr_components/chromeos/smb_shares/smb_browser_proxy.m.js'; \ No newline at end of file
diff --git a/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn index bec2d53..a4df43c 100644 --- a/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_files_page/BUILD.gn
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//third_party/closure_compiler/compile_js.gni") +import("../os_settings.gni") js_type_check("closure_compile") { deps = [ @@ -27,19 +28,19 @@ ] } -# TODO: Uncomment as the Polymer3 migration makes progress. -#js_type_check("closure_compile_module") { -# is_polymer3 = true -# deps = [ -# ":os_files_page.m", -# ":smb_shares_page.m" -# ] -#} +js_type_check("closure_compile_module") { + is_polymer3 = true + deps = [ + ":os_files_page.m", + ":smb_shares_page.m", + ] +} js_library("os_files_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.m.js" ] deps = [ - # TODO: Fill those in. + "..:os_route.m", + "../..:router.m", ] extra_deps = [ ":os_files_page_module" ] } @@ -47,7 +48,9 @@ js_library("smb_shares_page.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.m.js" ] deps = [ - # TODO: Fill those in. + "..:os_route.m", + "../..:router.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] extra_deps = [ ":smb_shares_page_module" ] } @@ -58,6 +61,7 @@ public_deps = [ ":os_files_page_module", ":smb_shares_page_module", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", ] } @@ -65,10 +69,14 @@ js_file = "os_files_page.js" html_file = "os_files_page.html" html_type = "dom-module" + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports } polymer_modulizer("smb_shares_page") { js_file = "smb_shares_page.js" html_file = "smb_shares_page.html" html_type = "dom-module" + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports }
diff --git a/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.html b/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.html index 5b97a99b..2f5c0c4b 100644 --- a/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.html +++ b/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.html
@@ -16,6 +16,7 @@ focus-config="[[focusConfig_]]"> <div route-path="default"> <settings-toggle-button + id="disconnectGoogleDriveAccount" class="hr" pref="{{prefs.gdata.disabled}}" label="$i18n{disconnectGoogleDriveAccount}">
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn index c31a1090e..887913c 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/BUILD.gn
@@ -10,10 +10,12 @@ deps = [ ":input_method_options_page", ":input_method_util", + ":input_page", ":languages_metrics_proxy", ":manage_input_methods_page", ":os_add_languages_dialog", ":os_languages_page", + ":os_languages_page_v2", ":os_languages_section", ":smart_inputs_page", "../../languages_page:languages", @@ -36,6 +38,10 @@ deps = [ "//ui/webui/resources/js:cr" ] } +js_library("input_page") { + deps = [ ":languages_metrics_proxy" ] +} + js_library("languages_metrics_proxy") { deps = [ "//ui/webui/resources/js:cr" ] externs_list = [ "$externs_path/metrics_private.js" ] @@ -88,6 +94,25 @@ ] } +js_library("os_languages_page_v2") { + deps = [ + ":languages_metrics_proxy", + "..:metrics_recorder", + "..:os_route", + "../..:router", + "../../languages_page:languages_types", + "../../settings_page:settings_animated_pages", + "../localized_link:localized_link", + "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", + "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button", + "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render", + "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:load_time_data", + "//ui/webui/resources/js/cr/ui:focus_without_ink", + ] +} + js_library("os_add_languages_dialog") { deps = [ "../../languages_page:languages", @@ -109,10 +134,12 @@ deps = [ ":input_method_options_page.m", ":input_method_util.m", + ":input_page.m", ":languages_metrics_proxy.m", ":manage_input_methods_page.m", ":os_add_languages_dialog.m", ":os_languages_page.m", + ":os_languages_page_v2.m", ":os_languages_section.m", ":smart_inputs_page.m", ] @@ -134,6 +161,12 @@ extra_deps = [ ":input_method_options_page_module" ] } +js_library("input_page.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.m.js" ] + deps = [ ":languages_metrics_proxy.m" ] + extra_deps = [ ":input_page_module" ] +} + js_library("languages_metrics_proxy.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/languages_metrics_proxy.m.js" ] deps = [ "//ui/webui/resources/js:cr.m" ] @@ -181,6 +214,27 @@ extra_deps = [ ":os_languages_page_module" ] } +js_library("os_languages_page_v2.m") { + sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.m.js" ] + deps = [ + ":input_method_util.m", + ":languages_metrics_proxy.m", + "..:metrics_recorder.m", + "..:os_route.m", + "../..:i18n_setup", + "../..:router.m", + "../localized_link:localized_link.m", + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu.m", + "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button.m", + "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render.m", + "//ui/webui/resources/js:assert.m", + "//ui/webui/resources/js:cr.m", + "//ui/webui/resources/js/cr/ui:focus_without_ink.m", + ] + extra_deps = [ ":os_languages_page_v2_module" ] +} + js_library("os_languages_section.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.m.js" ] deps = [ @@ -214,10 +268,12 @@ group("polymer3_elements") { public_deps = [ ":input_method_options_page_module", + ":input_page_module", ":manage_input_methods_page_module", ":modulize", ":os_add_languages_dialog_module", ":os_languages_page_module", + ":os_languages_page_v2_module", ":os_languages_section_module", ":smart_inputs_page_module", "../../languages_page:languages_module", @@ -252,6 +308,15 @@ auto_imports = os_settings_auto_imports } +polymer_modulizer("os_languages_page_v2") { + js_file = "os_languages_page_v2.js" + html_file = "os_languages_page_v2.html" + html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports +} + polymer_modulizer("os_languages_section") { js_file = "os_languages_section.js" html_file = "os_languages_section.html" @@ -270,6 +335,15 @@ auto_imports = os_settings_auto_imports } +polymer_modulizer("input_page") { + js_file = "input_page.js" + html_file = "input_page.html" + html_type = "dom-module" + migrated_imports = settings_migrated_imports + namespace_rewrites = os_settings_namespace_rewrites + auto_imports = os_settings_auto_imports +} + polymer_modulizer("smart_inputs_page") { js_file = "smart_inputs_page.js" html_file = "smart_inputs_page.html"
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html index 1d8b4b57..2d164cc 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.html
@@ -1,18 +1,26 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="languages_metrics_proxy.html"> +<link rel="import" href="../../controls/settings_toggle_button.html"> +<link rel="import" href="../../prefs/prefs_behavior.html"> +<link rel="import" href="../../settings_shared_css.html"> + <dom-module id="os-settings-input-page"> <template> - <style include="settings-shared action-link"> + <style include="settings-shared"> h2 { padding-inline-start: var(--cr-section-padding); } </style> <div route-path="default"> - - <h2>$i18n{inputPageTitle}</h2> - + <settings-toggle-button + class="first" id="showImeMenu" + pref="{{prefs.settings.language.ime_menu_activated}}" + label="$i18n{showImeMenu}" + on-settings-boolean-control-change="onShowImeMenuChange_"> + </settings-toggle-button> </div> - </template> + <script src="input_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js new file mode 100644 index 0000000..bdb397b --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.js
@@ -0,0 +1,43 @@ +// 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. + +/** + * @fileoverview 'os-settings-input-page' is the input sub-page + * for language and input method settings. + */ +Polymer({ + is: 'os-settings-input-page', + + behaviors: [ + PrefsBehavior, + ], + + properties: { + /** + * Preferences state. + */ + prefs: { + type: Object, + notify: true, + }, + }, + + /** @private {?settings.LanguagesMetricsProxy} */ + languagesMetricsProxy_: null, + + /** @override */ + created() { + this.languagesMetricsProxy_ = + settings.LanguagesMetricsProxyImpl.getInstance(); + }, + + /** + * @param {!Event} e + * @private + */ + onShowImeMenuChange_(e) { + this.languagesMetricsProxy_.recordToggleShowInputOptionsOnShelf( + e.target.checked); + }, +});
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.html b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.html index 774c407..fca6fdd 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.html +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.html
@@ -1,18 +1,139 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> +<link rel="import" href="chrome://resources/html/action_link.html"> +<link rel="import" href="chrome://resources/cr_elements/action_link_css.html"> +<link rel="import" href="chrome://resources/html/assert.html"> +<link rel="import" href="chrome://resources/html/cr.html"> +<link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.html"> +<link rel="import" href="languages_metrics_proxy.html"> +<link rel="import" href="os_add_languages_dialog.html"> +<link rel="import" href="../localized_link/localized_link.html"> +<link rel="import" href="../../controls/settings_toggle_button.html"> +<link rel="import" href="../../prefs/prefs_behavior.html"> +<link rel="import" href="../os_route.html"> +<link rel="import" href="../../i18n_setup.html"> +<link rel="import" href="../../router.html"> +<link rel="import" href="../../settings_shared_css.html"> +<link rel="import" href="../metrics_recorder.html"> + <dom-module id="os-settings-languages-page-v2"> <template> <style include="settings-shared action-link"> h2 { padding-inline-start: var(--cr-section-padding); } + + cr-action-menu.complex .dropdown-item { + min-height: 36px; + } + + .bottom-margin { + margin-bottom: var(--cr-section-vertical-margin); + } + + #addLanguagesIcon { + --iron-icon-fill-color: var(--cr-link-color); + margin-inline-end: 4px; + } </style> <div route-path="default"> + <h2 aria-hidden="true">$i18n{systemLanguageTitle}</h2> + <span class="settings-box first" aria-hidden="true"> + $i18n{systemLanguageDescription} + </span> + <div class="settings-box continuation embedded bottom-margin"> + <div class="start" aria-hidden="true"> + [[getLanguageDisplayName_(languages.prospectiveUILanguage)]] + </div> + <cr-button id="changeSystemLanguage" + on-click="onChangeSystemLanguageClick_" + aria-label="[[getChangeSystemLanguageButtonDescription_( + languages.prospectiveUILanguage)]]"> + $i18n{changeSystemLanguageLabel} + </cr-button> + </div> - <h2>$i18n{languagesPageTitle}</h2> + <div class="hr"> + <h2 aria-hidden="true">$i18n{languagesPreferenceTitle}</h2> + <settings-localized-link class="settings-box first" + localized-string="[[i18nAdvanced( + 'languagesPreferenceDescription')]]"> + </settings-localized-link> + <div class="list-frame vertical-list" id="languagesList"> + <template is="dom-repeat" items="[[languages.enabled]]"> + <div class="list-item"> + <div class="start" id="displayText-[[index]]" + aria-hidden="true"> + <div title="[[item.language.nativeDisplayName]]"> + [[item.language.displayName]] + </div> + </div> + <cr-icon-button class="icon-more-vert" + title="$i18n{moreActions}" id="more-[[item.language.code]]" + on-click="onDotsClick_" + aria-labelledby$="displayText-[[index]]"> + </cr-icon-button> + </div> + </template> + <div class="list-item"> + <cr-button id="addLanguages" + disabled="[[!canEnableSomeSupportedLanguage_(languages)]]" + on-click="onAddLanguagesClick_"> + <iron-icon id="addLanguagesIcon" icon="cr:add"></iron-icon> + $i18n{addLanguages} + </cr-button> + </div> + </div> + </div> + <settings-toggle-button id="offerTranslation" class="hr" + pref="{{prefs.translate.enabled}}" + label="$i18n{offerTranslationLabel}" + sub-label="$i18n{offerTranslationSublabel}" + on-settings-boolean-control-change="onTranslateToggleChange_"> + </settings-toggle-button> + + <cr-lazy-render id="menu"> + <template> + <cr-action-menu class="complex" + role-description="$i18n{menu}"> + <button class="dropdown-item" role="menuitem" + on-click="onMoveToTopClick_" + hidden="[[showMoveToTop_(detailLanguage_)]]"> + $i18n{moveToTop} + </button> + <button class="dropdown-item" role="menuitem" + on-click="onMoveUpClick_" + hidden="[[!showMoveUp_(detailLanguage_)]]"> + $i18n{moveUp} + </button> + <button class="dropdown-item" role="menuitem" + on-click="onMoveDownClick_" + hidden="[[!showMoveDown_(detailLanguage_)]]"> + $i18n{moveDown} + </button> + <button class="dropdown-item" role="menuitem" + on-click="onRemoveLanguageClick_"> + $i18n{removeLanguage} + </button> + </cr-action-menu> + </template> + </cr-lazy-render> </div> + <template is="dom-if" if="[[showAddLanguagesDialog_]]" restamp> + <os-settings-add-languages-dialog languages="{{languages}}" + language-helper="[[languageHelper]]" + on-close="onAddLanguagesDialogClose_"> + </os-settings-add-languages-dialog> + </template> </template> + <script src="os_languages_page_v2.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.js b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.js new file mode 100644 index 0000000..8ba9ab7 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.js
@@ -0,0 +1,217 @@ +// 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. + +/** + * @fileoverview 'os-settings-languages-page-v2' is the languages sub-page + * for languages and inputs settings. + */ + +Polymer({ + is: 'os-settings-languages-page-v2', + + behaviors: [ + I18nBehavior, + PrefsBehavior, + ], + + properties: { + /** + * Preferences state. + */ + prefs: { + type: Object, + notify: true, + }, + + /** + * Read-only reference to the languages model provided by the + * 'os-settings-languages' instance. + * @type {!LanguagesModel|undefined} + */ + languages: { + type: Object, + notify: true, + }, + + /** @type {!LanguageHelper} */ + languageHelper: Object, + + /** + * The language to display the details for and its index. + * @type {{state: !LanguageState, index: number}|undefined} + * @private + */ + detailLanguage_: Object, + + /** @private */ + showAddLanguagesDialog_: Boolean, + }, + + /** @private {?settings.LanguagesMetricsProxy} */ + languagesMetricsProxy_: null, + + /** @override */ + created() { + this.languagesMetricsProxy_ = + settings.LanguagesMetricsProxyImpl.getInstance(); + }, + + /** + * @param {string} language + * @return {string} + * @private + */ + getLanguageDisplayName_(language) { + return this.languageHelper.getLanguage(language).displayName; + }, + + /** @private */ + onChangeSystemLanguageClick_() { + // TODO(crbug/1113439): Implement change system language dialog. + }, + + /** + * @param {string} language + * @return {string} + * @private + */ + getChangeSystemLanguageButtonDescription_(language) { + return this.i18n( + 'changeSystemLanguageButtonDescription', + this.getLanguageDisplayName_(language)); + }, + + /** + * Stamps and opens the Add Languages dialog, registering a listener to + * disable the dialog's dom-if again on close. + * @param {!Event} e + * @private + */ + onAddLanguagesClick_(e) { + e.preventDefault(); + this.languagesMetricsProxy_.recordAddLanguages(); + this.showAddLanguagesDialog_ = true; + }, + + /** @private */ + onAddLanguagesDialogClose_() { + this.showAddLanguagesDialog_ = false; + cr.ui.focusWithoutInk(assert(this.$.addLanguages)); + }, + + /** + * Checks if there are supported languages that are not enabled but can be + * enabled. + * @param {LanguagesModel|undefined} languages + * @return {boolean} True if there is at least one available language. + * @private + */ + canEnableSomeSupportedLanguage_(languages) { + return languages !== undefined && languages.supported.some(language => { + return this.languageHelper.canEnableLanguage(language); + }); + }, + + /** + * @return {boolean} True if the "Move to top" option for |language| should + * be visible. + * @private + */ + showMoveToTop_() { + // "Move To Top" is a no-op for the top language. + return this.detailLanguage_ !== undefined && + this.detailLanguage_.index === 0; + }, + + /** + * @return {boolean} True if the "Move up" option for |language| should + * be visible. + * @private + */ + showMoveUp_() { + // "Move up" is a no-op for the top language, and redundant with + // "Move to top" for the 2nd language. + return this.detailLanguage_ !== undefined && + this.detailLanguage_.index !== 0 && this.detailLanguage_.index !== 1; + }, + + /** + * @return {boolean} True if the "Move down" option for |language| should be + * visible. + * @private + */ + showMoveDown_() { + return this.languages !== undefined && this.detailLanguage_ !== undefined && + this.detailLanguage_.index !== this.languages.enabled.length - 1; + }, + + /** + * Moves the language to the top of the list. + * @private + */ + onMoveToTopClick_() { + /** @type {!CrActionMenuElement} */ (this.$.menu.get()).close(); + this.languageHelper.moveLanguageToFront( + this.detailLanguage_.state.language.code); + settings.recordSettingChange(); + }, + + /** + * Moves the language up in the list. + * @private + */ + onMoveUpClick_() { + /** @type {!CrActionMenuElement} */ (this.$.menu.get()).close(); + this.languageHelper.moveLanguage( + this.detailLanguage_.state.language.code, /*upDirection=*/ true); + settings.recordSettingChange(); + }, + + /** + * Moves the language down in the list. + * @private + */ + onMoveDownClick_() { + /** @type {!CrActionMenuElement} */ (this.$.menu.get()).close(); + this.languageHelper.moveLanguage( + this.detailLanguage_.state.language.code, /*upDirection=*/ false); + settings.recordSettingChange(); + }, + + /** + * Disables the language. + * @private + */ + onRemoveLanguageClick_() { + /** @type {!CrActionMenuElement} */ (this.$.menu.get()).close(); + this.languageHelper.disableLanguage( + this.detailLanguage_.state.language.code); + settings.recordSettingChange(); + }, + + /** + * @param {!Event} e + * @private + */ + onDotsClick_(e) { + // Sets a copy of the LanguageState object since it is not data-bound to + // the languages model directly. + this.detailLanguage_ = + /** @type {{state: !LanguageState, index: number}} */ ({ + state: /** @type {!LanguageState} */ (e.model.item), + index: /** @type {number} */ (e.model.index) + }); + + const menu = /** @type {!CrActionMenuElement} */ (this.$.menu.get()); + menu.showAt(/** @type {!Element} */ (e.target)); + }, + + /** + * @param {!Event} e + * @private + */ + onTranslateToggleChange_(e) { + this.languagesMetricsProxy_.recordToggleTranslate(e.target.checked); + }, +});
diff --git a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.html b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.html index d9f045093..6f2a9db 100644 --- a/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.html +++ b/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.html
@@ -2,7 +2,9 @@ <link rel="import" href="chrome://resources/cr_elements/cr_icon_button/cr_icon_button.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> +<link rel="import" href="input_page.html"> <link rel="import" href="os_languages_page.html"> +<link rel="import" href="os_languages_page_v2.html"> <link rel="import" href="smart_inputs_page.html"> <link rel="import" href="input_method_options_page.html"> <link rel="import" href="../../i18n_setup.html"> @@ -83,7 +85,11 @@ <settings-subpage associated-control="[[$$('#languagesPageTrigger')]]" page-title="$i18n{languagesPageTitle}"> - <os-settings-languages-page-v2> + <os-settings-languages-page-v2 + language-helper="[[languageHelper]]" + languages="[[languages]]" + prefs="{{prefs}}"> + </os-settings-languages-page-v2> </settings-subpage> </template> @@ -92,7 +98,8 @@ <settings-subpage associated-control="[[$$('#inputPageTrigger')]]" page-title="$i18n{inputPageTitle}"> - <os-settings-input-page> + <os-settings-input-page prefs="{{prefs}}"> + </os-settings-input-page> </settings-subpage> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_printing_page/BUILD.gn index 5a9af5b..9f81ab3 100644 --- a/chrome/browser/resources/settings/chromeos/os_printing_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_printing_page/BUILD.gn
@@ -15,6 +15,7 @@ ":cups_printer_dialog_util", ":cups_printers", ":cups_printers_browser_proxy", + ":cups_printers_entry_manager", ":cups_settings_add_printer_dialog", ":os_printing_page", ]
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.js b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.js index ce2b570..7e3c7a6 100644 --- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.js +++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.js
@@ -33,6 +33,12 @@ notify: true, }, + /** @private {?WebUIListener} */ + onPrintersChangedListener_: { + type: Object, + value: null, + }, + searchTerm: { type: String, }, @@ -128,13 +134,17 @@ */ currentRouteChanged(route) { if (route != settings.routes.CUPS_PRINTERS) { - cr.removeWebUIListener('on-printers-changed'); + if (this.onPrintersChangedListener_) { + cr.removeWebUIListener( + /** @type {WebUIListener} */ (this.onPrintersChangedListener_)); + this.onPrintersChangedListener_ = null; + } this.entryManager_.removeWebUIListeners(); return; } this.entryManager_.addWebUIListeners(); - cr.addWebUIListener( + this.onPrintersChangedListener_ = cr.addWebUIListener( 'on-printers-changed', this.onPrintersChanged_.bind(this)); this.updateCupsPrintersList_(); },
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_manager.js b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_manager.js index c14fafe..1adf9a9 100644 --- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_manager.js +++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_manager.js
@@ -41,22 +41,29 @@ /** @type {!Array<!PrinterListEntry>} */ this.printServerPrinters = []; - /** @type {!Array<PrintersListCallback>} */ + /** @private {!Array<PrintersListCallback>} */ this.onNearbyPrintersChangedListeners_ = []; + + /** @private {?WebUIListener} */ + this.onNearbyPrintersChangedListener_ = null; } addWebUIListeners() { // TODO(1005905): Add on-printers-changed listener here once legacy code // is removed. - cr.addWebUIListener( + this.onNearbyPrintersChangedListener_ = cr.addWebUIListener( 'on-nearby-printers-changed', this.setNearbyPrintersList.bind(this)); + settings.CupsPrintersBrowserProxyImpl.getInstance() .startDiscoveringPrinters(); } removeWebUIListeners() { - cr.removeWebUIListener('on-nearby-printers-changed'); - cr.removeWebUIListener('on-print-server-added'); + if (this.onNearbyPrintersChangedListener_) { + cr.removeWebUIListener(/** @type {WebUIListener} */ ( + this.onNearbyPrintersChangedListener_)); + this.onNearbyPrintersChangedListener_ = null; + } } /** @return {!Array<!PrinterListEntry>} */
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index 054c597..f0fb832 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -60,6 +60,7 @@ "settings.TimeZoneBrowserProxyImpl|TimeZoneBrowserProxyImpl", "settings.ValidateKerberosConfigResult|ValidateKerberosConfigResult", "settings.WallpaperBrowserProxy|WallpaperBrowserProxy", + "smb_shares.SmbBrowserProxy|SmbBrowserProxy", ] os_settings_auto_imports = settings_auto_imports +
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html index 41b508d..d3b543a 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html +++ b/chrome/browser/resources/settings/chromeos/os_settings_page/os_settings_page.html
@@ -27,10 +27,6 @@ <dom-module id="os-settings-page"> <template> <style include="settings-page-styles cr-hidden-style settings-shared"> - :host { - --google-yellow-50: #fef7e0; - } - :host([is-subpage-animating]) { /* Prevent an unwanted horizontal scrollbar when transitioning back from * a sub-page. */
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp b/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp index 3ab5070..669169d 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp +++ b/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp
@@ -94,17 +94,22 @@ use_base_dir="false" compress="false" type="BINDATA" /> - <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_INPUT_METHOD_OPTIONS_PAGE_M_JS" + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_INPUT_METHOD_OPTIONS_PAGE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_options_page.m.js" use_base_dir="false" compress="false" type="BINDATA" /> - <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_INPUT_METHOD_UTIL_M_JS" + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_INPUT_METHOD_UTIL_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/input_method_util.m.js" use_base_dir="false" compress="false" type="BINDATA" /> - <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_MANAGE_INPUT_METHODS_PAGE_M_JS" + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_INPUT_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/input_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_MANAGE_INPUT_METHODS_PAGE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/manage_input_methods_page.m.js" use_base_dir="false" compress="false" @@ -119,6 +124,11 @@ use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_LANGUAGES_PAGE_V2_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_page_v2.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> <include name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_LANGUAGES_SECTION_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_languages_page/os_languages_section.m.js" use_base_dir="false" @@ -301,6 +311,16 @@ use_base_dir="false" compress="false" type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_FILES_PAGE_OS_FILES_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> + <include name="IDR_OS_SETTINGS_OS_FILES_PAGE_SMB_SHARES_PAGE_M_JS" + file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_files_page/smb_shares_page.m.js" + use_base_dir="false" + compress="false" + type="BINDATA" /> <include name="IDR_OS_SETTINGS_BLUETOOTH_PAGE_M_JS" file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/bluetooth_page/bluetooth_page.m.js" use_base_dir="false"
diff --git a/chrome/browser/resources/settings/os_settings_resources.grd b/chrome/browser/resources/settings/os_settings_resources.grd index a19d2705..1c5b05f 100644 --- a/chrome/browser/resources/settings/os_settings_resources.grd +++ b/chrome/browser/resources/settings/os_settings_resources.grd
@@ -704,9 +704,15 @@ <structure name="IDR_OS_SETTINGS_LANGUAGES_PAGE_INPUT_PAGE_HTML" file="chromeos/os_languages_page/input_page.html" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_LANGUAGES_PAGE_INPUT_PAGE_JS" + file="chromeos/os_languages_page/input_page.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_LANGUAGES_PAGE_V2_HTML" file="chromeos/os_languages_page/os_languages_page_v2.html" compress="false" type="chrome_html" /> + <structure name="IDR_OS_SETTINGS_LANGUAGES_PAGE_OS_LANGUAGES_PAGE_V2_JS" + file="chromeos/os_languages_page/os_languages_page_v2.js" + compress="false" type="chrome_html" /> <structure name="IDR_OS_SETTINGS_LANGUAGES_SECTION_HTML" file="chromeos/os_languages_page/os_languages_section.html" compress="false" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/printing_page/cloud_printers.html b/chrome/browser/resources/settings/printing_page/cloud_printers.html index 16e8caf..5bbeff0 100644 --- a/chrome/browser/resources/settings/printing_page/cloud_printers.html +++ b/chrome/browser/resources/settings/printing_page/cloud_printers.html
@@ -1,10 +1,25 @@ - <style include="cr-shared-style settings-shared iron-flex"></style> + <style include="cr-shared-style settings-shared iron-flex"> + #cloud-print-warning { + --google-orange-900: rgb(176, 96, 0); /* b06000 */ + --warning-extra-spacing: 12px; + align-items: center; + background-color: var(--google-yellow-50); + color: var(--google-orange-900); + display: flex; + margin: 0 var(--cr-section-padding) var(--warning-extra-spacing); + min-height: var(--settings-row-min-height); + padding: 0 var(--warning-extra-spacing); + } + </style> + <div id="cloud-print-warning"> + <div class="cr-padded-text">$i18nRaw{cloudPrintFullWarning}</div> + </div> <settings-toggle-button pref="{{prefs.local_discovery.notifications_enabled}}" label="$i18n{printingNotificationsLabel}"> </settings-toggle-button> <a class="cr-row inherit-color no-outline" tabindex="-1" - target="_blank" href="$i18n{devicesUrl}"> + target="_blank" href="$i18n{cloudPrintersUrl}"> <div class="flex"> $i18n{printingManageCloudPrintDevices} </div>
diff --git a/chrome/browser/resources/settings/printing_page/cloud_printers.js b/chrome/browser/resources/settings/printing_page/cloud_printers.js index d7be82bc..aab0f7b 100644 --- a/chrome/browser/resources/settings/printing_page/cloud_printers.js +++ b/chrome/browser/resources/settings/printing_page/cloud_printers.js
@@ -9,6 +9,7 @@ // TODO(xdai): Rename it to 'settings-cloud-printers-page'. import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js'; import 'chrome://resources/cr_elements/shared_style_css.m.js'; +import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; import '../controls/settings_toggle_button.m.js'; import '../settings_shared_css.m.js';
diff --git a/chrome/browser/resources/settings/printing_page/printing_page.html b/chrome/browser/resources/settings/printing_page/printing_page.html index e8d4761c..bb6e3387 100644 --- a/chrome/browser/resources/settings/printing_page/printing_page.html +++ b/chrome/browser/resources/settings/printing_page/printing_page.html
@@ -7,7 +7,9 @@ on-click="onTapLocalPrinters_" external></cr-link-row> </if> <cr-link-row class="hr" id="cloudPrinters" - label="$i18n{cloudPrintersTitle}" on-click="onTapCloudPrinters_" + label="$i18n{cloudPrintersTitle}" + sub-label="$i18n{cloudPrintWarning}" + on-click="onTapCloudPrinters_" role-description="$i18n{subpageArrowRoleDescription}"> </cr-link-row> </div>
diff --git a/chrome/browser/resources/signin/profile_picker/navigation_behavior.js b/chrome/browser/resources/signin/profile_picker/navigation_behavior.js index 97f5175e..754a7e7 100644 --- a/chrome/browser/resources/signin/profile_picker/navigation_behavior.js +++ b/chrome/browser/resources/signin/profile_picker/navigation_behavior.js
@@ -39,8 +39,11 @@ // TODO(msalama): Add support in profile creation mode for policies like: // - ForceSignIn --> load signin page directly. // - DisallowSignIn --> open local profile customization. - // - Check |signInProfileCreationFlow| is not enabled. - return ProfileCreationSteps.PROFILE_TYPE_CHOICE; + if (loadTimeData.getBoolean('signInProfileCreationFlow')) { + return ProfileCreationSteps.PROFILE_TYPE_CHOICE; + } else { + return ProfileCreationSteps.LOCAL_PROFILE_CUSTOMIZATION; + } default: assertNotReached(); }
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn index 518f990..749fd0a4 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn +++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/BUILD.gn
@@ -7,7 +7,10 @@ js_type_check("closure_compile") { is_polymer3 = true - deps = [ ":profile_type_choice" ] + deps = [ + ":local_profile_customization", + ":profile_type_choice", + ] } js_library("profile_type_choice") { @@ -20,6 +23,15 @@ ] } +js_library("local_profile_customization") { + deps = [ + "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + ] +} + html_to_js("web_components") { - js_files = [ "profile_type_choice.js" ] + js_files = [ + "profile_type_choice.js", + "local_profile_customization.js", + ] }
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/ensure_lazy_loaded.js b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/ensure_lazy_loaded.js index 4e50bdc..8821ca6c2 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/ensure_lazy_loaded.js +++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/ensure_lazy_loaded.js
@@ -15,6 +15,7 @@ lazyLoadPromise = Promise.all([ 'profile-type-choice', + 'local-profile-customization', ].map(name => customElements.whenDefined(name))); } return lazyLoadPromise;
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/lazy_load.js b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/lazy_load.js index bb015564..ab38aa4 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/lazy_load.js +++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/lazy_load.js
@@ -3,3 +3,4 @@ // found in the LICENSE file. import './profile_type_choice.js'; +import './local_profile_customization.js'; \ No newline at end of file
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html new file mode 100644 index 0000000..060847e6 --- /dev/null +++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html
@@ -0,0 +1 @@ +<div> Local profile customization </div> \ No newline at end of file
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js new file mode 100644 index 0000000..81e88a7 --- /dev/null +++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js
@@ -0,0 +1,11 @@ +// 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 {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +Polymer({ + is: 'local-profile-customization', + + _template: html`{__html_template__}`, +}); \ No newline at end of file
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_app.html b/chrome/browser/resources/signin/profile_picker/profile_picker_app.html index 23a2704..4ceb884 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_picker_app.html +++ b/chrome/browser/resources/signin/profile_picker/profile_picker_app.html
@@ -16,4 +16,10 @@ </profile-type-choice> </template> </cr-lazy-render> + + <cr-lazy-render id="localProfileCustomization"> + <template> + <local-profile-customization slot="view"></local-profile-customizatione> + </template> + </cr-lazy-render> </cr-view-manager>
diff --git a/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd b/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd index 9c77ec48..465789f 100644 --- a/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd +++ b/chrome/browser/resources/signin/profile_picker/profile_picker_resources.grd
@@ -46,6 +46,9 @@ <include name="IDR_PROFILE_PICKER_PROFILE_CREATION_FLOW_PROFILE_TYPE_CHOICE_JS" file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_creation_flow/profile_type_choice.js" use_base_dir="false" type="BINDATA"/> + <include name="IDR_PROFILE_PICKER_PROFILE_CREATION_FLOW_LOCAL_PROFILE_CUSTOMIZATION_JS" + file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.js" + use_base_dir="false" type="BINDATA"/> <include name="IDR_PROFILE_PICKER_PROFILE_PICKER_SHARED_CSS_JS" file="${root_gen_dir}/chrome/browser/resources/signin/profile_picker/profile_picker_shared_css.js" use_base_dir="false" type="BINDATA"/>
diff --git a/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/settings/SecuritySettingsFragment.java b/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/settings/SecuritySettingsFragment.java index de505ca..1ae1b736 100644 --- a/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/settings/SecuritySettingsFragment.java +++ b/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/settings/SecuritySettingsFragment.java
@@ -118,10 +118,12 @@ int newState = (int) newValue; @SafeBrowsingState int currentState = SafeBrowsingBridge.getSafeBrowsingState(); + if (newState == currentState) { + return true; + } // If the user selects no protection from another Safe Browsing state, show a confirmation // dialog to double check if they want to select no protection. - if (newState == SafeBrowsingState.NO_SAFE_BROWSING - && currentState != SafeBrowsingState.NO_SAFE_BROWSING) { + if (newState == SafeBrowsingState.NO_SAFE_BROWSING) { // The user hasn't confirmed to select no protection, keep the radio button / UI checked // state at the currently selected level. mSafeBrowsingPreference.setCheckedState(currentState);
diff --git a/chrome/browser/sessions/closed_tab_cache.cc b/chrome/browser/sessions/closed_tab_cache.cc new file mode 100644 index 0000000..5e0a0b18 --- /dev/null +++ b/chrome/browser/sessions/closed_tab_cache.cc
@@ -0,0 +1,133 @@ +// 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/sessions/closed_tab_cache.h" + +#include <memory> + +#include "base/bind.h" +#include "base/metrics/field_trial_params.h" +#include "chrome/browser/browser_features.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/web_contents.h" + +namespace { + +// The number of entries the ClosedTabCache can hold. +static constexpr size_t kClosedTabCacheLimit = 1; + +// The default time to live in seconds for entries in the ClosedTabCache. +static constexpr base::TimeDelta kDefaultTimeToLiveInClosedTabCacheInSeconds = + base::TimeDelta::FromSeconds(15); +} // namespace + +ClosedTabCache::Entry::Entry(SessionID id, + std::unique_ptr<content::WebContents> wc, + base::TimeTicks timestamp) + : id(id), web_contents(std::move(wc)), tab_closure_timestamp(timestamp) {} +ClosedTabCache::Entry::~Entry() = default; + +ClosedTabCache::ClosedTabCache() + : cache_size_limit_(kClosedTabCacheLimit), + task_runner_( + content::GetUIThreadTaskRunner(content::BrowserTaskTraits())) {} +ClosedTabCache::~ClosedTabCache() = default; + +base::TimeDelta ClosedTabCache::GetTimeToLiveInClosedTabCache() { + // We use the following order of priority if multiple values exist: + // - The programmatical value set in params. Used in specific tests. + // - Default value otherwise, kDefaultTimeToLiveInClosedTabCacheInSeconds. + + return base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt( + features::kClosedTabCache, "time_to_live_in_closed_tab_cache_in_seconds", + kDefaultTimeToLiveInClosedTabCacheInSeconds.InSeconds())); +} + +void ClosedTabCache::StoreEntry(SessionID id, + std::unique_ptr<content::WebContents> wc, + base::TimeTicks timestamp) { + TRACE_EVENT2("browser", "ClosedTabCache::StoreEntry", "SessionID", id.id(), + "URL", wc->GetURL().spec()); + + auto entry = std::make_unique<Entry>(id, std::move(wc), timestamp); + + // TODO: Dispatch pagehide() before freezing. + entry->web_contents->SetPageFrozen(/*frozen=*/true); + StartEvictionTimer(entry.get()); + + entries_.push_front(std::move(entry)); + + // Evict least recently used tab if the ClosedTabCache is full. + if (entries_.size() > cache_size_limit_) { + entries_.pop_back(); + } +} + +std::unique_ptr<content::WebContents> ClosedTabCache::RestoreEntry( + SessionID id) { + TRACE_EVENT1("browser", "ClosedTabCache::RestoreEntry", "SessionID", id.id()); + auto matching_entry = std::find_if( + entries_.begin(), entries_.end(), + [id](const std::unique_ptr<Entry>& entry) { return entry->id == id; }); + + if (matching_entry == entries_.end()) + return nullptr; + + std::unique_ptr<Entry> entry = std::move(*matching_entry); + entries_.erase(matching_entry); + entry->web_contents->SetPageFrozen(/*frozen=*/false); + // TODO: Dispatch pageshow() after unfreezing. + + return std::move(entry->web_contents); +} + +const content::WebContents* ClosedTabCache::GetWebContents(SessionID id) const { + auto matching_entry = std::find_if( + entries_.begin(), entries_.end(), + [id](const std::unique_ptr<Entry>& entry) { return entry->id == id; }); + + if (matching_entry == entries_.end()) + return nullptr; + + return (*matching_entry).get()->web_contents.get(); +} + +void ClosedTabCache::StartEvictionTimer(Entry* entry) { + base::TimeDelta evict_after = GetTimeToLiveInClosedTabCache(); + entry->eviction_timer.SetTaskRunner(task_runner_); + entry->eviction_timer.Start( + FROM_HERE, evict_after, + base::BindOnce(&ClosedTabCache::EvictEntryById, base::Unretained(this), + entry->id)); +} + +void ClosedTabCache::EvictEntryById(SessionID id) { + auto matching_entry = std::find_if( + entries_.begin(), entries_.end(), + [id](const std::unique_ptr<Entry>& entry) { return entry->id == id; }); + + if (matching_entry == entries_.end()) + return; + + std::unique_ptr<Entry> entry = std::move(*matching_entry); + entries_.erase(matching_entry); +} + +void ClosedTabCache::SetCacheSizeLimitForTesting(size_t limit) { + cache_size_limit_ = limit; +} + +void ClosedTabCache::SetTaskRunnerForTesting( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + task_runner_ = task_runner; +} + +bool ClosedTabCache::IsEmpty() { + return entries_.empty(); +} + +size_t ClosedTabCache::EntriesCount() { + return entries_.size(); +} \ No newline at end of file
diff --git a/chrome/browser/sessions/closed_tab_cache.h b/chrome/browser/sessions/closed_tab_cache.h new file mode 100644 index 0000000..ead7224 --- /dev/null +++ b/chrome/browser/sessions/closed_tab_cache.h
@@ -0,0 +1,111 @@ +// 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_SESSIONS_CLOSED_TAB_CACHE_H_ +#define CHROME_BROWSER_SESSIONS_CLOSED_TAB_CACHE_H_ +#endif + +#include <list> +#include <memory> + +#include "base/single_thread_task_runner.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "components/sessions/core/session_id.h" + +namespace content { +class WebContents; +} // namespace content + +// ClosedTabCache: +// +// A browser feature implemented with the purpose of instantaneously restoring +// recently closed tabs. The main use case of ClosedTabCache is to immediately +// restore accidentally closed tabs. +// +// Main functionality: +// - stores WebContents instances uniquely identified by a SessionID. +// - evicts cache entries after a timeout. +// - evicts the least recently closed tab when the cache is full. +// +// TODO(aebacanu): Make ClosedTabCache listen to MemoryPressureListener and +// clear the cache if memory is tight. Hook ClosedTabCache into the navigation +// flow. +class ClosedTabCache { + public: + ClosedTabCache(); + ClosedTabCache(const ClosedTabCache&) = delete; + ClosedTabCache& operator=(const ClosedTabCache&) = delete; + ~ClosedTabCache(); + + // Creates a ClosedTabCache::Entry from the given |id|, |wc| and |timestamp|. + // Moves the entry into the ClosedTabCache and evicts one if necessary. + void StoreEntry(SessionID id, + std::unique_ptr<content::WebContents> wc, + base::TimeTicks timestamp); + + // Moves a WebContents out of ClosedTabCache knowing its |id|. Returns nullptr + // if none is found. + std::unique_ptr<content::WebContents> RestoreEntry(SessionID id); + + // Returns a pointer to a cached WebContents whose entry is matching |id| if + // it exists in the ClosedTabCache. Returns nullptr if no matching is found. + const content::WebContents* GetWebContents(SessionID id) const; + + // We evict tabs from the ClosedTabCache after the time to live, which can be + // controlled via experiment. + static base::TimeDelta GetTimeToLiveInClosedTabCache(); + + // Set a different cache size limit that is only used in tests. + void SetCacheSizeLimitForTesting(size_t limit); + + // Inject a task runner for timing control within browser tests. + void SetTaskRunnerForTesting( + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + // Whether the entries list is empty or not. + bool IsEmpty(); + + // Get the number of currently stored entries. + size_t EntriesCount(); + + private: + struct Entry { + Entry(SessionID id, + std::unique_ptr<content::WebContents> wc, + base::TimeTicks timestamp); + Entry(const Entry&) = delete; + Entry& operator=(const Entry&) = delete; + ~Entry(); + + // The tab's unique SessionID used in TabRestoreService::Entry. + SessionID id; + + // The tab being stored. + std::unique_ptr<content::WebContents> web_contents; + + // Timestamp of tab closure. + base::TimeTicks tab_closure_timestamp; + + base::OneShotTimer eviction_timer; + }; + + // Start the given entry's eviction timer. + void StartEvictionTimer(Entry* entry); + + // Evict an entry from the ClosedTabCache based on the given SessionID. Does + // nothing if the entry cannot be found. + void EvictEntryById(SessionID id); + + // The set of stored Entries. + // Invariants: + // - Ordered from the most recently closed tab to the least recently closed. + // - Once the list is full, the least recently closed tab is evicted. + std::list<std::unique_ptr<Entry>> entries_; + + size_t cache_size_limit_; + + // Task runner used for evicting cache entries after timeout. + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; +}; \ No newline at end of file
diff --git a/chrome/browser/sessions/closed_tab_cache_browsertest.cc b/chrome/browser/sessions/closed_tab_cache_browsertest.cc new file mode 100644 index 0000000..25f0cfa --- /dev/null +++ b/chrome/browser/sessions/closed_tab_cache_browsertest.cc
@@ -0,0 +1,196 @@ +// 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/sessions/closed_tab_cache.h" + +#include "base/test/test_mock_time_task_runner.h" +#include "base/time/time.h" +#include "chrome/browser/browser_features.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_tabstrip.h" +#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/sessions/core/session_id.h" +#include "content/public/test/browser_test.h" + +using content::WebContents; + +class ClosedTabCacheTest : public InProcessBrowserTest { + public: + ClosedTabCacheTest() = default; + ClosedTabCacheTest(const ClosedTabCacheTest&) = delete; + ClosedTabCacheTest& operator=(const ClosedTabCacheTest&) = delete; + + protected: + // Add a tab to the given browser. + void AddTab(Browser* browser) { + ui_test_utils::NavigateToURLWithDisposition( + browser, GURL(chrome::kChromeUINewTabURL), + WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + } +}; + +// Add an entry to the cache when the cache is empty. +IN_PROC_BROWSER_TEST_F(ClosedTabCacheTest, StoreEntryWhenEmpty) { + ClosedTabCache cache; + + AddTab(browser()); + ASSERT_EQ(browser()->tab_strip_model()->count(), 2); + + std::unique_ptr<WebContents> wc = + browser()->tab_strip_model()->DetachWebContentsAt(0); + + ASSERT_TRUE(cache.IsEmpty()) + << "Expected cache to be empty at the start of the test."; + + cache.StoreEntry(SessionID::NewUnique(), std::move(wc), + base::TimeTicks::Now()); + EXPECT_EQ(cache.EntriesCount(), 1U); +} + +// Add an entry to the cache when there is enough space. +IN_PROC_BROWSER_TEST_F(ClosedTabCacheTest, StoreEntryBasic) { + ClosedTabCache cache; + + cache.SetCacheSizeLimitForTesting(2); + + AddTab(browser()); + AddTab(browser()); + ASSERT_EQ(browser()->tab_strip_model()->count(), 3); + + std::unique_ptr<WebContents> wc1 = + browser()->tab_strip_model()->DetachWebContentsAt(0); + std::unique_ptr<WebContents> wc2 = + browser()->tab_strip_model()->DetachWebContentsAt(0); + + ASSERT_TRUE(cache.IsEmpty()) + << "Expected cache to be empty at the start of the test."; + + cache.StoreEntry(SessionID::NewUnique(), std::move(wc1), + base::TimeTicks::Now()); + EXPECT_EQ(cache.EntriesCount(), 1U); + + cache.StoreEntry(SessionID::NewUnique(), std::move(wc2), + base::TimeTicks::Now()); + EXPECT_EQ(cache.EntriesCount(), 2U); +} + +// Add an entry to the cache when the cache is at its limit. +IN_PROC_BROWSER_TEST_F(ClosedTabCacheTest, StoreEntryWhenFull) { + ClosedTabCache cache; + + AddTab(browser()); + AddTab(browser()); + ASSERT_EQ(browser()->tab_strip_model()->count(), 3); + + std::unique_ptr<WebContents> wc1 = + browser()->tab_strip_model()->DetachWebContentsAt(0); + std::unique_ptr<WebContents> wc2 = + browser()->tab_strip_model()->DetachWebContentsAt(0); + SessionID id1 = SessionID::NewUnique(); + + ASSERT_TRUE(cache.IsEmpty()) + << "Expected cache to be empty at the start of the test."; + + cache.StoreEntry(id1, std::move(wc1), base::TimeTicks::Now()); + EXPECT_EQ(cache.EntriesCount(), 1U); + + cache.StoreEntry(SessionID::NewUnique(), std::move(wc2), + base::TimeTicks::Now()); + + // Expect the cache size to still be 1 and the removed entry to be entry1. + EXPECT_EQ(cache.EntriesCount(), 1U); + EXPECT_EQ(cache.GetWebContents(id1), nullptr); +} + +// Restore an entry when the cache is empty. +IN_PROC_BROWSER_TEST_F(ClosedTabCacheTest, RestoreEntryWhenEmpty) { + ClosedTabCache cache; + + ASSERT_TRUE(cache.IsEmpty()) + << "Expected cache to be empty at the start of the test."; + + SessionID id = SessionID::NewUnique(); + EXPECT_EQ(cache.RestoreEntry(id), nullptr); +} + +// Restore an entry that is not in the cache. +IN_PROC_BROWSER_TEST_F(ClosedTabCacheTest, RestoreEntryWhenNotFound) { + ClosedTabCache cache; + + AddTab(browser()); + ASSERT_EQ(browser()->tab_strip_model()->count(), 2); + + std::unique_ptr<WebContents> wc = + browser()->tab_strip_model()->DetachWebContentsAt(0); + + ASSERT_TRUE(cache.IsEmpty()) + << "Expected cache to be empty at the start of the test."; + + cache.StoreEntry(SessionID::NewUnique(), std::move(wc), + base::TimeTicks::Now()); + EXPECT_EQ(cache.EntriesCount(), 1U); + + SessionID id = SessionID::NewUnique(); + EXPECT_EQ(cache.RestoreEntry(id), nullptr); +} + +// Restore an entry that is in the cache. +IN_PROC_BROWSER_TEST_F(ClosedTabCacheTest, RestoreEntryWhenFound) { + ClosedTabCache cache; + + AddTab(browser()); + ASSERT_EQ(browser()->tab_strip_model()->count(), 2); + + std::unique_ptr<WebContents> wc = + browser()->tab_strip_model()->DetachWebContentsAt(0); + + ASSERT_TRUE(cache.IsEmpty()) + << "Expected cache to be empty at the start of the test."; + + SessionID id = SessionID::NewUnique(); + cache.StoreEntry(id, std::move(wc), base::TimeTicks::Now()); + EXPECT_EQ(cache.EntriesCount(), 1U); + + EXPECT_NE(cache.RestoreEntry(id), nullptr); +} + +// Evict an entry after timeout. +IN_PROC_BROWSER_TEST_F(ClosedTabCacheTest, EvictEntryOnTimeout) { + ClosedTabCache cache; + + scoped_refptr<base::TestMockTimeTaskRunner> task_runner = + base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + cache.SetTaskRunnerForTesting(task_runner); + + AddTab(browser()); + ASSERT_EQ(browser()->tab_strip_model()->count(), 2); + + std::unique_ptr<WebContents> wc = + browser()->tab_strip_model()->DetachWebContentsAt(0); + + ASSERT_TRUE(cache.IsEmpty()) + << "Expected cache to be empty at the start of the test."; + + cache.StoreEntry(SessionID::NewUnique(), std::move(wc), + base::TimeTicks::Now()); + EXPECT_EQ(cache.EntriesCount(), 1U); + + // Fast forward to just before eviction is due. + base::TimeDelta delta = base::TimeDelta::FromMilliseconds(1); + base::TimeDelta ttl = ClosedTabCache::GetTimeToLiveInClosedTabCache(); + task_runner->FastForwardBy(ttl - delta); + + // Expect the entry to still be in the cache. + EXPECT_EQ(cache.EntriesCount(), 1U); + + // Fast forward to when eviction is due. + task_runner->FastForwardBy(delta); + + // Expect the entry to have been evicted. + EXPECT_EQ(cache.EntriesCount(), 0U); +} \ No newline at end of file
diff --git a/chrome/browser/subresource_filter/subresource_filter_test_harness.cc b/chrome/browser/subresource_filter/subresource_filter_test_harness.cc index eda4f880..cef3607 100644 --- a/chrome/browser/subresource_filter/subresource_filter_test_harness.cc +++ b/chrome/browser/subresource_filter/subresource_filter_test_harness.cc
@@ -29,6 +29,7 @@ #include "components/subresource_filter/core/common/activation_decision.h" #include "components/subresource_filter/core/common/activation_list.h" #include "components/subresource_filter/core/common/test_ruleset_creator.h" +#include "components/subresource_filter/core/common/test_ruleset_utils.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/navigation_throttle.h" @@ -37,6 +38,8 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +constexpr char const SubresourceFilterTestHarness::kDefaultAllowedSuffix[]; +constexpr char const SubresourceFilterTestHarness::kDefaultDisallowedSuffix[]; constexpr char const SubresourceFilterTestHarness::kDefaultDisallowedUrl[]; SubresourceFilterTestHarness::SubresourceFilterTestHarness() = default; @@ -91,8 +94,11 @@ // Publish the test ruleset. subresource_filter::testing::TestRulesetCreator ruleset_creator; subresource_filter::testing::TestRulesetPair test_ruleset_pair; - ruleset_creator.CreateRulesetToDisallowURLsWithPathSuffix("disallowed.html", - &test_ruleset_pair); + ruleset_creator.CreateRulesetWithRules( + {subresource_filter::testing::CreateSuffixRule(kDefaultDisallowedSuffix), + subresource_filter::testing::CreateAllowlistSuffixRule( + kDefaultAllowedSuffix)}, + &test_ruleset_pair); subresource_filter::testing::TestRulesetPublisher test_ruleset_publisher; ASSERT_NO_FATAL_FAILURE( test_ruleset_publisher.SetRuleset(test_ruleset_pair.unindexed));
diff --git a/chrome/browser/subresource_filter/subresource_filter_test_harness.h b/chrome/browser/subresource_filter/subresource_filter_test_harness.h index 36129ac..247e42c 100644 --- a/chrome/browser/subresource_filter/subresource_filter_test_harness.h +++ b/chrome/browser/subresource_filter/subresource_filter_test_harness.h
@@ -25,8 +25,12 @@ // subresource filtering code. class SubresourceFilterTestHarness : public ChromeRenderViewHostTestHarness { public: - static constexpr char const kDefaultDisallowedUrl[] = + // Allowlist rules must prefix a disallowed rule in order to work correctly. + static constexpr const char kDefaultAllowedSuffix[] = "not_disallowed.html"; + static constexpr const char kDefaultDisallowedSuffix[] = "disallowed.html"; + static constexpr const char kDefaultDisallowedUrl[] = "https://example.test/disallowed.html"; + SubresourceFilterTestHarness(); ~SubresourceFilterTestHarness() override;
diff --git a/chrome/browser/sync/test/integration/enable_disable_test.cc b/chrome/browser/sync/test/integration/enable_disable_test.cc index d7777aa..979291ba 100644 --- a/chrome/browser/sync/test/integration/enable_disable_test.cc +++ b/chrome/browser/sync/test/integration/enable_disable_test.cc
@@ -442,14 +442,10 @@ SetupTest(/*all_types_enabled=*/true); SyncPrefs prefs(GetProfile(0)->GetPrefs()); - const std::string initial_cache_guid = prefs.GetCacheGuid(); - ASSERT_NE("", initial_cache_guid); + ASSERT_NE("", prefs.GetCacheGuid()); GetClient(0)->StopSyncServiceAndClearData(); - // After "stop and clear", the SyncService may immediately start up again in - // transport-only mode, creating a new cache GUID. So the cache GUID may be - // non-empty now, but it must be different from the previous one. - EXPECT_NE(initial_cache_guid, prefs.GetCacheGuid()); + EXPECT_EQ("", prefs.GetCacheGuid()); } IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
diff --git a/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc b/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc index 342d37db..bdb507b 100644 --- a/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_web_apps_sync_test.cc
@@ -429,7 +429,7 @@ base::RunLoop run_loop; WebAppProvider::Get(dest_profile) ->icon_manager() - .ReadSmallestIcon( + .ReadSmallestIconAny( synced_app_id, 192, base::BindLambdaForTesting([&run_loop](const SkBitmap& bitmap) { EXPECT_EQ(bitmap.getColor(0, 0), SK_ColorBLUE);
diff --git a/chrome/browser/tab/BUILD.gn b/chrome/browser/tab/BUILD.gn index 1beca98..bded4fd 100644 --- a/chrome/browser/tab/BUILD.gn +++ b/chrome/browser/tab/BUILD.gn
@@ -59,7 +59,7 @@ "//net/android:net_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_core_core_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", "//ui/android:ui_full_java", "//url:gurl_java", "//url:origin_java",
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java index d16f6bc..da4b9655 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -157,14 +157,6 @@ int getLaunchType(); /** - * @return The reason the Tab was launched. This remains unchanged, while {@link - * #getLaunchType()} can change over time. - */ - @Nullable - @TabLaunchType - Integer getLaunchTypeAtInitialTabCreation(); - - /** * @return {@code true} if the Tab is in incognito mode. */ boolean isIncognito();
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java index 499bfc6..1d107bc6 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java
@@ -6,6 +6,7 @@ import android.graphics.Color; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import com.google.protobuf.ByteString; @@ -18,6 +19,7 @@ import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.WebContentsState; import org.chromium.chrome.browser.tab.proto.CriticalPersistedTabData.CriticalPersistedTabDataProto; +import org.chromium.url.GURL; import java.nio.ByteBuffer; import java.util.Locale; @@ -37,6 +39,11 @@ * Title of the ContentViews webpage. */ private String mTitle; + + /** + * URL of the page currently loading. Used as a fall-back in case tab restore fails. + */ + private GURL mUrl; private int mParentId; private int mRootId; private long mTimestampMillis; @@ -50,7 +57,12 @@ private int mContentStateVersion; private String mOpenerAppId; private int mThemeColor; - private @TabLaunchType Integer mTabLaunchTypeAtCreation; + /** + * Saves how this tab was initially launched so that we can record metrics on how the + * tab was created. This is different than {@link Tab#getLaunchType()}, since {@link + * Tab#getLaunchType()} will be overridden to "FROM_RESTORE" during tab restoration. + */ + private @Nullable @TabLaunchType Integer mTabLaunchTypeAtCreation; private ObserverList<CriticalPersistedTabDataObserver> mObservers = new ObserverList<CriticalPersistedTabDataObserver>(); @@ -79,7 +91,7 @@ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) CriticalPersistedTabData(Tab tab, int parentId, int rootId, long timestampMillis, WebContentsState webContentsState, int contentStateVersion, String openerAppId, - int themeColor, int launchTypeAtCreation) { + int themeColor, @Nullable @TabLaunchType Integer launchTypeAtCreation) { this(tab); mParentId = parentId; mRootId = rootId; @@ -142,10 +154,7 @@ // CriticalPersistedTabData is initialized with default values CriticalPersistedTabData criticalPersistedTabData = new CriticalPersistedTabData(tab, Tab.INVALID_TAB_ID, tab.getId(), - INVALID_TIMESTAMP, null, -1, "", UNSPECIFIED_THEME_COLOR, - tab.getLaunchTypeAtInitialTabCreation() == null - ? TabLaunchType.FROM_LINK - : tab.getLaunchTypeAtInitialTabCreation()); + INVALID_TIMESTAMP, null, -1, "", UNSPECIFIED_THEME_COLOR, null); return criticalPersistedTabData; } @@ -315,6 +324,21 @@ } /** + * @return {@link GURL} for the {@link Tab} + */ + public GURL getUrl() { + return mUrl; + } + + /** + * Set {@link GURL} for the {@link Tab} + * @param url to set + */ + public void setUrl(GURL url) { + mUrl = url; + } + + /** * @return identifier for the {@link Tab} */ public int getTabId() { @@ -405,10 +429,14 @@ /** * @return launch type at creation */ - public @TabLaunchType int getTabLaunchTypeAtCreation() { + public @Nullable @TabLaunchType Integer getTabLaunchTypeAtCreation() { return mTabLaunchTypeAtCreation; } + public void setLaunchTypeAtCreation(@Nullable @TabLaunchType Integer launchTypeAtCreation) { + mTabLaunchTypeAtCreation = launchTypeAtCreation; + } + /** * Add a {@link CriticalPersistedTabDataObserver} * @param criticalPersistedTabDataObserver the observer
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_keyed_service.cc b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service.cc new file mode 100644 index 0000000..96298d94 --- /dev/null +++ b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service.cc
@@ -0,0 +1,24 @@ +// 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/tflite_experiment/tflite_experiment_keyed_service.h" + +#include "base/optional.h" +#include "chrome/browser/tflite_experiment/tflite_experiment_switches.h" + +constexpr int32_t kTFLiteNumThreads = 4; + +TFLiteExperimentKeyedService::TFLiteExperimentKeyedService( + content::BrowserContext* browser_context) { + base::Optional<std::string> model_path = + tflite_experiment::switches::GetTFLiteModelPath(); + if (!model_path) + return; + + predictor_ = std::make_unique<machine_learning::TFLitePredictor>( + model_path.value(), kTFLiteNumThreads); + predictor_->Initialize(); +} + +TFLiteExperimentKeyedService::~TFLiteExperimentKeyedService() = default;
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_keyed_service.h b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service.h new file mode 100644 index 0000000..cb58890 --- /dev/null +++ b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service.h
@@ -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. + +#ifndef CHROME_BROWSER_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_KEYED_SERVICE_H_ +#define CHROME_BROWSER_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_KEYED_SERVICE_H_ + +#include "chrome/services/machine_learning/machine_learning_tflite_predictor.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace content { +class BrowserContext; +} // namespace content + +// Keyed service than can be used to receive requests for enabling +// a TFLite experiment. +class TFLiteExperimentKeyedService : public KeyedService { + public: + explicit TFLiteExperimentKeyedService( + content::BrowserContext* browser_context); + ~TFLiteExperimentKeyedService() override; + + machine_learning::TFLitePredictor* tflite_predictor() { + return predictor_.get(); + } + + private: + // The predictor owned by this keyed service capable of + // running a TFLite model. + std::unique_ptr<machine_learning::TFLitePredictor> predictor_; +}; + +#endif // CHROME_BROWSER_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_KEYED_SERVICE_H_
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_browsertest.cc b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_browsertest.cc new file mode 100644 index 0000000..963cd06 --- /dev/null +++ b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_browsertest.cc
@@ -0,0 +1,179 @@ +// 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/tflite_experiment/tflite_experiment_keyed_service.h" + +#include "base/command_line.h" +#include "base/json/json_reader.h" +#include "base/path_service.h" +#include "base/task/thread_pool/thread_pool_instance.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/values.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/tflite_experiment/tflite_experiment_keyed_service_factory.h" +#include "chrome/browser/tflite_experiment/tflite_experiment_switches.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/metrics/content/subprocess_metrics_provider.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +constexpr char kTFLiteModelName[] = "simple_test.tflite"; +constexpr char kNavigationURL[] = "https://google.com"; +constexpr char kTFLiteExperimentLogName[] = "tflite_experiment.log"; + +namespace { +// Fetch and calculate the total number of samples from all the bins for +// |histogram_name|. Note: from some browertests run, there might be two +// profiles created, and this will return the total sample count across +// profiles. +int GetTotalHistogramSamples(const base::HistogramTester& histogram_tester, + const std::string& histogram_name) { + std::vector<base::Bucket> buckets = + histogram_tester.GetAllSamples(histogram_name); + int total = 0; + for (const auto& bucket : buckets) + total += bucket.count; + + return total; +} + +// Retries fetching |histogram_name| until it contains at least |count| samples. +int RetryForHistogramUntilCountReached( + const base::HistogramTester& histogram_tester, + const std::string& histogram_name, + int count) { + int total = 0; + while (true) { + base::ThreadPoolInstance::Get()->FlushForTesting(); + total = GetTotalHistogramSamples(histogram_tester, histogram_name); + if (total >= count) + return total; + content::FetchHistogramsFromChildProcesses(); + metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + base::RunLoop().RunUntilIdle(); + } +} +} // namespace + +class TFLiteExperimentKeyedServiceDisabledBrowserTest + : public InProcessBrowserTest { + public: + TFLiteExperimentKeyedServiceDisabledBrowserTest() = default; + ~TFLiteExperimentKeyedServiceDisabledBrowserTest() override = default; + + void WaitForTFLiteObserverToCallNullTFLitePredictor() { + EXPECT_GT(RetryForHistogramUntilCountReached( + histogram_tester_, + "TFLiteExperiment.Observer.TFLitePredictor.Null", 1), + 0); + } + + private: + base::HistogramTester histogram_tester_; +}; + +IN_PROC_BROWSER_TEST_F(TFLiteExperimentKeyedServiceDisabledBrowserTest, + TFLiteExperimentEnabledButTFLitePredictorDisabled) { + auto* tflite_experiment_keyed_service = + TFLiteExperimentKeyedServiceFactory::GetForProfile(browser()->profile()); + EXPECT_TRUE(tflite_experiment_keyed_service); + EXPECT_FALSE(tflite_experiment_keyed_service->tflite_predictor()); +} + +IN_PROC_BROWSER_TEST_F( + TFLiteExperimentKeyedServiceDisabledBrowserTest, + TFLiteExperimentEnabledButTFLitePredictorDisabledOnNavigation) { + GURL navigation_url(kNavigationURL); + ui_test_utils::NavigateToURL(browser(), navigation_url); + WaitForTFLiteObserverToCallNullTFLitePredictor(); +} + +class TFLiteExperimentKeyedServiceBrowserTest : public InProcessBrowserTest { + public: + TFLiteExperimentKeyedServiceBrowserTest() = default; + ~TFLiteExperimentKeyedServiceBrowserTest() override = default; + + void SetUpCommandLine(base::CommandLine* cmd) override { + // Location of test data. + base::FilePath g_test_data_directory; + + // Set TFLite model path. + base::PathService::Get(chrome::DIR_TEST_DATA, &g_test_data_directory); + g_test_data_directory = g_test_data_directory.Append(kTFLiteModelName); + cmd->AppendSwitchASCII(tflite_experiment::switches::kTFLiteModelPath, + g_test_data_directory.value()); + + // Set TFLite experiment log path. + cmd->AppendSwitchASCII( + tflite_experiment::switches::kTFLiteExperimentLogPath, + GetTFLiteExperimentLogPath().value()); + } + + base::FilePath GetTFLiteExperimentLogPath() { + base::FilePath g_test_data_directory; + base::PathService::Get(chrome::DIR_TEST_DATA, &g_test_data_directory); + g_test_data_directory = + g_test_data_directory.Append(kTFLiteExperimentLogName); + return g_test_data_directory; + } + + void WaitForObserverToFinish() { + EXPECT_GT(RetryForHistogramUntilCountReached( + histogram_tester_, "TFLiteExperiment.Observer.Finish", 1), + 0); + } + + void WaitForTFLitePredictorToBeReEvaluated() { + EXPECT_GT( + RetryForHistogramUntilCountReached( + histogram_tester_, + "TFLiteExperiment.Observer.TFLitePredictor.EvaluationRequested", 1), + 0); + } + + private: + base::HistogramTester histogram_tester_; +}; + +IN_PROC_BROWSER_TEST_F(TFLiteExperimentKeyedServiceBrowserTest, + TFLiteExperimentEnabledWithKeyedService) { + EXPECT_TRUE( + TFLiteExperimentKeyedServiceFactory::GetForProfile(browser()->profile())); +} + +IN_PROC_BROWSER_TEST_F(TFLiteExperimentKeyedServiceBrowserTest, + TFLiteExperimentPredictorCreated) { + auto* tflite_experiment_keyed_service = + TFLiteExperimentKeyedServiceFactory::GetForProfile(browser()->profile()); + EXPECT_TRUE(tflite_experiment_keyed_service); + EXPECT_TRUE(tflite_experiment_keyed_service->tflite_predictor()); +} + +IN_PROC_BROWSER_TEST_F(TFLiteExperimentKeyedServiceBrowserTest, + TFLiteExperimentPredictorEvaluated) { + GURL navigation_url(kNavigationURL); + ui_test_utils::NavigateToURL(browser(), navigation_url); + WaitForTFLitePredictorToBeReEvaluated(); +} + +IN_PROC_BROWSER_TEST_F(TFLiteExperimentKeyedServiceBrowserTest, + TFLiteExperimentLog) { + GURL navigation_url(kNavigationURL); + ui_test_utils::NavigateToURL(browser(), navigation_url); + WaitForObserverToFinish(); + + std::string data; + base::ScopedAllowBlockingForTesting allow_blocking; + base::ReadFileToString(GetTFLiteExperimentLogPath(), &data); + base::Optional<base::Value> root = base::JSONReader::Read(data); + EXPECT_TRUE(root); + EXPECT_TRUE(*root->FindIntKey("input_set_time")); + EXPECT_TRUE(*root->FindIntKey("evaluation_time")); +}
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_factory.cc b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_factory.cc new file mode 100644 index 0000000..5859bb3 --- /dev/null +++ b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_factory.cc
@@ -0,0 +1,36 @@ +// 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/tflite_experiment/tflite_experiment_keyed_service_factory.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/tflite_experiment/tflite_experiment_keyed_service.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" + +// static +TFLiteExperimentKeyedService* +TFLiteExperimentKeyedServiceFactory::GetForProfile(Profile* profile) { + return static_cast<TFLiteExperimentKeyedService*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + +// static +TFLiteExperimentKeyedServiceFactory* +TFLiteExperimentKeyedServiceFactory::GetInstance() { + static base::NoDestructor<TFLiteExperimentKeyedServiceFactory> factory; + return factory.get(); +} + +TFLiteExperimentKeyedServiceFactory::TFLiteExperimentKeyedServiceFactory() + : BrowserContextKeyedServiceFactory( + "TFLiteExperimentKeyedService", + BrowserContextDependencyManager::GetInstance()) {} + +TFLiteExperimentKeyedServiceFactory::~TFLiteExperimentKeyedServiceFactory() = + default; + +KeyedService* TFLiteExperimentKeyedServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + return new TFLiteExperimentKeyedService(context); +}
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_factory.h b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_factory.h new file mode 100644 index 0000000..94de771f --- /dev/null +++ b/chrome/browser/tflite_experiment/tflite_experiment_keyed_service_factory.h
@@ -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. + +#ifndef CHROME_BROWSER_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_KEYED_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_KEYED_SERVICE_FACTORY_H_ + +#include "base/macros.h" +#include "base/no_destructor.h" +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +namespace content { +class BrowserContext; +} // namespace content + +class TFLiteExperimentKeyedService; +class Profile; + +// LazyInstance that owns all TFLiteExperimentKeyedService and associates them +// with Profiles. +class TFLiteExperimentKeyedServiceFactory + : public BrowserContextKeyedServiceFactory { + public: + // Gets the TFLiteExperimentService for the profile. + static TFLiteExperimentKeyedService* GetForProfile(Profile* profile); + + // Gets the LazyInstance that owns all TFLiteExperimentKeyedService(s). + static TFLiteExperimentKeyedServiceFactory* GetInstance(); + + private: + friend base::NoDestructor<TFLiteExperimentKeyedServiceFactory>; + + TFLiteExperimentKeyedServiceFactory(); + ~TFLiteExperimentKeyedServiceFactory() override; + + // BrowserContextKeyedServiceFactory: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; +}; + +#endif // CHROME_BROWSER_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_KEYED_SERVICE_FACTORY_H_
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_observer.cc b/chrome/browser/tflite_experiment/tflite_experiment_observer.cc new file mode 100644 index 0000000..c72d967 --- /dev/null +++ b/chrome/browser/tflite_experiment/tflite_experiment_observer.cc
@@ -0,0 +1,135 @@ +// 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/tflite_experiment/tflite_experiment_observer.h" + +#include "base/files/file_util.h" +#include "base/json/json_writer.h" +#include "base/metrics/histogram_macros_local.h" +#include "base/task/task_traits.h" +#include "base/time/time.h" +#include "base/values.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/tflite_experiment/tflite_experiment_keyed_service.h" +#include "chrome/browser/tflite_experiment/tflite_experiment_keyed_service_factory.h" +#include "chrome/browser/tflite_experiment/tflite_experiment_switches.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" + +constexpr int32_t kTFLitePredictorEvaluationLoop = 10; + +namespace { + +// Returns the TFLitePredictor. +machine_learning::TFLitePredictor* GetTFLitePredictorFromWebContents( + content::WebContents* web_contents) { + if (!web_contents) + return nullptr; + + if (Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext())) { + return TFLiteExperimentKeyedServiceFactory::GetForProfile(profile) + ->tflite_predictor(); + } + return nullptr; +} + +} // namespace + +TFLiteExperimentObserver::TFLiteExperimentObserver( + content::WebContents* web_contents) + : content::WebContentsObserver(web_contents) { + tflite_predictor_ = GetTFLitePredictorFromWebContents(web_contents); + tflite_experiment_log_path_ = + tflite_experiment::switches::GetTFLiteExperimentLogPath(); +} + +TFLiteExperimentObserver::~TFLiteExperimentObserver() = default; + +void TFLiteExperimentObserver::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + DCHECK(navigation_handle); + if (!navigation_handle->IsInMainFrame() || + !navigation_handle->GetURL().SchemeIsHTTPOrHTTPS() || + !navigation_handle->HasCommitted()) { + return; + } + + if (!tflite_predictor_ || !tflite_predictor_->IsInitialized()) { + LOCAL_HISTOGRAM_BOOLEAN("TFLiteExperiment.Observer.TFLitePredictor.Null", + true); + return; + } + + if (is_tflite_evaluated_) + return; + + base::TimeTicks t1 = base::TimeTicks::Now(); + CreatePredictorInputForTesting(); + base::TimeTicks t2 = base::TimeTicks::Now(); + // Run evaluation for |kTFLitePredictorEvaluationLoop| times and report + // average time. + for (int i = 0; i < kTFLitePredictorEvaluationLoop; i++) + tflite_predictor_->Evaluate(); + base::TimeTicks t3 = base::TimeTicks::Now(); + + log_dict_.SetIntKey("input_set_time", (t2 - t1).InMicroseconds()); + log_dict_.SetIntKey("evaluation_time", (t3 - t2).InMilliseconds() / + kTFLitePredictorEvaluationLoop); + + is_tflite_evaluated_ = true; + LOCAL_HISTOGRAM_BOOLEAN( + "TFLiteExperiment.Observer.TFLitePredictor.EvaluationRequested", true); + + std::string message; + base::JSONWriter::Write(log_dict_, &message); + base::ThreadPool::PostTask( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&LogDictionary, tflite_experiment_log_path_, message)); +} + +void TFLiteExperimentObserver::CreatePredictorInputForTesting() { + for (int i = 0; i < tflite_predictor_->GetInputTensorCount(); i++) { + int32_t tensor_total_dim = 1; + for (int j = 0; j < tflite_predictor_->GetInputTensorNumDims(i); j++) { + tensor_total_dim = + tensor_total_dim * tflite_predictor_->GetInputTensorDim(i, j); + } + int* tensor_data = + static_cast<int*>(tflite_predictor_->GetInputTensorData(i)); + for (int k = 0; k < tensor_total_dim; k++) { + tensor_data[k] = 1; + } + } +} + +// static +void TFLiteExperimentObserver::Log(base::Optional<std::string> log_path, + const std::string& data) { + if (!log_path) + return; + base::FilePath log_file = base::FilePath(log_path.value()); + base::AppendToFile(log_file, data.c_str(), data.size()); +} + +// static +void TFLiteExperimentObserver::LogWriteHeader( + base::Optional<std::string> log_path) { + if (!log_path) + return; + base::FilePath log_file = base::FilePath(log_path.value()); + base::WriteFile(log_file, "", 0); +} + +// static +void TFLiteExperimentObserver::LogDictionary( + base::Optional<std::string> log_path, + const std::string& data) { + LogWriteHeader(log_path); + Log(log_path, data); + LOCAL_HISTOGRAM_BOOLEAN("TFLiteExperiment.Observer.Finish", true); +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(TFLiteExperimentObserver)
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_observer.h b/chrome/browser/tflite_experiment/tflite_experiment_observer.h new file mode 100644 index 0000000..71b2c50 --- /dev/null +++ b/chrome/browser/tflite_experiment/tflite_experiment_observer.h
@@ -0,0 +1,67 @@ +// 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_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_OBSERVER_H_ +#define CHROME_BROWSER_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_OBSERVER_H_ + +#include <string> + +#include "base/macros.h" +#include "base/timer/timer.h" +#include "chrome/services/machine_learning/machine_learning_tflite_predictor.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace content { +class NavigationHandle; +class WebContents; +} // namespace content + +// Web content observer that runs a TFLite predictor +// at different stages of a navigation. +class TFLiteExperimentObserver + : public content::WebContentsObserver, + public content::WebContentsUserData<TFLiteExperimentObserver> { + public: + ~TFLiteExperimentObserver() override; + + private: + friend class content::WebContentsUserData<TFLiteExperimentObserver>; + explicit TFLiteExperimentObserver(content::WebContents* web_contents); + + // content::WebContentsObserver. + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + + // Set input of the TFLite model for testing. + void CreatePredictorInputForTesting(); + + // Log data in TFLite experiment |log_path|. + static void Log(base::Optional<std::string> log_path, + const std::string& data); + + // Writes header in TFLite experiment |log_path|. + static void LogWriteHeader(base::Optional<std::string> log_path); + + // Writes TFLite experiment metrics in |log_path| when experiment is finished. + static void LogDictionary(base::Optional<std::string> log_path, + const std::string&); + + // The predictor is capable of running a TFLite model. + machine_learning::TFLitePredictor* tflite_predictor_ = nullptr; + + // True when |tflite_predictor_| ran model evaluation. It forces + // the observer to run tflite prediction only once. + bool is_tflite_evaluated_ = false; + + // Log dictionary that keeps recorded metrics. + base::DictionaryValue log_dict_; + + // TFLite experiment log path. + base::Optional<std::string> tflite_experiment_log_path_; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); +}; + +#endif // CHROME_BROWSER_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_OBSERVER_H_
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_switches.cc b/chrome/browser/tflite_experiment/tflite_experiment_switches.cc new file mode 100644 index 0000000..0b038a6 --- /dev/null +++ b/chrome/browser/tflite_experiment/tflite_experiment_switches.cc
@@ -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. + +#include "chrome/browser/tflite_experiment/tflite_experiment_switches.h" + +#include "base/command_line.h" + +namespace tflite_experiment { +namespace switches { + +// Specifies the TFLite model path that TFLite machine learning uses. +const char kTFLiteModelPath[] = "tflite-model-path"; + +// Specifies the TFLite experiment log file path. +const char kTFLiteExperimentLogPath[] = "tflite-experiment-log-path"; + +base::Optional<std::string> GetTFLiteModelPath() { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(tflite_experiment::switches::kTFLiteModelPath)) { + return command_line->GetSwitchValueASCII( + tflite_experiment::switches::kTFLiteModelPath); + } + return base::nullopt; +} + +base::Optional<std::string> GetTFLiteExperimentLogPath() { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch( + tflite_experiment::switches::kTFLiteExperimentLogPath)) { + return command_line->GetSwitchValueASCII( + tflite_experiment::switches::kTFLiteExperimentLogPath); + } + return base::nullopt; +} + +} // namespace switches +} // namespace tflite_experiment
diff --git a/chrome/browser/tflite_experiment/tflite_experiment_switches.h b/chrome/browser/tflite_experiment/tflite_experiment_switches.h new file mode 100644 index 0000000..448a243 --- /dev/null +++ b/chrome/browser/tflite_experiment/tflite_experiment_switches.h
@@ -0,0 +1,27 @@ +// 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_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_SWITCHES_H_ +#define CHROME_BROWSER_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_SWITCHES_H_ + +#include <string> + +#include "base/optional.h" + +namespace tflite_experiment { +namespace switches { + +extern const char kTFLiteModelPath[]; +extern const char kTFLiteExperimentLogPath[]; + +// Returns TFLite model path. +base::Optional<std::string> GetTFLiteModelPath(); + +// Returns TFLite experiment log file path. +base::Optional<std::string> GetTFLiteExperimentLogPath(); + +} // namespace switches +} // namespace tflite_experiment + +#endif // CHROME_BROWSER_TFLITE_EXPERIMENT_TFLITE_EXPERIMENT_SWITCHES_H_
diff --git a/chrome/browser/thumbnail/generator/BUILD.gn b/chrome/browser/thumbnail/generator/BUILD.gn index 04dffbd..1a78ab32 100644 --- a/chrome/browser/thumbnail/generator/BUILD.gn +++ b/chrome/browser/thumbnail/generator/BUILD.gn
@@ -79,7 +79,7 @@ "//third_party/android_deps:android_support_v4_java", "//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_collection_collection_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", ] sources = [
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 6163224b..bca26fd 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -340,6 +340,7 @@ # have the same dependencies. Once browser_ui is untangled from # browser, then we can clean up these dependencies. public_deps = [ + "//chrome/services/machine_learning:machine_learning_tflite_buildflags", "//components/dom_distiller/core", "//components/safe_browsing:buildflags", "//components/sync", @@ -1999,6 +2000,8 @@ "views/apps/chrome_native_app_window_views_aura_ash.h", "views/arc_app_dialog_view.cc", "views/arc_data_removal_dialog_view.cc", + "views/borealis/borealis_installer_view.cc", + "views/borealis/borealis_installer_view.h", "views/chrome_views_delegate_chromeos.cc", "views/crostini/crostini_ansible_software_config_view.cc", "views/crostini/crostini_ansible_software_config_view.h", @@ -2060,8 +2063,6 @@ "webui/app_management/app_management_shelf_delegate_chromeos.h", "webui/certificate_provisioning_ui_handler.cc", "webui/certificate_provisioning_ui_handler.h", - "webui/chrome_url_disabled_ui.cc", - "webui/chrome_url_disabled_ui.h", "webui/chromeos/account_manager/account_manager_error_ui.cc", "webui/chromeos/account_manager/account_manager_error_ui.h", "webui/chromeos/account_manager/account_manager_welcome_dialog.cc", @@ -2107,6 +2108,8 @@ "webui/chromeos/cellular_setup/mobile_setup_ui.h", "webui/chromeos/certificate_manager_dialog_ui.cc", "webui/chromeos/certificate_manager_dialog_ui.h", + "webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.cc", + "webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.h", "webui/chromeos/crostini_installer/crostini_installer_dialog.cc", "webui/chromeos/crostini_installer/crostini_installer_dialog.h", "webui/chromeos/crostini_installer/crostini_installer_page_handler.cc",
diff --git a/chrome/browser/ui/android/autofill/OWNERS b/chrome/browser/ui/android/autofill/OWNERS new file mode 100644 index 0000000..b946bf67 --- /dev/null +++ b/chrome/browser/ui/android/autofill/OWNERS
@@ -0,0 +1 @@ +file://chrome/android/java/src/org/chromium/chrome/browser/autofill/OWNERS \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb index fd201fc..4abe30ae 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_af.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Meld aan en skakel sinkronisering aan om jou oortjies van jou ander toestelle af te kry</translation> <translation id="3587482841069643663">Alles</translation> <translation id="3587596251841506391">Help websekuriteit verbeter</translation> -<translation id="3590487821116122040">Berging van werwe wat Chrome nie dink belangrik is nie (bv. werwe met geen gestoorde instellings nie of wat jy nie dikwels besoek nie)</translation> <translation id="3594780231884063836">Demp video</translation> <translation id="3599863153486145794">Vee geskiedenis op alle aangemelde toestelle uit. Jou Google-rekening het dalk ander vorme van blaaigeskiedenis by <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Oudio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopieer skakel</translation> <translation id="3988213473815854515">Ligging word toegelaat</translation> <translation id="3988466920954086464">Sien kitssoekresultate in hierdie paneel</translation> -<translation id="3997476611815694295">Berging vir onbelangrike werwe</translation> <translation id="4000212216660919741">Vanlyn tuisblad</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# uur}other{# uur}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Gebruikernaam is gekopieer</translation> <translation id="543509235395288790">Laai tans <ph name="COUNT" /> lêers af (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Spring na die adresbalk</translation> -<translation id="5447201525962359567">Alle werfberging, insluitend koekies en ander plaaslik gestoorde data</translation> <translation id="545042621069398927">Maak jou aflaai vinniger.</translation> <translation id="5456381639095306749">Laai bladsy af</translation> <translation id="548278423535722844">Maak in kaarteprogram oop</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb index e1b1ded..fc24120 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_am.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">ትሮችዎን ከሌሎች መሣሪያዎችዎ በመለያ መግባት እና ስምረትን ማብራት ለማግኘት</translation> <translation id="3587482841069643663">ሁሉም</translation> <translation id="3587596251841506391">ድር ላይ ደህንነትን ለማሻሻል ያግዙ</translation> -<translation id="3590487821116122040">Chrome አላስፈላጊ ነው የሚያስበው የጣቢያ ማከማቻ (ለምሳሌ፦ ምንም የተቀመጡ ቅንብሮች የሌላቸው ጣቢያዎች ወይም እርስዎ ብዙ ጊዜ የማይጎበኟቸው)</translation> <translation id="3594780231884063836">ቪዲዮ ላይ ድምጸ-ከል አድርግ</translation> <translation id="3599863153486145794">ታሪክን በመለያ ከገቡ ሁሉም መሣሪያዎች ላይ ያጸዳል። የእርስዎ Google መለያ <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> ላይ ሌሎች የአሰሳ ታሪክ ዓይነቶች ሊኖረው ይችላል</translation> <translation id="3616113530831147358">ድምጽ</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">አገናኝ ቅዳ</translation> <translation id="3988213473815854515">መገኛ አካባቢ ተፈቅዷል</translation> <translation id="3988466920954086464">በዚህ ፓነል ውስጥ ቅጽበታዊ የፍለጋ ውጤቶችን ይመልከቱ</translation> -<translation id="3997476611815694295">የማያስፈልግ ማከማቻ</translation> <translation id="4000212216660919741">ከመስመር ውጭ መነሻ</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ሰዓ}one{# ሰዓቶች}other{# ሰዓቶች}}</translation> <translation id="4056223980640387499">ቀይ ቡናማ</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">የተጠቃሚ ስም ተቀድቷል</translation> <translation id="543509235395288790"><ph name="COUNT" /> ፋይሎችን በማውረድ ላይ (<ph name="MEGABYTES" />)።</translation> <translation id="5441522332038954058">ወደ የአድራሻው አሞሌ ዘልለህ ሂድ</translation> -<translation id="5447201525962359567">ኩኪዎች እና ሌላ በአከባቢያዊ የተከማቸ ውሂብን ጨምሮ ሁሉም የጣቢያ ማከማቻ</translation> <translation id="545042621069398927">ውርድዎን በማፍጠን ላይ።</translation> <translation id="5456381639095306749">ገጽ አውርድ</translation> <translation id="548278423535722844">በካርታዎች መተግበሪያ ውስጥ ይክፈቱ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb index ef2f2e7..8e2a0f8 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ar.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">للحصول على علامات التبويب من أجهزتك الأخرى، يُرجى تسجيل الدخول وتفعيل المزامنة.</translation> <translation id="3587482841069643663">الكل</translation> <translation id="3587596251841506391">المساعدة في تحسين الأمان على الويب</translation> -<translation id="3590487821116122040">مساحة تخزين الموقع التي لا يعتقد Chrome أنها مهمة (مثل المواقع التي لا تتضمَّن إعدادات محفوظة أو تلك التي لا تزورها مرارًا)</translation> <translation id="3594780231884063836">كتم صوت الفيديو</translation> <translation id="3599863153486145794">يمسح السجل من كل الأجهزة التي تم تسجيل الدخول عليها. وقد يتضمن حسابك في Google نماذج أخرى من سجل التصفح في <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">المقاطع الصوتية</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">نسخ الرابط</translation> <translation id="3988213473815854515">الموقع مسموح به</translation> <translation id="3988466920954086464">الاطلاع على نتائج البحث الفورية في هذه اللوحة</translation> -<translation id="3997476611815694295">مساحة تخزين غير مهمة</translation> <translation id="4000212216660919741">الصفحة الرئيسية بلا اتصال بالإنترنت</translation> <translation id="4034817413553209278">{HOURS,plural, =1{ساعة واحدة (#)}zero{# ساعة}two{ساعتان (#)}few{# ساعات}many{# ساعةً}other{# ساعة}}</translation> <translation id="4056223980640387499">بني داكن</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">تم نسخ اسم المستخدم</translation> <translation id="543509235395288790">جارٍ تنزيل <ph name="COUNT" /> من الملفات (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">الانتقال السريع إلى شريط العناوين</translation> -<translation id="5447201525962359567">مساحة التخزين في الموقع كاملة، بما في ذلك ملفات تعريف الارتباط وغيرها من البيانات المُخزَّنَة محليًا</translation> <translation id="545042621069398927">جارٍ تسريع التنزيل.</translation> <translation id="5456381639095306749">تنزيل الصفحة</translation> <translation id="548278423535722844">فتح في تطبيق الخرائط</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb index 30947b9..6083bed 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_as.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">আপোনাৰ অন্য ডিভাইচসমূহৰ পৰা নিজৰ টেবসমূহ পাবলৈ ছাইন ইন আৰু ছিংক কৰা সুবিধাটো অন কৰক</translation> <translation id="3587482841069643663">সকলো</translation> <translation id="3587596251841506391">ৱেবত সুৰক্ষা উন্নত কৰাত সহায় কৰক</translation> -<translation id="3590487821116122040">Chromeএ গুৰুত্বপূর্ণ বুলি গণ্য নকৰা ছাইটৰ ষ্ট’ৰেজ (যেনে ছেভ কৰা ছেটিংসমূহ নথকা ছাইটসমূহ বা আপুনি সঘনে নোচোৱা ছাইটসমূহ)</translation> <translation id="3594780231884063836">ভিডিঅ' মিউট কৰক</translation> <translation id="3599863153486145794">সকলো ছাইন ইন হৈ থকা ডিভাইচৰ পৰা ইতিহাস মচে। <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />ত আপোনাৰ Google একাউণ্টৰ অন্য প্ৰকাৰৰ ব্ৰাউজিং ইতিহাস থাকিব পাৰে।</translation> <translation id="3616113530831147358">অডিঅ’</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">লিংক প্ৰতিলিপি কৰক</translation> <translation id="3988213473815854515">অৱস্থানৰ অনুমতি দিয়া হৈছে</translation> <translation id="3988466920954086464">এই পেনেলটোত তাৎক্ষণিকভাৱে সন্ধানৰ ফলাফল চাওক</translation> -<translation id="3997476611815694295">গুৰুত্বহীন ফাইলৰ ষ্ট’ৰেজ</translation> <translation id="4000212216660919741">অফলাইন গৃহপৃষ্ঠা</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ঘণ্টা}one{# ঘণ্টা}other{# ঘণ্টা}}</translation> <translation id="4056223980640387499">ছেপিয়া</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">ব্যৱহাৰকাৰীৰ নাম প্ৰতিলিপি কৰা হ’ল</translation> <translation id="543509235395288790"><ph name="COUNT" />টা ফাইল ডাউনল’ড হৈ আছে (<ph name="MEGABYTES" />)।</translation> <translation id="5441522332038954058">পোনপটীয়াকৈ ঠিকনা বাৰলৈ যাওক</translation> -<translation id="5447201525962359567">কুকি আৰু স্থানীয়ভাৱে ষ্ট'ৰ কৰা অন্য ডেটাকে ধৰি ছাইটৰ সম্পূৰ্ণ ষ্ট'ৰেজ</translation> <translation id="545042621069398927">আপোনাৰ ডাউনল’ড আৰু খৰতকীয়া কৰি থকা হৈছে।</translation> <translation id="5456381639095306749">পৃষ্ঠাটো ডাউনল'ড কৰক</translation> <translation id="548278423535722844">maps এপত খোলক</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb index a1ff19a..f0b0d28 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_az.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Tabları digər cihazlarınızdan əldə etmək üçün daxil olun və sinxronizasiyanı aktiv edin</translation> <translation id="3587482841069643663">Hamısı</translation> <translation id="3587596251841506391">Vebdə güvənliyi artırmağa yardım edin</translation> -<translation id="3590487821116122040">Sayt yaddaşı Chrome vacib olduğunu düşünmür (məs. yadda saxlanmayan ayarlar ilə olan və ya tez-tez daxil olmadığınız saytlar)</translation> <translation id="3594780231884063836">Videonu səssiz rejimə keçirin</translation> <translation id="3599863153486145794">Bütün daxil olunmuş cihazlardan tarixçəni silir. <ph name="BEGIN_LINK" />history.google.com<ph name="END_LINK" /> linkində Google Hesabına məxsus axtarış tarixçəsinin başqa formaları ola bilər.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Linki kopyalayın</translation> <translation id="3988213473815854515">Məkana icazə verilir</translation> <translation id="3988466920954086464">Ani axtarış nəticələrinə bu paneldə baxın</translation> -<translation id="3997476611815694295">Əhəmiyyətsiz yaddaş</translation> <translation id="4000212216660919741">Ev oflayndır</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# saat}other{# saat}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">İstifadəçi adı kopyalandı</translation> <translation id="543509235395288790"><ph name="COUNT" /> fayl (<ph name="MEGABYTES" />) endirilir.</translation> <translation id="5441522332038954058">Ünvan barına keçin</translation> -<translation id="5447201525962359567">Kukilər və digər yerli yadda saxlanmış data daxil olmaqla bütün sayt yaddaşı</translation> <translation id="545042621069398927">Endirmənizi sürətləndirin.</translation> <translation id="5456381639095306749">Endirmə səhifəsi</translation> <translation id="548278423535722844">Xəritə tətbiqində açın</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb index 1f28d4a..db64b1b 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_be.xtb
@@ -328,7 +328,6 @@ <translation id="3568688522516854065">Каб бачыць укладкі з іншых сваіх прылад, увайдзіце і ўключыце сінхранізацыю</translation> <translation id="3587482841069643663">Усе</translation> <translation id="3587596251841506391">Павысіць бяспеку ў інтэрнэце</translation> -<translation id="3590487821116122040">Даныя сайтаў, якія Chrome не лічыць важнымі (напрыклад, сайты, налады якіх не захаваны або якія вы наведваеце рэдка)</translation> <translation id="3594780231884063836">Выключыць гук відэа</translation> <translation id="3599863153486145794">Ачышчае гісторыю на ўсіх прыладах, з якіх выкананы ўваход. На сайце <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> могуць быць размешчаны іншыя формы запісу гісторыі прагляду сайтаў для вашага Уліковага запісу Google.</translation> <translation id="3616113530831147358">Аўдыя</translation> @@ -379,7 +378,6 @@ <translation id="3987993985790029246">Скапіраваць спасылку</translation> <translation id="3988213473815854515">Вызначэнне месцазнаходжання дазволена</translation> <translation id="3988466920954086464">Імгненныя вынікі пошуку будуць паказвацца ў гэтай панэлі</translation> -<translation id="3997476611815694295">Другараднае сховішча</translation> <translation id="4000212216660919741">Пазасеткавы рэжым</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# гадз}one{# гадз}few{# гадз}many{# гадз}other{# гадз}}</translation> <translation id="4056223980640387499">Сепія</translation> @@ -556,7 +554,6 @@ <translation id="5433691172869980887">Імя карыстальніка скапіравана</translation> <translation id="543509235395288790">Спампоўваюцца файлы ў колькасці <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Перайсці да адраснага радка</translation> -<translation id="5447201525962359567">Усё сховішча сайта, у тым ліку файлы cookie і іншыя лакальна захаваныя даныя</translation> <translation id="545042621069398927">Спампоўка паскараецца.</translation> <translation id="5456381639095306749">Спампаваць старонку</translation> <translation id="548278423535722844">Адкрыць у праграме карт</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb index 7f36f327..243645a 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bg.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Влезте в профила си и включете синхронизирането, за да получите разделите си от другите си устройства</translation> <translation id="3587482841069643663">Всички</translation> <translation id="3587596251841506391">Помогнете за по-сигурна мрежа</translation> -<translation id="3590487821116122040">Съхранявани данни от сайтове, които Chrome не счита за важни (напр. рядко посещавани или сайтове без запазени настройки)</translation> <translation id="3594780231884063836">Без образ</translation> <translation id="3599863153486145794">Изчиства историята от всички устройства, на които сте влезли в профила си в Google. В него може да има други видове история на сърфиране, съхранявани на адрес <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Аудио</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Връзка: Коп.</translation> <translation id="3988213473815854515">Местоположението е разрешено</translation> <translation id="3988466920954086464">Отворете този панел, за да видите динамичните резултати от търсенето</translation> -<translation id="3997476611815694295">Маловажни данни в хранилището</translation> <translation id="4000212216660919741">Начална страница в офлайн режим</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ч}other{# ч}}</translation> <translation id="4056223980640387499">Сепия</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Потребителското име е копирано</translation> <translation id="543509235395288790">Изтеглят се <ph name="COUNT" /> файла (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Преминаване към адресната лента</translation> -<translation id="5447201525962359567">Всички данни от сайтове, включително „бисквитки“ и друга локално съхранявана информация</translation> <translation id="545042621069398927">Изтеглянето се ускорява.</translation> <translation id="5456381639095306749">Изтегляне на страницата</translation> <translation id="548278423535722844">Отваряне в приложение за карти</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb index 9a8ca7a..29d0ac76 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bn.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">আপনার অন্যান্য ডিভাইস থেকে ট্যাবগুলি পেতে সাইন-ইন করে সিঙ্ক বিকল্প চালু করুন</translation> <translation id="3587482841069643663">সকল</translation> <translation id="3587596251841506391">ওয়েবে নিরাপত্তা উন্নত করতে সাহায্য করে</translation> -<translation id="3590487821116122040">যে সাইট স্টোরেজকে Chrome গুরুত্বপূর্ণ মনে করে না (উদাঃ সেভকরা সেটিংস বিহীন সাইটগুলি বা আপনি প্রায়শই ঘুরে দেখেন না এমন সাইটগুলি)</translation> <translation id="3594780231884063836">ভিডিওটি মিউট করুন</translation> <translation id="3599863153486145794">সমস্ত সাইন-ইন করা ডিভাইসগুলি থেকে ইতিহাস মুছে ফেলে। <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />-এ আপনার Google অ্যাকাউন্টের অন্যান্য ধরনের ব্রাউজিংয়ের ইতিহাস থাকতে পারে।</translation> <translation id="3616113530831147358">অডিও</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">লিঙ্ক কপি করুন</translation> <translation id="3988213473815854515">লোকেশন অনুমোদিত হয়েছে</translation> <translation id="3988466920954086464">সার্চের ফলাফল ঝটপট এই প্যানেলে দেখুন</translation> -<translation id="3997476611815694295">গুরুত্বহীন সঞ্চয়স্থান</translation> <translation id="4000212216660919741">অফলাইন হোম</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ঘণ্টা}one{# ঘণ্টা}other{# ঘণ্টা}}</translation> <translation id="4056223980640387499">সেপিয়া</translation> @@ -564,7 +562,6 @@ <translation id="5433691172869980887">ইউজারনেম কপি করা হয়েছে</translation> <translation id="543509235395288790"><ph name="COUNT" />টি ফাইল ডাউনলোড হচ্ছে (<ph name="MEGABYTES" />)।</translation> <translation id="5441522332038954058">অ্যাড্রেস বারে চলে যান</translation> -<translation id="5447201525962359567">কুকিজ ও অন্যান্য স্থানীয়ভাবে সংরক্ষণ করা তথ্য সহ সাইটের সকল সঞ্চয়স্থান</translation> <translation id="545042621069398927">আপনার ডাউনলোডের স্পিড বাড়ানো হচ্ছে।</translation> <translation id="5456381639095306749">পৃষ্ঠা ডাউনলোড করুন</translation> <translation id="548278423535722844">ম্যাপ অ্যাপ্লিকেশানে খুলুন</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb index c3c930b..a74314a 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_bs.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">Da dobijete svoje kartice s vaših drugih uređaja, prijavite se i uključite sinhronizaciju</translation> <translation id="3587482841069643663">Sve</translation> <translation id="3587596251841506391">Poboljšajte sigurnost na webu</translation> -<translation id="3590487821116122040">Pohrana web lokacije za koju Chrome smatra da nije važna (npr. stranice bez sačuvanih postavki ili one koje ne posjećujete često)</translation> <translation id="3594780231884063836">Isključivanje zvuka videozapisa</translation> <translation id="3599863153486145794">Briše historiju sa svih prijavljenih uređaja. Vaš Google račun može imati druge oblike historije pregledanja na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Zvuk</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">Kopiraj link</translation> <translation id="3988213473815854515">Lokacija je dozvoljena</translation> <translation id="3988466920954086464">Vidite rezultate instant pretraživanja u ovom panelu</translation> -<translation id="3997476611815694295">Nevažna pohrana</translation> <translation id="4000212216660919741">Početna stranica van mreže</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}one{# h}few{# h}other{# h}}</translation> <translation id="4056223980640387499">Sepija</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">Kopirano je korisničko ime</translation> <translation id="543509235395288790">Broj fajlova koji se preuzima: <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Pređi na traku za adresu</translation> -<translation id="5447201525962359567">Pohrana cijele web lokacije, uključujući kolačiće i druge podatke koji su lokalno pohranjeni</translation> <translation id="545042621069398927">Ubrzavanje preuzimanja.</translation> <translation id="5456381639095306749">Preuzmi stranicu</translation> <translation id="548278423535722844">Otvori u aplikacijama za mape</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb index d186d0383..06f3214 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ca.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Inicia la sessió i activa la sincronització per accedir a les pestanyes dels altres dispositius que tinguis</translation> <translation id="3587482841069643663">Tots</translation> <translation id="3587596251841506391">Millora la seguretat al web</translation> -<translation id="3590487821116122040">Emmagatzematge de llocs web que Chrome no considera important (com ara llocs web sense configuració desada o aquells que no visites sovint)</translation> <translation id="3594780231884063836">Silencia el vídeo</translation> <translation id="3599863153486145794">Esborra l'historial de tots els dispositius en què tinguis iniciada la sessió. A <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> trobaràs altres maneres d'explorar l'historial de navegació del Compte de Google.</translation> <translation id="3616113530831147358">Àudio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Copia l'enllaç</translation> <translation id="3988213473815854515">La ubicació es permet</translation> <translation id="3988466920954086464">Consulta els resultats de la cerca instantània en aquest tauler</translation> -<translation id="3997476611815694295">Emmagatzematge no important</translation> <translation id="4000212216660919741">Pàgina d'inici sense connexió</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4056223980640387499">Sèpia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">S'ha copiat el nom d'usuari</translation> <translation id="543509235395288790">S'estan baixant <ph name="COUNT" /> fitxers (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Ves a la barra d'adreces</translation> -<translation id="5447201525962359567">Tot l'emmagatzematge del lloc web, com ara les galetes i altres dades emmagatzemades localment</translation> <translation id="545042621069398927">S'està accelerant la baixada.</translation> <translation id="5456381639095306749">Baixa la pàgina</translation> <translation id="548278423535722844">Obre en una aplicació de mapes</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb index 02650370..7a80f05b 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_cs.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Chcete-li získat přístup ke kartám ze svých ostatních zařízení, zapněte synchronizaci</translation> <translation id="3587482841069643663">Vše</translation> <translation id="3587596251841506391">Zlepšovat bezpečnost na webu</translation> -<translation id="3590487821116122040">Úložiště webů, které Chrome považuje za nedůležité (např. weby bez uložených nastavení nebo weby, které nenavštěvujete často)</translation> <translation id="3594780231884063836">Vypnout zvuk videa</translation> <translation id="3599863153486145794">Vymaže historii ze všech zařízení, na kterých jste přihlášeni. Na stránce <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> mohou být k dispozici další druhy historie prohlížení zaznamenané ve vašem účtu Google.</translation> <translation id="3616113530831147358">Zvuk</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopírovat odkaz</translation> <translation id="3988213473815854515">Přístup k poloze je povolen</translation> <translation id="3988466920954086464">Na tomto panelu naleznete výsledky dynamického vyhledávání</translation> -<translation id="3997476611815694295">Nedůležité úložiště</translation> <translation id="4000212216660919741">Offline domovská stránka</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}few{# h}many{# h}other{# h}}</translation> <translation id="4056223980640387499">Sépie</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Uživatelské jméno bylo zkopírováno</translation> <translation id="543509235395288790">Stahování <ph name="COUNT" /> souborů (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Přejít na adresní řádek</translation> -<translation id="5447201525962359567">Veškerá data webů, včetně souborů cookie a dalších místně uložených dat</translation> <translation id="545042621069398927">Zrychlování stahování.</translation> <translation id="5456381639095306749">Stáhnout stránku</translation> <translation id="548278423535722844">Otevřít v mapové aplikaci</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb index fea05c3..cacef41c 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_da.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Log ind, og aktivér synkronisering for at få adgang til dine faner på dine andre enheder</translation> <translation id="3587482841069643663">Alle</translation> <translation id="3587596251841506391">Gør sikkerheden på nettet bedre</translation> -<translation id="3590487821116122040">Websitelagerplads, som ikke er vigtig ifølge Chrome (f.eks. websites uden gemte indstillinger eller websites, du ikke besøger så ofte)</translation> <translation id="3594780231884063836">Slå lyden i videoen fra</translation> <translation id="3599863153486145794">Rydder historikken på alle enheder, hvor du er logget ind. Din Google-konto kan have andre former for browserhistorik på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Lyd</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopiér linket</translation> <translation id="3988213473815854515">Placeringen er tilladt</translation> <translation id="3988466920954086464">Se direkte søgeresultater i dette panel</translation> -<translation id="3997476611815694295">Lagerplads, der ikke er vigtig</translation> <translation id="4000212216660919741">Hjemmet er offline</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# t.}one{# t.}other{# t.}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Brugernavnet er kopieret</translation> <translation id="543509235395288790">Downloader <ph name="COUNT" /> filer (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Gå til adresselinjen</translation> -<translation id="5447201525962359567">Al websitelagerplads, herunder cookies og andre data, der er gemt lokalt</translation> <translation id="545042621069398927">Øger hastigheden på din download.</translation> <translation id="5456381639095306749">Download siden</translation> <translation id="548278423535722844">Åbn i kortapp</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb index ea0a3ef..0c8f87a 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_de.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Melden Sie sich an und aktivieren Sie die Synchronisierung, um Ihre Tabs von Ihren anderen Geräten abzurufen</translation> <translation id="3587482841069643663">Alle</translation> <translation id="3587596251841506391">Dabei helfen, das Web sicherer zu machen</translation> -<translation id="3590487821116122040">Websitespeicher, den Chrome nicht für wichtig hält, wie etwa Websites ohne gespeicherte Einstellungen oder solche, die nicht oft besucht werden</translation> <translation id="3594780231884063836">Video stummschalten</translation> <translation id="3599863153486145794">Löscht den Verlauf auf allen angemeldeten Geräten. Unter <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> sind möglicherweise weitere Arten von Browserverlaufsdaten für Ihr Google-Konto gespeichert.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Link kopieren</translation> <translation id="3988213473815854515">Standort freigegeben</translation> <translation id="3988466920954086464">Instant-Suchergebnisse in diesem Feld ansehen</translation> -<translation id="3997476611815694295">Speicher für unwichtige Websites</translation> <translation id="4000212216660919741">Offline-Startseite</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Nutzername kopiert</translation> <translation id="543509235395288790"><ph name="COUNT" /> Dateien (<ph name="MEGABYTES" /> MB) werden heruntergeladen.</translation> <translation id="5441522332038954058">Zur Adressleiste wechseln</translation> -<translation id="5447201525962359567">Gesamter Websitespeicher einschließlich Cookies und anderer lokal gespeicherter Daten</translation> <translation id="545042621069398927">Download wird beschleunigt.</translation> <translation id="5456381639095306749">Seite herunterladen</translation> <translation id="548278423535722844">In einer Karten-App öffnen</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb index 3a83473..4cb144b 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_el.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">Για να εμφανίζονται οι καρτέλες σας από τις άλλες συσκευές σας, συνδεθείτε και ενεργοποιήστε τον συγχρονισμό</translation> <translation id="3587482841069643663">Όλες</translation> <translation id="3587596251841506391">Συμβάλ. στη βελτίωση της ασφάλ.</translation> -<translation id="3590487821116122040">Αποθηκευτικός χώρος ιστοτόπων που το Chrome θεωρεί ότι δεν είναι σημαντικός (π.χ. ιστότοποι χωρίς αποθηκευμένες ρυθμίσεις ή που δεν επισκέπτεστε συχνά)</translation> <translation id="3594780231884063836">Σίγαση βίντεο</translation> <translation id="3599863153486145794">Διαγράφει το ιστορικό από όλες τις συνδεδεμένες συσκευές. Ο Λογαριασμός σας Google ενδέχεται να διαθέτει άλλες μορφές ιστορικού περιήγησης στη διεύθυνση <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Ήχος</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">Αντ. συνδ.</translation> <translation id="3988213473815854515">Η τοποθεσία επιτρέπεται</translation> <translation id="3988466920954086464">Προβολή αποτελεσμάτων αναζήτησης Instant σε αυτό το πλαίσιο</translation> -<translation id="3997476611815694295">Ασήμαντος αποθηκευτικός χώρος</translation> <translation id="4000212216660919741">Η αρχική σελίδα είναι εκτός σύνδεσης</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ω.}other{# ω.}}</translation> <translation id="4056223980640387499">Σέπια</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">Το όνομα χρήστη αντιγράφηκε</translation> <translation id="543509235395288790">Λήψη <ph name="COUNT" /> αρχείων (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Μετάβαση στη γραμμή διευθύνσεων</translation> -<translation id="5447201525962359567">Όλος ο αποθηκευτικός χώρος ιστοτόπων, συμπεριλαμβανομένων των cookie και άλλων τοπικά αποθηκευμένων δεδομένων</translation> <translation id="545042621069398927">Επιτάχυνση της λήψης σας.</translation> <translation id="5456381639095306749">Λήψη σελίδας</translation> <translation id="548278423535722844">Άνοιγμα σε εφαρμογή χαρτών</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb index 289b63f1..e2e8fe94 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">To get your tabs from your other devices, sign in and turn on sync</translation> <translation id="3587482841069643663">All</translation> <translation id="3587596251841506391">Help improve security on the web</translation> -<translation id="3590487821116122040">Site storage Chrome doesn't think is important (e.g. sites with no saved settings or that you don't visit often)</translation> <translation id="3594780231884063836">Mute video</translation> <translation id="3599863153486145794">Clears history from all signed-in devices. Your Google Account may have other forms of browsing history at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">Copy link</translation> <translation id="3988213473815854515">Location is allowed</translation> <translation id="3988466920954086464">See instant search results in this panel</translation> -<translation id="3997476611815694295">Unimportant storage</translation> <translation id="4000212216660919741">Offline Home</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# hr}other{# hrs}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">Username copied</translation> <translation id="543509235395288790">Downloading <ph name="COUNT" /> files (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Jump to the address bar</translation> -<translation id="5447201525962359567">All site storage, including cookies and other locally stored data</translation> <translation id="545042621069398927">Speeding up your download.</translation> <translation id="5456381639095306749">Download page</translation> <translation id="548278423535722844">Open in maps app</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb index 56ab9fc2..690c8f1 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es-419.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Para obtener las pestañas de tus otros dispositivos, accede a tu cuenta y activa la sincronización</translation> <translation id="3587482841069643663">Todos</translation> <translation id="3587596251841506391">Ayuda a mejorar la seguridad en la Web</translation> -<translation id="3590487821116122040">Almacenamiento de sitios que Chrome no considera importantes (por ejemplo, sitios que no visitas a menudo o sin configuración guardada)</translation> <translation id="3594780231884063836">Silenciar video</translation> <translation id="3599863153486145794">Borra el historial de todos los dispositivos en los que accediste. Es posible que tu cuenta de Google tenga otros tipos de historial de navegación en <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Copiar vínculo</translation> <translation id="3988213473815854515">Se admite la ubicación.</translation> <translation id="3988466920954086464">Los resultados de la búsqueda instantánea se muestran en este panel</translation> -<translation id="3997476611815694295">Almacenamiento no importante</translation> <translation id="4000212216660919741">Página principal sin conexión</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Se copió el nombre de usuario</translation> <translation id="543509235395288790">Descargando <ph name="COUNT" /> archivos (<ph name="MEGABYTES" />)</translation> <translation id="5441522332038954058">Ir a la barra de direcciones</translation> -<translation id="5447201525962359567">Todo el almacenamiento de sitios, lo que incluye cookies y otros datos almacenados de forma local</translation> <translation id="545042621069398927">Acelerando la descarga</translation> <translation id="5456381639095306749">Descargar página</translation> <translation id="548278423535722844">Abrir en una app de mapas</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb index 7a14fbf..fe19772 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Inicia sesión y activa la sincronización para ver las pestañas de tus otros dispositivos</translation> <translation id="3587482841069643663">Todo</translation> <translation id="3587596251841506391">Ayudar a mejorar la seguridad en la Web</translation> -<translation id="3590487821116122040">Almacenamiento del sitio web que Chrome no considera importante (p. ej., los sitios web sin configuración guardada o aquellos que no visitas a menudo)</translation> <translation id="3594780231884063836">Silenciar vídeo</translation> <translation id="3599863153486145794">Borra el historial de todos los dispositivos en los que hayas iniciado sesión. Es posible que tu cuenta de Google tenga otros tipos de historial de navegación en <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Copiar enlace</translation> <translation id="3988213473815854515">Se permite la ubicación</translation> <translation id="3988466920954086464">Ver resultados de búsqueda instantánea en este panel</translation> -<translation id="3997476611815694295">Almacenamiento no importante</translation> <translation id="4000212216660919741">Página principal del modo sin conexión</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Se ha copiado el nombre de usuario</translation> <translation id="543509235395288790">Descargando <ph name="COUNT" /> archivos (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Te dirige a la barra de direcciones</translation> -<translation id="5447201525962359567">Todo el almacenamiento del sitio web, como las cookies y otros datos almacenados de forma local</translation> <translation id="545042621069398927">Acelerando descarga.</translation> <translation id="5456381639095306749">Descargar página</translation> <translation id="548278423535722844">Abrirla en una aplicación de mapas</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb index 34c81cd7..b7f1c5e 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Oma teistest seadmetest vahelehtede hankimiseks logige sisse ja lülitage sünkroonimine sisse</translation> <translation id="3587482841069643663">Kõik</translation> <translation id="3587596251841506391">Aidake veebi turvalisemaks muuta</translation> -<translation id="3590487821116122040">Saitide salvestusruum, mida Chrome peab ebatähtsaks (nt saidid, mida külastate harva või millel ei ole salvestatud seadeid)</translation> <translation id="3594780231884063836">Video vaigistamine</translation> <translation id="3599863153486145794">Kustutab ajaloo kõigist sisselogitud seadmetest. Aadressil <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> võib teie Google'i kontol olla muus vormis sirvimisajalugu.</translation> <translation id="3616113530831147358">Heli</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kop. link</translation> <translation id="3988213473815854515">Asukoht on lubatud</translation> <translation id="3988466920954086464">Vaadake kiirotsingu tulemusi sellel paneelil</translation> -<translation id="3997476611815694295">Ebatähtis salvestusruum</translation> <translation id="4000212216660919741">Võrguühenduseta avaleht</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4056223980640387499">Seepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Kasutajanimi on kopeeritud</translation> <translation id="543509235395288790"><ph name="COUNT" /> faili allalaadimine (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Aadressiribale liikumine</translation> -<translation id="5447201525962359567">Saidi kogu salvestusruum, sh küpsised ja muud kohalikus seadmes talletatud andmed</translation> <translation id="545042621069398927">Allalaadimise kiirendamine.</translation> <translation id="5456381639095306749">Laadi leht alla</translation> <translation id="548278423535722844">Avage kaardirakenduses</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb index 4212a326..b5edf129 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_eu.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Beste gailuetako fitxak eskura izateko, hasi saioa eta aktibatu sinkronizazioa</translation> <translation id="3587482841069643663">Guztiak</translation> <translation id="3587596251841506391">Hobetu sareko segurtasuna</translation> -<translation id="3590487821116122040">Chrome-k garrantzi gabekotzat jotako webguneen datuak (hala nola ezarpenik gordeta ez duten webguneenak edo maiz bisitatzen ez dituzun webguneenak)</translation> <translation id="3594780231884063836">Desaktibatu bideoaren audioa</translation> <translation id="3599863153486145794">Saioa hasita daukaten gailu guztietako historia garbitzen du. Google-ko kontuko historia arakatzeko beste modu batzuk aurki zenitzake <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> webgunean.</translation> <translation id="3616113530831147358">Audioa</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopiatu esteka</translation> <translation id="3988213473815854515">Kokapena baimenduta dago</translation> <translation id="3988466920954086464">Ikusi istanteko bilaketaren emaitzak panel honetan</translation> -<translation id="3997476611815694295">Garrantzirik gabeko datuak</translation> <translation id="4000212216660919741">Etxea konexiorik gabeko moduan dago</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ordu}other{# ordu}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Kopiatu da erabiltzaile-izena</translation> <translation id="543509235395288790"><ph name="COUNT" /> fitxategi deskargatzen (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Saltatu helbide-barrara</translation> -<translation id="5447201525962359567">Webguneen datu guztiak, cookieak eta gailuan gordetako beste datu batzuk barne</translation> <translation id="545042621069398927">Deskarga bizkortzen.</translation> <translation id="5456381639095306749">Deskargatu orria</translation> <translation id="548278423535722844">Ireki mapa-aplikazio batean</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb index 7a78a8f0..401a34e 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">برای اینکه به برگههای بازشده در سایر دستگاهها دسترسی داشته باشید، به سیستم وارد شوید و همگامسازی را روشن کنید</translation> <translation id="3587482841069643663">همه</translation> <translation id="3587596251841506391">به بهبود امنیت وب کمک کنید</translation> -<translation id="3590487821116122040">فضای ذخیرهسازی سایت که از نظر Chrome مهم نیست (مثلاً سایتهایی که تنظیمات ذخیرهشده ندارند یا شما مرتب بازدید نمیکنید)</translation> <translation id="3594780231884063836">بیصدا کردن ویدیو</translation> <translation id="3599863153486145794">سابقه را از همه دستگاههای به سیستم واردشده پاک میکند. ممکن است حساب Google شما اشکال دیگری از سابقه مرور در <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> داشته باشد.</translation> <translation id="3616113530831147358">صوتی</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">کپی پیوند</translation> <translation id="3988213473815854515">مکان مجاز است</translation> <translation id="3988466920954086464">نتایج جستجوی فوری را در این پانل مشاهده کنید</translation> -<translation id="3997476611815694295">فضای ذخیره غیرمهم</translation> <translation id="4000212216660919741">صفحه اصلیِ آفلاین</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ساعت}one{# ساعت}other{# ساعت}}</translation> <translation id="4056223980640387499">سپیا</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">نام کاربری کپی شد</translation> <translation id="543509235395288790">درحال بارگیری <ph name="COUNT" /> فایل (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">رفتن به نوار نشانی</translation> -<translation id="5447201525962359567">همه فضای ذخیره سایتها، ازجمله کوکیها و سایر دادههای ذخیرهشده در دستگاه</translation> <translation id="545042621069398927">درحال سرعت بخشیدن به بارگیری.</translation> <translation id="5456381639095306749">بارگیری صفحه</translation> <translation id="548278423535722844">باز کردن در برنامه Maps</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb index 56daa004..df4d40c8 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fi.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Kirjaudu sisään ja ota synkronointi käyttöön, niin voit käyttää välilehtiä muilta laitteiltasi</translation> <translation id="3587482841069643663">Kaikki</translation> <translation id="3587596251841506391">Paranna verkon turvallisuutta</translation> -<translation id="3590487821116122040">Tallennetut sivustotiedot, joita Chrome ei pidä tärkeinä (esim. sivustot, joilla ei ole tallennettuja asetuksia tai joilla et käy usein).</translation> <translation id="3594780231884063836">Mykistä video</translation> <translation id="3599863153486145794">Tyhjentää kaikkien sisäänkirjautuneiden laitteiden historian. Google-tililläsi voi olla muuta toimintaa osoitteessa <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Ääni</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopioi linkki</translation> <translation id="3988213473815854515">Sijainnin käyttö on sallittu.</translation> <translation id="3988466920954086464">Näytä Instant-hakutulokset tässä paneelissa</translation> -<translation id="3997476611815694295">Vähemmän tärkeät tiedot</translation> <translation id="4000212216660919741">Offline-etusivu</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4056223980640387499">Seepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Käyttäjänimi kopioitu</translation> <translation id="543509235395288790">Ladataan <ph name="COUNT" /> tiedostoa (<ph name="MEGABYTES" />)</translation> <translation id="5441522332038954058">Siirry osoitepalkkiin</translation> -<translation id="5447201525962359567">Kaikki tallennetut sivustotiedot, mukaan lukien evästeet ja muut paikallisesti tallennetut tiedot</translation> <translation id="545042621069398927">Lataustasi nopeutetaan</translation> <translation id="5456381639095306749">Lataa sivu</translation> <translation id="548278423535722844">Avaa karttasovelluksessa</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb index bdf4cd7..76753b7 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fil.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Para makuha ang iyong mga tab sa iba mo pang device, mag-sign in at i-on ang pag-sync</translation> <translation id="3587482841069643663">Lahat</translation> <translation id="3587596251841506391">Pahusayin ang seguridad sa web</translation> -<translation id="3590487821116122040">Storage ng site na sa tingin ng Chrome ay hindi mahalaga (hal. mga site na walang mga naka-save na setting o hindi mo madalas bisitahin)</translation> <translation id="3594780231884063836">I-mute ang video</translation> <translation id="3599863153486145794">Kini-clear ang history sa lahat ng naka-sign in na device. Maaaring may iba pang anyo ng history ng pag-browse ang iyong Google Account sa <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopyahin ang link</translation> <translation id="3988213473815854515">Pinapahintulutan ang lokasyon</translation> <translation id="3988466920954086464">Tingnan ang mga instant na resulta ng paghahanap sa panel na ito</translation> -<translation id="3997476611815694295">Storage ng hindi mahalaga</translation> <translation id="4000212216660919741">Offline Home</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# oras}one{# oras}other{# na oras}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Nakopya ang username</translation> <translation id="543509235395288790">Nagda-download ng <ph name="COUNT" /> (na) file (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Pumunta sa address bar</translation> -<translation id="5447201525962359567">Lahat ng storage ng site, kabilang ang cookies at iba pang lokal na naka-store na data</translation> <translation id="545042621069398927">Pinapabilis ang iyong pag-download.</translation> <translation id="5456381639095306749">I-download ang page</translation> <translation id="548278423535722844">Buksan sa app na mga mapa</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb index 17527689..55fbe8e 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr-CA.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Pour synchroniser vos onglets sur vos autres appareils, connectez-vous et activez la synchronisation</translation> <translation id="3587482841069643663">Tous</translation> <translation id="3587596251841506391">Contribuer à la sécurité sur le Web</translation> -<translation id="3590487821116122040">Le stockage des sites que Chrome ne considère pas comme importants (comme les sites qui n'ont pas de paramètres enregistrés ou que vous ne consultez pas souvent)</translation> <translation id="3594780231884063836">Désactiver le son de la vidéo</translation> <translation id="3599863153486145794">Efface l'historique de tous les appareils connectés. D'autres formes d'historique de navigation peuvent exister sur votre compte Google à l'adresse <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Copier lien</translation> <translation id="3988213473815854515">L'emplacement est autorisé</translation> <translation id="3988466920954086464">Affichez les résultats de recherche instantanée dans ce volet</translation> -<translation id="3997476611815694295">Stockage non important</translation> <translation id="4000212216660919741">Accueil hors ligne</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}one{# h}other{# h}}</translation> <translation id="4056223980640387499">Sépia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Nom d'utilisateur copié</translation> <translation id="543509235395288790">Téléchargement de <ph name="COUNT" /> fichiers (<ph name="MEGABYTES" />) en cours…</translation> <translation id="5441522332038954058">Accéder à la barre d'adresse</translation> -<translation id="5447201525962359567">Le stockage des sites, y compris les témoins et d'autres données stockées localement</translation> <translation id="545042621069398927">Accélération de votre téléchargement en cours…</translation> <translation id="5456381639095306749">Télécharger la page</translation> <translation id="548278423535722844">Ouvrir dans l'application Maps</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb index 9d8a034..32e61c2 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_fr.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Connectez-vous et activez la synchronisation pour accéder à vos onglets sur vos autres appareils</translation> <translation id="3587482841069643663">Tous</translation> <translation id="3587596251841506391">Contribuer à sécuriser le Web</translation> -<translation id="3590487821116122040">Données de site stockées que Chrome ne considère pas comme importantes (par exemple, pour des sites sans paramètres enregistrés ou que vous ne consultez pas souvent)</translation> <translation id="3594780231884063836">Couper le son de la vidéo</translation> <translation id="3599863153486145794">Efface l'historique de tous les appareils sur lesquels vous êtes connecté à votre compte Google. Ce dernier peut conserver d'autres formes d'historique de navigation sur la page <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Copier lien</translation> <translation id="3988213473815854515">Position autorisée</translation> <translation id="3988466920954086464">Consultez les résultats de la recherche instantanée dans ce panneau</translation> -<translation id="3997476611815694295">Stockage non important</translation> <translation id="4000212216660919741">Mode hors connexion</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}one{# h}other{# h}}</translation> <translation id="4056223980640387499">Sépia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Nom d'utilisateur copié</translation> <translation id="543509235395288790">Téléchargement de <ph name="COUNT" /> fichiers (<ph name="MEGABYTES" />)…</translation> <translation id="5441522332038954058">Accéder à la barre d'adresse</translation> -<translation id="5447201525962359567">Toutes les données de site stockées, y compris les cookies et d'autres données stockées en local</translation> <translation id="545042621069398927">Accélération du téléchargement…</translation> <translation id="5456381639095306749">Télécharger la page</translation> <translation id="548278423535722844">Ouvrir dans une application de plans</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb index 1ecde3f5..8c6530c 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gl.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Inicia sesión e activa a sincronización para sincronizar as pestanas dos demais dispositivos</translation> <translation id="3587482841069643663">Todos</translation> <translation id="3587596251841506391">Axudar a mellorar a seguranza na Web</translation> -<translation id="3590487821116122040">Datos de almacenamento do sitio que Chrome non considera importantes (por exemplo, de sitios sen configuración gardada ou que non visitas a miúdo)</translation> <translation id="3594780231884063836">Silenciar o vídeo</translation> <translation id="3599863153486145794">Borra o historial de todos os dispositivos que teñen a sesión iniciada. É posible que a túa conta de Google teña outras formas do historial de navegación en <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Copiar ligazón</translation> <translation id="3988213473815854515">A localización está permitida</translation> <translation id="3988466920954086464">Consulta os resultados da busca instantáneos neste panel</translation> -<translation id="3997476611815694295">Datos non importantes</translation> <translation id="4000212216660919741">Inicio sen conexión</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Copiouse o nome de usuario</translation> <translation id="543509235395288790">Descargando <ph name="COUNT" /> ficheiros (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Saltar á barra de enderezos</translation> -<translation id="5447201525962359567">Todos os datos dos sitios, incluídas as cookies e outros datos almacenados localmente</translation> <translation id="545042621069398927">Estase acelerando a descarga.</translation> <translation id="5456381639095306749">Descargar páxina</translation> <translation id="548278423535722844">Abrir na aplicación de mapas</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb index ef2e893..af0f52e 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">તમારા અન્ય ઉપકરણો પરથી તમારા ટૅબ મેળવવા માટે, સાઇન ઇન કરો અને સિંક કરવાનું ચાલુ કરો.</translation> <translation id="3587482841069643663">બધા</translation> <translation id="3587596251841506391">વેબ પર સુરક્ષા સુધારવા સહાય કરો</translation> -<translation id="3590487821116122040">Chrome ને મહત્વનું ન લાગતું સાઇટ સ્ટોરેજ (ઉદા., કોઇ સાચવેલ સેટિંગ્સ ન હોય તેવી અથવા વારંવાર મુલાકાત ન લેવાતી હોય તેવી સાઇટ્સ)</translation> <translation id="3594780231884063836">વીડિયોને મ્યૂટ કરો</translation> <translation id="3599863153486145794">બધા સાઇન ઇન કરેલ ડિવાઇસમાંથી ઇતિહાસ સાફ કરે છે. તમારા Google એકાઉન્ટમાં <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> પર બ્રાઉઝિંગ ઇતિહાસના બીજા સ્વરૂપો હોય શકે.</translation> <translation id="3616113530831147358">ઑડિઓ</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">લિંક કૉપિ કરો</translation> <translation id="3988213473815854515">સ્થાન માન્ય છે</translation> <translation id="3988466920954086464">ઝટપટ શોધ પરિણામો આ પૅનલમાં જુઓ</translation> -<translation id="3997476611815694295">બિનમહત્વપૂર્ણ સ્ટોરેજ</translation> <translation id="4000212216660919741">ઑફલાઇન હોમ</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# કલાક}one{# કલાક}other{# કલાક}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">વપરાશકર્તાનામ કૉપિ કર્યું</translation> <translation id="543509235395288790"><ph name="COUNT" /> ફાઇલ (<ph name="MEGABYTES" />) ડાઉનલોડ કરી રહ્યાં છીએ.</translation> <translation id="5441522332038954058">સરનામાં બાર પર જાઓ</translation> -<translation id="5447201525962359567">કુકીઝ અને અન્ય સ્થાનિક રીતે સંગ્રહિત કરેલ ડેટા સહિત, બધું સાઇટ સ્ટોરેજ</translation> <translation id="545042621069398927">તમારા ડાઉનલોડની ગતિ વધારી રહ્યાં છીએ.</translation> <translation id="5456381639095306749">પૃષ્ઠ ડાઉનલોડ કરો</translation> <translation id="548278423535722844">નકશા અૅપ્લિકેશનમાં ખોલો</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb index 835d133b..43e698bc 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hi.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">अपने दूसरे डिवाइस से अपने टैब पाने के लिए, साइन इन करें और 'सिंक करें' को चालू करें</translation> <translation id="3587482841069643663">सभी</translation> <translation id="3587596251841506391">वेब पर सुरक्षा बेहतर करने में मदद करें</translation> -<translation id="3590487821116122040">ऐसी 'साइट मेमोरी' जो Chrome के हिसाब से ज़रूरी नहीं है (जैसे कि ऐसी साइट जिनमें कोई भी सेटिंग नहीं सेव की गई है या जिन पर आप अक्सर नहीं जाते हैं)</translation> <translation id="3594780231884063836">वीडियो म्यूट करें</translation> <translation id="3599863153486145794">साइन इन किए हुए सभी डिवाइसों से इतिहास साफ़ कर देता है. आपके Google खाते में <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> पर अन्य प्रकार के ब्राउज़िंग इतिहास हो सकते हैं.</translation> <translation id="3616113530831147358">ऑडियो</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">लिंक की प्रति बनाएं</translation> <translation id="3988213473815854515">स्थान अनुमत है</translation> <translation id="3988466920954086464">झटपट खोज नतीजे इस पैनल में देखें</translation> -<translation id="3997476611815694295">महत्वहीन मेमोरी</translation> <translation id="4000212216660919741">ऑफ़लाइन होम</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# घंटा}one{# घंटे}other{# घंटे}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">उपयोगकर्ता नाम कॉपी किया गया</translation> <translation id="543509235395288790"><ph name="COUNT" /> फ़ाइलें डाउनलोड हो रही हैं (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">सीधे पता बार पर जाएं</translation> -<translation id="5447201525962359567">सभी साइट मेमोरी, जिसमें कुकी और स्थानीय रूप से संग्रहित अन्य डेटा शामिल है</translation> <translation id="545042621069398927">आपके डाउनलोड की गति बढ़ाई जा रही है.</translation> <translation id="5456381639095306749">पेज डाउनलोड करें</translation> <translation id="548278423535722844">मैप ऐप्लिकेशन में खोलें</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb index 18f3711a..0d57dd6 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hr.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">Da bi se prikazale kartice s vaših ostalih uređaja, prijavite se i uključite sinkronizaciju</translation> <translation id="3587482841069643663">Sve</translation> <translation id="3587596251841506391">Za bolju sigurnost na webu</translation> -<translation id="3590487821116122040">Pohrana web-lokacije koju Chrome ne smatra važnom (primjerice web-lokacije koje nemaju spremljene postavke ili koje ne posjećujete često)</translation> <translation id="3594780231884063836">Isključi kameru</translation> <translation id="3599863153486145794">Briše povijest na svim uređajima na kojima ste prijavljeni. Na vašem Google računu možda postoje drugi oblici povijesti pregledavanja na stranici <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">Kopiraj vezu</translation> <translation id="3988213473815854515">Lokacija je dopuštena</translation> <translation id="3988466920954086464">Na ovoj ploči pogledajte instant rezultate pretraživanja</translation> -<translation id="3997476611815694295">Nevažna pohrana</translation> <translation id="4000212216660919741">Početna stranica offline</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}one{# h}few{# h}other{# h}}</translation> <translation id="4056223980640387499">Sepija</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">Korisničko je ime kopirano</translation> <translation id="543509235395288790">Preuzimanje ovoliko datoteka: <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Preskakanje na adresnu traku</translation> -<translation id="5447201525962359567">Cijela pohrana web-lokacije, uključujući kolačiće i druge lokalno pohranjene podatke</translation> <translation id="545042621069398927">Ubrzavanje preuzimanja.</translation> <translation id="5456381639095306749">Preuzmi stranicu</translation> <translation id="548278423535722844">Otvori u aplikaciji za karte</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb index a145aba2..9b8e276b 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hu.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Ha a többi eszközén is szeretné elérni lapjait, jelentkezzen be, és kapcsolja be a szinkronizálást</translation> <translation id="3587482841069643663">Mind</translation> <translation id="3587596251841506391">Legyen biztonságos a böngészés</translation> -<translation id="3590487821116122040">A Chrome által nem fontosnak ítélt webhelytárhely (például a mentett beállítások nélküli vagy ritkán megnyitott webhelyek)</translation> <translation id="3594780231884063836">Videó némítása</translation> <translation id="3599863153486145794">Törli az előzményeket valamennyi bejelentkezett eszközről. Előfordulhat, hogy a böngészési előzmények más formái még megtalálhatók Google-fiókjában a <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> webhelyen.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Link másolása</translation> <translation id="3988213473815854515">Hely engedélyezve</translation> <translation id="3988466920954086464">Azonnali keresési találatok megtekintése ezen a panelen</translation> -<translation id="3997476611815694295">Nem fontos tárhely</translation> <translation id="4000212216660919741">Offline kezdőlap</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# órája}other{# órája}}</translation> <translation id="4056223980640387499">Szépia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Felhasználónév vágólapra másolva</translation> <translation id="543509235395288790"><ph name="COUNT" /> fájl letöltése folyamatban (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Ugrás a címsávba</translation> -<translation id="5447201525962359567">Összes webhelytárhely, beleértve a cookie-kat és más helyben tárolt adatokat</translation> <translation id="545042621069398927">Letöltés felgyorsítása…</translation> <translation id="5456381639095306749">Oldal letöltése</translation> <translation id="548278423535722844">Megnyitás térképalkalmazásban</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb index a301e8f..9ef73e1 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Ձեր մյուս սարքերում եղած ներդիրներն օգտագործելու համար մտեք հաշիվ և միացրեք համաժամացումը</translation> <translation id="3587482841069643663">Բոլորը</translation> <translation id="3587596251841506391">Օգնեք բարելավել անվտանգությունը</translation> -<translation id="3590487821116122040">Ըստ Chrome-ի ոչ կարևոր կայքերի տվյալներ (օր.` առանց պահված կարգավորումների կայքերը կամ այն կայքերը, որոնք վաղուց չեք այցելել)</translation> <translation id="3594780231884063836">Անջատել տեսանյութի ձայնը</translation> <translation id="3599863153486145794">Մաքրում է պատմությունը բոլոր սարքերից, որոնցում մուտք եք գործել։ Ձեր Google հաշվում կարող են լինել այցելությունների պատմության այլ ձևեր ևս: Դրանք կարող եք գտնել <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> էջում։</translation> <translation id="3616113530831147358">Աուդիո</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Պատճենել հղումը</translation> <translation id="3988213473815854515">Տեղադրության որոշումը թույլատրված է</translation> <translation id="3988466920954086464">Որոնման արդյունքներն ակնթարթորեն կհայտնվեն այս վահանակում</translation> -<translation id="3997476611815694295">Անկարևոր տվյալներ</translation> <translation id="4000212216660919741">Home անցանց ռեժիմում</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ժամ}one{# ժամ}other{# ժամ}}</translation> <translation id="4056223980640387499">Սեպիա</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Օգտանունը պատճենվեց</translation> <translation id="543509235395288790">Ներբեռնվում է <ph name="COUNT" /> ֆայլ (<ph name="MEGABYTES" />)։</translation> <translation id="5441522332038954058">Անցնել հասցեագոտի</translation> -<translation id="5447201525962359567">Կայքերի բոլոր տվյալները, ներառյալ` քուքիները և սարքում պահված մյուս տվյալները</translation> <translation id="545042621069398927">Ներբեռնումն արագացվում է։</translation> <translation id="5456381639095306749">Ներբեռնել էջը</translation> <translation id="548278423535722844">Բացեք Քարտեզներ հավելվածում</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb index 63d211d8..d019a02e 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_id.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Untuk membuka tab dari perangkat Anda yang lain, login dan aktifkan sinkronisasi</translation> <translation id="3587482841069643663">Semua</translation> <translation id="3587596251841506391">Bantu sempurnakan keamanan di web</translation> -<translation id="3590487821116122040">Penyimpanan situs yang dianggap tidak penting oleh Chrome (misalnya situs yang tidak memiliki setelan penyimpanan atau situs yang tidak sering Anda kunjungi)</translation> <translation id="3594780231884063836">Bisukan video</translation> <translation id="3599863153486145794">Menghapus histori dari semua perangkat yang dibuat login. Akun Google Anda mungkin memiliki bentuk histori penjelajahan lainnya di <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Salin link</translation> <translation id="3988213473815854515">Lokasi diaktifkan</translation> <translation id="3988466920954086464">Lihat hasil penelusuran instan di panel ini</translation> -<translation id="3997476611815694295">Penyimpanan tidak penting</translation> <translation id="4000212216660919741">Beranda Offline</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# jam}other{# jam}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Nama pengguna disalin</translation> <translation id="543509235395288790">Mendownload <ph name="COUNT" /> file (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Beralih ke bilah alamat</translation> -<translation id="5447201525962359567">Semua penyimpanan situs, termasuk cookie dan data lain yang tersimpan secara lokal</translation> <translation id="545042621069398927">Mempercepat download.</translation> <translation id="5456381639095306749">Download halaman</translation> <translation id="548278423535722844">Buka di aplikasi peta</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb index c1ffaad..73c2d986 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_is.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Skráðu þig inn og kveiktu á samstillingu til að fá aðgang að flipunum þínum í öðrum tækjum</translation> <translation id="3587482841069643663">Allar</translation> <translation id="3587596251841506391">Hjálpaðu við að bæta netöryggi</translation> -<translation id="3590487821116122040">Geymsla vefsvæða sem Chrome telur ekki mikilvæg (t.d. vefsvæði með engar vistaðar stillingar eða sem þú heimsækir sjaldan)</translation> <translation id="3594780231884063836">Slökkva á mynd</translation> <translation id="3599863153486145794">Hreinsar ferilinn úr öllum innskráðum tækjum. Google reikningurinn þinn kann að vera með annars konar vefskoðunarferil á <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Hljóð</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Afrita tengil</translation> <translation id="3988213473815854515">Staðsetning er leyfð</translation> <translation id="3988466920954086464">Sjá niðurstöður flýtileitar á þessu svæði</translation> -<translation id="3997476611815694295">Geymsla fyrir lítilvæg atriði</translation> <translation id="4000212216660919741">Ónettengt</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# klst.}one{# klst.}other{# klst.}}</translation> <translation id="4056223980640387499">Brúnn blær</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Notandanafn afritað</translation> <translation id="543509235395288790">Sækir <ph name="COUNT" /> skrár (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Stökkva í veffangastikuna</translation> -<translation id="5447201525962359567">Öll geymsla vefsvæða, þ.m.t. fótspor og önnur gögn vistuð staðbundið</translation> <translation id="545042621069398927">Flýtir fyrir niðurhali.</translation> <translation id="5456381639095306749">Sækja síðu</translation> <translation id="548278423535722844">Opna í kortaforriti</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb index c375869..71410f1 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Accedi e attiva la sincronizzazione per trovare le tue schede degli altri dispositivi</translation> <translation id="3587482841069643663">Tutti</translation> <translation id="3587596251841506391">Aumenta la sicurezza sul Web</translation> -<translation id="3590487821116122040">Memoria utilizzata da siti che Chrome non ritiene importanti (ad esempio siti senza impostazioni salvate o che non visiti spesso)</translation> <translation id="3594780231884063836">Disattiva audio video</translation> <translation id="3599863153486145794">Consente di cancellare la cronologia da tutti i dispositivi su cui hai eseguito l'accesso. Il tuo Account Google potrebbe avere altri tipi di cronologia di navigazione all'indirizzo <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Copia link</translation> <translation id="3988213473815854515">La geolocalizzazione è consentita</translation> <translation id="3988466920954086464">Visualizza i risultati della ricerca immediata in questo riquadro</translation> -<translation id="3997476611815694295">Memoria dati non importanti</translation> <translation id="4000212216660919741">Home page offline</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ora}other{# ore}}</translation> <translation id="4056223980640387499">Seppia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Nome utente copiato</translation> <translation id="543509235395288790">Download di <ph name="COUNT" /> file (<ph name="MEGABYTES" />) in corso.</translation> <translation id="5441522332038954058">Vai alla barra degli indirizzi</translation> -<translation id="5447201525962359567">Tutta la memoria utilizzata da siti, tra cui cookie e altri dati memorizzati in locale</translation> <translation id="545042621069398927">Accelerazione del download in corso.</translation> <translation id="5456381639095306749">Scarica la pagina</translation> <translation id="548278423535722844">Apri nell'app di mappe</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb index 20b13ef5..8b11f30 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_iw.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">כדי לקבל את הכרטיסיות מהמכשירים האחרים שלך, יש להיכנס לחשבון ולהפעיל את הסנכרון</translation> <translation id="3587482841069643663">הכל</translation> <translation id="3587596251841506391">סיוע לשיפור האבטחה באינטרנט</translation> -<translation id="3590487821116122040">נתוני אתר מאוחסנים ש-Chrome לא מחשיב כחשובים (לדוגמה, אתרים ללא הגדרות שמורות או כאלה שאינך מבקר בהם לעתים קרובות)</translation> <translation id="3594780231884063836">השתקת הסרטון</translation> <translation id="3599863153486145794">ניקוי ההיסטוריה מכל המכשירים שבהם המשתמש נכנס לחשבון. ייתכן שלחשבון Google שלך יהיו צורות אחרות של היסטוריית גלישה בכתובת <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">אודיו</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">העתק קישור</translation> <translation id="3988213473815854515">ניתנה הרשאת מיקום</translation> <translation id="3988466920954086464">בחלונית הזו אפשר לראות תוצאות חיפוש מיידי</translation> -<translation id="3997476611815694295">נתונים מאוחסנים לא חשובים</translation> <translation id="4000212216660919741">דף הבית במצב לא מקוון</translation> <translation id="4034817413553209278">{HOURS,plural, =1{שעה אחת}two{שעתיים}many{# שעות}other{# שעות}}</translation> <translation id="4056223980640387499">חום-ספיה</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">שם המשתמש הועתק</translation> <translation id="543509235395288790">מתבצעת הורדה של <ph name="COUNT" /> קבצים (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">מעבר לשורת כתובת האתר</translation> -<translation id="5447201525962359567">כל נתוני האתר המאוחסנים, כולל קובצי Cookie ונתונים אחרים המאוחסנים באופן מקומי</translation> <translation id="545042621069398927">הדפדפן מאיץ את ההורדה.</translation> <translation id="5456381639095306749">הורד דף זה</translation> <translation id="548278423535722844">פתח יישום מפות</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb index 1349637b..79e8ca7 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">他のデバイスと同じタブを使用するには、ログインして同期を有効にします</translation> <translation id="3587482841069643663">すべて</translation> <translation id="3587596251841506391">ウェブ上のセキュリティ強化に協力する</translation> -<translation id="3590487821116122040">Chrome で重要度が低いと判断されるサイトのストレージ(設定を保存していないサイトやアクセス頻度の少ないサイトなど)</translation> <translation id="3594780231884063836">動画をミュート</translation> <translation id="3599863153486145794">ログインしているすべてのデバイスの履歴を削除します。お使いの Google アカウントの <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> に、他の形式の閲覧履歴が記録されている場合があります。</translation> <translation id="3616113530831147358">音声</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">リンクのコピー</translation> <translation id="3988213473815854515">位置情報は許可</translation> <translation id="3988466920954086464">このパネルにインスタント検索の結果が表示されます</translation> -<translation id="3997476611815694295">重要度の低いストレージ</translation> <translation id="4000212216660919741">オフライン ホーム</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# 時間}other{# 時間}}</translation> <translation id="4056223980640387499">セピア</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">ユーザー名がコピーされました</translation> <translation id="543509235395288790"><ph name="COUNT" /> 件のファイルをダウンロードしています(<ph name="MEGABYTES" />)。</translation> <translation id="5441522332038954058">アドレスバーに移動する</translation> -<translation id="5447201525962359567">すべてのサイトのストレージ(Cookie やローカルに保存した他のデータを含む)</translation> <translation id="545042621069398927">ダウンロード速度が向上しました。</translation> <translation id="5456381639095306749">ページをダウンロード</translation> <translation id="548278423535722844">マップアプリで開く</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb index 422821b..6403d301 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ka.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">თქვენს სხვა მოწყობილობაზე არსებულ ჩანართებზე წვდომისთვის შედით სისტემაში და ჩართეთ სინქრონიზაცია</translation> <translation id="3587482841069643663">ყველა</translation> <translation id="3587596251841506391">გააუმჯობესეთ ვების უსაფრთხოება</translation> -<translation id="3590487821116122040">საიტების მეხსიერება, რომელსაც Chrome უმნიშვნელოდ თვლის (მაგ.: საიტები შენახული პარამეტრების გარეშე ან რომლებსაც ხშირად არ სტუმრობთ)</translation> <translation id="3594780231884063836">ვიდეოს დადუმება</translation> <translation id="3599863153486145794">გაასუფთავებს ისტორიას სისტემაში შესული ყველა მოწყობილობიდან. თქვენს Google ანგარიშში შეიძლება ინახებოდეს სხვა ტიპის დათვალიერების ისტორიაც, რომელიც ხელმისაწვდომია მისამართზე: <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">აუდიო</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">ბმულის კოპირება</translation> <translation id="3988213473815854515">მდებარეობა დაშვებულია</translation> <translation id="3988466920954086464">ძიების მყისიერი შედეგები ამ პანელზე გამოჩნდება</translation> -<translation id="3997476611815694295">უმნიშვნელო მეხსიერება</translation> <translation id="4000212216660919741">ხაზგარეშე მთავარი გვერდი</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# სთ}other{# სთ}}</translation> <translation id="4056223980640387499">სეპია</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">მომხმარებლის სახელი დაკოპირდა</translation> <translation id="543509235395288790">მიმდინარეობს <ph name="COUNT" /> ფაილის ჩამოტვირთვა (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">მისამართთა ზოლზე გადასვლა</translation> -<translation id="5447201525962359567">საიტების მეხსიერება, რომელიც შეიცავს ქუქი-ჩანაწერებს და სხვა ადგილობრივად შენახულ მონაცემებს</translation> <translation id="545042621069398927">მიმდინარეობს ჩამოტვირთვის აჩქარება.</translation> <translation id="5456381639095306749">გვერდის ჩამოტვირთვა</translation> <translation id="548278423535722844">რუკების აპში გახსნა</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb index 87da44fd..108b1f0 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kk.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Қойындыларды барлық құрылғылардан пайдалану үшін есептік жазбаға кіріп, синхрондау функциясын қосыңыз</translation> <translation id="3587482841069643663">Барлығы</translation> <translation id="3587596251841506391">Интернет қауіпсіздігін күшейту</translation> -<translation id="3590487821116122040">Маңызды деп саналмайтын сайт деректері (мысалы, параметрлері сақталмаған немесе сіз жиі кірмейтін сайттар)</translation> <translation id="3594780231884063836">Бейненің дыбысын өшіру</translation> <translation id="3599863153486145794">Барлық жүйеге кірген құрылғылардан тарихты өшіреді.<ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> мекенжайында Google есептік жазбасымен шолу тарихының басқа да үлгілері болуы мүмкін.</translation> <translation id="3616113530831147358">Аудио</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Сілтемені көшіру</translation> <translation id="3988213473815854515">Орналасқан жерді анықтауға рұқсат бар</translation> <translation id="3988466920954086464">Осы панельде жедел іздеу нәтижелерін көру</translation> -<translation id="3997476611815694295">Маңызды емес деректер</translation> <translation id="4000212216660919741">Негізгі экран офлайн режимде</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# сағ}other{# сағ}}</translation> <translation id="4056223980640387499">Сепия</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Пайдаланушының аты көшірілді</translation> <translation id="543509235395288790"><ph name="COUNT" /> файл (<ph name="MEGABYTES" />) жүктеп алынуда.</translation> <translation id="5441522332038954058">Мекенжай жолағына өту</translation> -<translation id="5447201525962359567">Барлық сақталған сайт деректері, соның ішінде cookie файлдары және басқа жергілікті сақталған деректер</translation> <translation id="545042621069398927">Жылдамырақ жүктеп алынуда.</translation> <translation id="5456381639095306749">Жүктеп алу беті</translation> <translation id="548278423535722844">Maps қолданбасында ашу</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb index 7fc8f97..f8da84c91 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_km.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">ដើម្បីទទួលបានផ្ទាំងរបស់អ្នកពីឧបករណ៍ផ្សេងទៀតរបស់អ្នក សូមចូលគណនី និងបើកសមកាលកម្ម</translation> <translation id="3587482841069643663">ទាំងអស់</translation> <translation id="3587596251841506391">ជួយពង្រឹងសុវត្ថិភាពនៅលើអ៊ីនធឺណិត</translation> -<translation id="3590487821116122040">ទំហំផ្ទុកគេហទំព័រដែល Chrome គិតថាមិនសំខាន់ (ឧ៖ គេហទំព័រដែលគ្មានការកំណត់ដែលបានរក្សាទុក ឬគេហទំព័រដែលអ្នកមិនសូវចូលទៅកាន់ញឹកញាប់)</translation> <translation id="3594780231884063836">បិទសំឡេងវីដេអូ</translation> <translation id="3599863153486145794">សម្អាតប្រវត្តិពីឧបករណ៍ទាំងអស់ដែលបានចូលគណនី។ គណនី Google របស់អ្នកអាចនឹងមានទម្រង់ប្រវត្តិរុករកផ្សេងទៀតនៅ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> ។</translation> <translation id="3616113530831147358">សម្លេង</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">ចម្លងតំណ</translation> <translation id="3988213473815854515">ទីតាំងត្រូវបានអនុញ្ញាត</translation> <translation id="3988466920954086464">មើលលទ្ធផលស្វែងរកភ្លាមៗនៅក្នុងផ្ទាំងនេះ</translation> -<translation id="3997476611815694295">ទំហំផ្ទុកមិនសំខាន់</translation> <translation id="4000212216660919741">Home គ្មានអ៊ីនធឺណិតទេ</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ម៉ោង}other{# ម៉ោង}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">បានចម្លងឈ្មោះអ្នកប្រើប្រាស់</translation> <translation id="543509235395288790">កំពុងទាញយកឯកសារ <ph name="COUNT" /> (<ph name="MEGABYTES" />)។</translation> <translation id="5441522332038954058">លោតទៅរបារអាសយដ្ឋាន</translation> -<translation id="5447201525962359567">ទំហំផ្ទុកគេហទំព័រទាំងអស់ ដោយរាប់បញ្ចូលទាំងខុកឃី និងទិន្នន័យផ្សេងទៀតដែលបានផ្ទុកជាមូលដ្ឋាន</translation> <translation id="545042621069398927">កំពុងបង្កើនល្បឿននៃការទាញយករបស់អ្នក។</translation> <translation id="5456381639095306749">ទាញយកទំព័រ</translation> <translation id="548278423535722844">បើកនៅក្នុងកម្មវិធីផែនទី</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb index 3a4c3a0..116c065 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_kn.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">ನಿಮ್ಮ ಇತರ ಸಾಧನಗಳಿಂದ ನಿಮ್ಮ ಟ್ಯಾಬ್ಗಳನ್ನು ಪಡೆದುಕೊಳ್ಳಲು, ಸೈನ್ ಇನ್ ಮಾಡಿ ಮತ್ತು ಸಿಂಕ್ ಆನ್ ಮಾಡಿ</translation> <translation id="3587482841069643663">ಎಲ್ಲ</translation> <translation id="3587596251841506391">ವೆಬ್ ಸುರಕ್ಷತೆ ಸುಧಾರಿಸಲು ಸಹಕರಿಸಿ</translation> -<translation id="3590487821116122040">ಪ್ರಮುಖವಲ್ಲವೆಂದು Chrome ಭಾವಿಸುವ ಸೈಟ್ ಸಂಗ್ರಹಣೆ (ಉದಾ. ಯಾವುದೇ ಉಳಿಸದ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಹೊಂದಿರುವ ಅಥವಾ ನೀವು ಆಗಾಗ್ಗೆ ಭೇಟಿ ನೀಡದ ಸೈಟ್ಗಳು)</translation> <translation id="3594780231884063836">ವೀಡಿಯೊ ಮ್ಯೂಟ್ ಮಾಡಿ</translation> <translation id="3599863153486145794">ಸೈನ್-ಇನ್ ಮಾಡಿರುವ ಎಲ್ಲ ಸಾಧನಗಳಿಂದ ಇತಿಹಾಸವನ್ನು ತೆರವುಗೊಳಿಸುತ್ತದೆ. ನಿಮ್ಮ Google ಖಾತೆಯು <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> ನಲ್ಲಿ ಇತರ ವಿಧಗಳ ಬ್ರೌಸಿಂಗ್ ಇತಿಹಾಸವನ್ನು ಹೊಂದಿರಬಹುದು.</translation> <translation id="3616113530831147358">ಆಡಿಯೋ</translation> @@ -385,7 +384,6 @@ <translation id="3987993985790029246">ಲಿಂಕ್ ನಕಲಿಸಿ</translation> <translation id="3988213473815854515">ಸ್ಥಳವನ್ನು ಅನುಮತಿಸಲಾಗಿದೆ</translation> <translation id="3988466920954086464">ಈ ಫಲಕದಲ್ಲಿ ತತ್ಕ್ಷಣ ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳನ್ನು ನೋಡಿ</translation> -<translation id="3997476611815694295">ಪ್ರಮುಖವಲ್ಲದ ಸಂಗ್ರಹಣೆ</translation> <translation id="4000212216660919741">ಆಫ್ಲೈನ್ ಹೋಮ್</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ಗಂಟೆ}one{# ಗಂಟೆಗಳು}other{# ಗಂಟೆಗಳು}}</translation> <translation id="4056223980640387499">ಸೆಪಿಯಾ</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">ಬಳಕೆದಾರರ ಹೆಸರನ್ನು ನಕಲಿಸಲಾಗಿದೆ</translation> <translation id="543509235395288790"><ph name="COUNT" /> ಫೈಲ್ಗಳನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">ವಿಳಾಸ ಪಟ್ಟಿಗೆ ಹೋಗಿ</translation> -<translation id="5447201525962359567">ಕುಕೀಗಳು ಮತ್ತು ಇತರ ಸ್ಥಳೀಯವಾಗಿ ಸಂಗ್ರಹಿಸಿದ ಡೇಟಾ ಒಳಗೊಂಡು ಎಲ್ಲಾ ಸೈಟ್ ಸಂಗ್ರಹಣೆ</translation> <translation id="545042621069398927">ನಿಮ್ಮ ಡೌನ್ಲೋಡ್ನ ವೇಗವನ್ನು ಹೆಚ್ಚಿಸಲಾಗುತ್ತಿದೆ.</translation> <translation id="5456381639095306749">ಪುಟ ಡೌನ್ಲೋಡ್ ಮಾಡಿ</translation> <translation id="548278423535722844">ನಕ್ಷೆಗಳ ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿ ತೆರೆಯಿರಿ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb index ae47381..66f0909 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ko.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">다른 기기에서 탭을 가져오려면 로그인하고 동기화를 사용 설정하세요.</translation> <translation id="3587482841069643663">전체</translation> <translation id="3587596251841506391">웹 보안 개선에 참여</translation> -<translation id="3590487821116122040">Chrome에서 중요하다고 간주하지 않는 사이트 저장공간(예: 저장된 설정이 없거나 사용자가 자주 방문하지 않는 사이트)</translation> <translation id="3594780231884063836">동영상 음소거</translation> <translation id="3599863153486145794">로그인된 모든 기기에서 방문 기록을 지웁니다. Google 계정의 내 활동(<ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />)에는 인터넷 사용 기록이 다른 형식으로 남아 있을 수도 있습니다.</translation> <translation id="3616113530831147358">오디오</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">링크 복사</translation> <translation id="3988213473815854515">위치 허용됨</translation> <translation id="3988466920954086464">이 패널에서 순간 검색결과 보기</translation> -<translation id="3997476611815694295">중요하지 않은 저장공간</translation> <translation id="4000212216660919741">오프라인 홈</translation> <translation id="4034817413553209278">{HOURS,plural, =1{#시간}other{#시간}}</translation> <translation id="4056223980640387499">세피아</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">사용자 이름 복사됨</translation> <translation id="543509235395288790">파일 <ph name="COUNT" />개(<ph name="MEGABYTES" />) 다운로드 중</translation> <translation id="5441522332038954058">검색주소창으로 이동</translation> -<translation id="5447201525962359567">쿠키 및 기타 로컬에 저장된 데이터 등 모든 사이트 저장공간</translation> <translation id="545042621069398927">다운로드 속도 향상</translation> <translation id="5456381639095306749">다운로드 페이지</translation> <translation id="548278423535722844">지도 앱에서 열기</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb index 486e0409..ff24557 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Өтмөктөрүңүздү башка түзмөктөрүңүздөн алуу үчүн аккаунтуңузга кирип, шайкештирүүнү күйгүзүңүз</translation> <translation id="3587482841069643663">Баары</translation> <translation id="3587596251841506391">Интернеттеги коопсуздукту жакшыртууга жардам бериңиз</translation> -<translation id="3590487821116122040">Анча маанилүү болбогон сайттардын дайындары (мис., жөндөөлөрү сакталбаган же сиз көп кирбеген сайттар)</translation> <translation id="3594780231884063836">Видеонун үнүн басуу</translation> <translation id="3599863153486145794">Аккаунтка кирген бардык түзмөктөрүңүздөгү таржымал тазаланат. Google аккаунтуңуздун серептөө таржымалынын башка түрлөрү <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> дарегинде болушу мүмкүн.</translation> <translation id="3616113530831147358">Аудио</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Шилтм көчр</translation> <translation id="3988213473815854515">Жайгашкан жер дайындарына уруксат берилген</translation> <translation id="3988466920954086464">Ыкчам издөө жыйынтыктарын ушул панелде көрүү</translation> -<translation id="3997476611815694295">Маанилүү эмес дайындар</translation> <translation id="4000212216660919741">Үйдө оффлайн режиминде</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# саат}other{# саат}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Колдонуучунун аты көчүрүлдү</translation> <translation id="543509235395288790"><ph name="COUNT" /> файл жүктөлүп алынууда (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Дарек тилкесине секирүү</translation> -<translation id="5447201525962359567">Бардык сайттардын дайындары, анын ичинде кукилер жана башка жергиликтүү сакталган дайындар</translation> <translation id="545042621069398927">Файл ылдам жүктөлүп алынууда.</translation> <translation id="5456381639095306749">Баракты жүктөп алуу</translation> <translation id="548278423535722844">Карталар колдонмосунан ачыңыз</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb index 421f373..5833297 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lo.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">ເພື່ອໂຫຼດແຖບຂອງທ່ານຈາກອຸປະກອນອື່ນ, ກະລຸນາເປີດການຊິ້ງຂໍ້ມູນກ່ອນ</translation> <translation id="3587482841069643663">ທັງໝົດ</translation> <translation id="3587596251841506391">ຊ່ວຍປັບປຸງຄວາມປອດໄພໃນເວັັບ</translation> -<translation id="3590487821116122040">ບ່ອນເກັບຂໍ້ມູນເວັບໄຊທີ່ Chrome ຄິດວ່າບໍ່ສຳຄັນ (ເຊັ່ນ ເວັບໄຊທີ່ບໍ່ມີການຕັ້ງຄ່າທີ່ບັນທຶກໄວ້ ຫຼື ທີ່ທ່ານບໍ່ຄ່ອຍເຂົ້າເບິ່ງ)</translation> <translation id="3594780231884063836">ປິດສຽງວິດີໂອ</translation> <translation id="3599863153486145794">ລຶບລ້າງປະຫວັດຈາກທຸກອຸປະກອນທີ່ເຂົ້າສູ່ລະບົບແລ້ວ. ບັນຊີ Google ຂອງທ່ານອາດຈະມີຮູບແບບອື່ນຂອງປະຫວັດການທ່ອງເວັບຢູ່ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">ສຽງ</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">ອັດສຳເນົາລິ້ງເຊື່ອມໂຍງ</translation> <translation id="3988213473815854515">ທີ່ຕັ້ງໄດ້ຮັບອະນຸຍາດແລ້ວ</translation> <translation id="3988466920954086464">ເບິ່ງຜົນການຊອກຫາທັນທີໃນແຜງນີ້</translation> -<translation id="3997476611815694295">ບ່ອນເກັບຂໍ້ມູນທີ່ບໍ່ສຳຄັນ</translation> <translation id="4000212216660919741">ໜ້າຫຼັກອອບລາຍຢູ່</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ຊົ່ວໂມງ}other{# ຊົ່ວໂມງ}}</translation> <translation id="4056223980640387499">ສີນໍ້າຕານດໍາ</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">ສຳເນົາຊື່ຜູ້ໃຊ້ແລ້ວ</translation> <translation id="543509235395288790">ກຳລັງດາວໂຫຼດ <ph name="COUNT" /> ໄຟລ໌ (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">ໂດດໄປຫາແຖບທີ່ຢູ່</translation> -<translation id="5447201525962359567">ທຸກບ່ອນເກັບຂໍ້ມູນຂອງເວັບໄຊ ລວມທັງຄຸກກີ້ ແລະ ຂໍ້ມູນອື່ນທີ່ເກັບໄວ້ພາຍໃນເຄື່ອງ</translation> <translation id="545042621069398927">ກຳລັງເພີ່ມຄວາມໄວໃຫ້ການດາວໂຫຼດຂອງທ່ານ.</translation> <translation id="5456381639095306749">ໜ້າການດາວໂຫຼດ</translation> <translation id="548278423535722844">ເປີດໃນແອັບແຜນທີ່</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb index dcaf562..f7793e2 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lt.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">Jei norite pasiekti skirtukus iš kitų įrenginių, prisijunkite ir įjunkite sinchronizavimą</translation> <translation id="3587482841069643663">Visi</translation> <translation id="3587596251841506391">Padėti gerinti saugą žiniatinkl.</translation> -<translation id="3590487821116122040">Svetainės saugykla, kurios „Chrome“ nelaiko svarbia (pvz., svetainės be išsaugotų nustatymų arba tos, kuriose retai lankotės)</translation> <translation id="3594780231884063836">Nutildyti vaizdo įrašą</translation> <translation id="3599863153486145794">Išvaloma visų įrenginių, prie kurių prisijungta, istorija. „Google“ paskyroje gali būti kito tipo naršymo istorijos, kuri pasiekiama adresu <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Garsas</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">Kop. nuor.</translation> <translation id="3988213473815854515">Vietovės informacija leidžiama</translation> <translation id="3988466920954086464">Žiūrėkite tiesioginius paieškos rezultatus šiame skydelyje</translation> -<translation id="3997476611815694295">Nesvarbi saugykla</translation> <translation id="4000212216660919741">„Home“ neprisijungus</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# val.}one{# val.}few{# val.}many{# val.}other{# val.}}</translation> <translation id="4056223980640387499">Sepija</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">Naudotojo vardas nukopijuotas</translation> <translation id="543509235395288790">Atsisiunčiami failai: <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Pereiti prie adreso juostos</translation> -<translation id="5447201525962359567">Visa svetainės saugykla, įskaitant slapukus ir kitus vietoje saugomus duomenis</translation> <translation id="545042621069398927">Paspartinamas atsisiuntimas.</translation> <translation id="5456381639095306749">Atsisiųsti puslapį</translation> <translation id="548278423535722844">Atidaryti Žemėlapių programoje</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb index eb8db3f..40c312f 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_lv.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Lai varētu piekļūt cilnēm no citām ierīcēm, pierakstieties un ieslēdziet sinhronizāciju.</translation> <translation id="3587482841069643663">Visi</translation> <translation id="3587596251841506391">Palīdzēt uzlabot drošību tīmeklī</translation> -<translation id="3590487821116122040">Vietnes krātuve, kura pārlūkā Chrome netiek uzskatīta par svarīgu (piemēram, vietnes bez saglabātiem iestatījumiem vai vietnes, kuras neapmeklējat bieži)</translation> <translation id="3594780231884063836">Izslēgt video skaņu</translation> <translation id="3599863153486145794">Notīra vēsturi no visām ierīcēm, kurās esat pierakstījies. Jūsu Google kontam vietnē <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> var būt citu veidu pārlūkošanas vēstures dati.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Saites kopēšana</translation> <translation id="3988213473815854515">Atļauta piekļuve atrašanās vietas informācijai</translation> <translation id="3988466920954086464">Skatīt tūlītējus meklēšanas rezultātus šajā panelī</translation> -<translation id="3997476611815694295">Nesvarīga krātuve</translation> <translation id="4000212216660919741">Bezsaistes sākums</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}zero{# h}one{# h}other{# h}}</translation> <translation id="4056223980640387499">Sēpija</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Lietotājvārds ir nokopēts.</translation> <translation id="543509235395288790">Notiek <ph name="COUNT" /> faila(-u) lejupielāde (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Pāriet uz adreses joslu</translation> -<translation id="5447201525962359567">Visa vietnes krātuve, tostarp sīkfaili un citi lokāli saglabāti dati</translation> <translation id="545042621069398927">Lejupielāde tiek paātrināta.</translation> <translation id="5456381639095306749">Lejupielādēt lapu</translation> <translation id="548278423535722844">Atvērt karšu lietotnē</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb index 8b1e959b..d55dbb20 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">За да ги добиете вашите картички од другите уреди, најавете се и вклучете ја синхронизацијата</translation> <translation id="3587482841069643663">Сите</translation> <translation id="3587596251841506391">Подобра безбедноста на интернет</translation> -<translation id="3590487821116122040">Достапен простор на сајтот за кој Chrome смета дека не е важен (на пр., сајтови без зачувани поставки или коишто не ги посетувате често)</translation> <translation id="3594780231884063836">Исклучете звук на видео</translation> <translation id="3599863153486145794">Ја чисти историјата од сите најавени уреди. Вашата сметка на Google можеби има други видови историја на прелистување на <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Аудио</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">Копирај линк</translation> <translation id="3988213473815854515">Локацијата е дозволена</translation> <translation id="3988466920954086464">Гледајте инстант резултати од пребарување на таблава</translation> -<translation id="3997476611815694295">Неважен простор</translation> <translation id="4000212216660919741">Офлајн</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ч.}one{# ч.}other{# ч.}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">Корисничкото име е копирано</translation> <translation id="543509235395288790">Се преземаат <ph name="COUNT" /> датотеки (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Скокнете на лентата за адреса</translation> -<translation id="5447201525962359567">Целиот простор на сајтот, вклучувајќи ги колачињата и другите локално зачувани податоци</translation> <translation id="545042621069398927">Го забрзуваме вашето преземање.</translation> <translation id="5456381639095306749">Преземете ја страницата</translation> <translation id="548278423535722844">Отвори во апликацијата „Карти“</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb index 3a77583..2ca52b2 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ml.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">നിങ്ങളുടെ മറ്റ് ഉപകരണങ്ങളിൽ നിന്നുള്ള ടാബുകൾ ലഭിക്കാൻ, സൈൻ ഇൻ ചെയ്ത് സമന്വയിപ്പിക്കൽ ഓണാക്കുക</translation> <translation id="3587482841069643663">എല്ലാം</translation> <translation id="3587596251841506391">വെബിലെ സുരക്ഷ മെച്ചപ്പെടുത്താൻ സഹായിക്കുക</translation> -<translation id="3590487821116122040">Chrome, സൈറ്റ് സ്റ്റോറേജിനെ പ്രധാനപ്പെട്ടതായി കണക്കാക്കുന്നില്ല (ഉദാ: ക്രമീകരണം സംരക്ഷിച്ചിട്ടില്ലാത്തതോ നിങ്ങൾ ഇടയ്ക്കിടെ സന്ദർശിക്കാത്തതോ ആയ സൈറ്റുകൾ)</translation> <translation id="3594780231884063836">വീഡിയോ മ്യൂട്ട് ചെയ്യുക</translation> <translation id="3599863153486145794">സൈൻ ഇൻ ചെയ്ത എല്ലാ ഉപകരണങ്ങളിൽ നിന്നും ചരിത്രം മായ്ക്കുന്നു. നിങ്ങളുടെ Google അക്കൗണ്ടിന് <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> എന്നതിൽ മറ്റ് തരത്തിലുള്ള ബ്രൗസിംഗ് ചരിത്രങ്ങളുണ്ടായിരിക്കാം.</translation> <translation id="3616113530831147358">ഓഡിയോ</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">ലിങ്ക് പകർത്തുക</translation> <translation id="3988213473815854515">ലൊക്കേഷൻ അനുവദനീയം</translation> <translation id="3988466920954086464">വേഗത്തിലുള്ള തിരയൽ ഫലങ്ങൾ ഈ പാനലിൽ കാണുക</translation> -<translation id="3997476611815694295">പ്രധാനമല്ലാത്ത സ്റ്റോറേജ്</translation> <translation id="4000212216660919741">ഓഫ്ലൈൻ ഹോം</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# മണിക്കൂർ}other{# മണിക്കൂർ}}</translation> <translation id="4056223980640387499">സിപിയ</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">ഉപയോക്തൃനാമം പകർത്തി</translation> <translation id="543509235395288790"><ph name="COUNT" /> ഫയലുകൾ ഡൗൺലോഡ് ചെയ്യുന്നു (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">വിലാസ ബാറിലേക്ക് പോകുക</translation> -<translation id="5447201525962359567">കുക്കികളും പ്രാദേശികമായി സംഭരിച്ച മറ്റ് വിവരങ്ങളും ഉൾപ്പെടെയുള്ള എല്ലാ സൈറ്റ് സ്റ്റോറേജും</translation> <translation id="545042621069398927">നിങ്ങളുടെ ഡൗൺലോഡ് വേഗത്തിലാക്കുന്നു.</translation> <translation id="5456381639095306749">പേജ് ഡൗൺലോഡ് ചെയ്യുക</translation> <translation id="548278423535722844">മാപ്സ് ആപ്പിൽ തുറക്കുക</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb index fc153a9b..6178508 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mn.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Бусад төхөөрөмжөөсөө чихтэй хуудсаа авахын тулд нэвтрээд синкийг асаана уу`</translation> <translation id="3587482841069643663">Бүгд</translation> <translation id="3587596251841506391">Вэб дэх аюулгүй байдлыг сайжруулахад туслах</translation> -<translation id="3590487821116122040">Chrome-н чухал гэж тооцдоггүй сайтын сан (жишээ нь: тохиргоог нь хадгалаагүй, эсвэл таны тогтмол зочилдоггүй сайт)</translation> <translation id="3594780231884063836">Видеоны дууг хаах</translation> <translation id="3599863153486145794">Бүх нэвтэрсэн төхөөрөмжийн түүхийг устгана. Таны Google бүртгэл <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />-д хайлтын түүхийн өөр хэлбэртэй байж болзошгүй.</translation> <translation id="3616113530831147358">Аудио</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Холбоосыг хуулах</translation> <translation id="3988213473815854515">Байршил мэдээлэхийг зөвшөөрсөн</translation> <translation id="3988466920954086464">Шуурхай хайлтын илэрцийг энэ самбарт харах</translation> -<translation id="3997476611815694295">Чухал биш сан</translation> <translation id="4000212216660919741">Офлайн нүүр</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# цаг}other{# цаг}}</translation> <translation id="4056223980640387499">Сепиа</translation> @@ -561,7 +559,6 @@ <translation id="5433691172869980887">Хэрэглэгчийн нэрийг хуулсан</translation> <translation id="543509235395288790"><ph name="COUNT" /> файлыг татаж байна (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Хаяг оруулах хэсэгт очих</translation> -<translation id="5447201525962359567">Күүки болон бусад дотоодод хадгалсан өгөгдлийг оруулсан бүх сайтын сан</translation> <translation id="545042621069398927">Таны таталтыг хурдасгаж байна.</translation> <translation id="5456381639095306749">Хуудсыг татах</translation> <translation id="548278423535722844">Газрын зургийн апп-д нээх</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb index 584cdc7..6b3b9e8b 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mr.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">तुमच्या इतर डिव्हाइसवरून तुमचे टॅब मिळविण्यासाठी, साइन इन करा आणि सिंक सुरू करा</translation> <translation id="3587482841069643663">सर्व</translation> <translation id="3587596251841506391">वेबवरील सुरक्षेमध्ये सुधारणा करण्यात मदत करा</translation> -<translation id="3590487821116122040">Chrome साइट स्टोरेज यास महत्त्व देत नाही (उदा. ज्या साइटमध्ये सेटिंग्ज सेव्ह केलेल्या नसतात किंवा तुम्ही सहसा भेट देत नाही अशा साइट)</translation> <translation id="3594780231884063836">व्हिडिओ म्यूट करा</translation> <translation id="3599863153486145794">साइन-इन केलेल्या सर्व डिव्हाइसमधून इतिहास साफ करते. तुमच्या Google खात्यामध्ये <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> वर कदाचित ब्राउझिंगचे इतर फॉर्म असतील.</translation> <translation id="3616113530831147358">ऑडिओ</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">लिंक कॉपी करा</translation> <translation id="3988213473815854515">स्थानास अनुमती आहे</translation> <translation id="3988466920954086464">या पॅनलमध्ये इंस्टंट शोध परिणाम पहा</translation> -<translation id="3997476611815694295">महत्त्वाचा नसलेले स्टोरेज</translation> <translation id="4000212216660919741">ऑफलाइन होम</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# तास}other{# तास}}</translation> <translation id="4056223980640387499">सेपिया</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">वापरकर्तानाव कॉपी केले</translation> <translation id="543509235395288790">(<ph name="MEGABYTES" />) च्या <ph name="COUNT" /> फाइल डाउनलोड करत आहे.</translation> <translation id="5441522332038954058">अॅड्रेस बारवर जा</translation> -<translation id="5447201525962359567">कुकीज आणि इतर स्थानिकरित्या स्टोरेज डेटासह, सर्व साइट स्टोरेज</translation> <translation id="545042621069398927">तुमच्या डाउनलोडचा वेग वाढवत आहे.</translation> <translation id="5456381639095306749">पेज डाउनलोड करा</translation> <translation id="548278423535722844">नकाशे ॲपमध्ये उघडा</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb index 2992f95..fe6d8e54 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ms.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Log masuk dan hidupkan penyegerakan untuk mendapatkan tab daripada peranti anda yang lain</translation> <translation id="3587482841069643663">Semua</translation> <translation id="3587596251841506391">Tingkatkan keselamatan pada web</translation> -<translation id="3590487821116122040">Storan tapak yang Chrome anggap tidak penting (misalnya tapak yang tiada tetapan yang disimpan atau yang jarang anda lawati)</translation> <translation id="3594780231884063836">Redam video</translation> <translation id="3599863153486145794">Mengosongkan sejarah daripada semua peranti yang dilog masuk. Akaun Google anda mungkin mempunyai sejarah penyemakan imbas dalam bentuk lain di <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Salin pautan</translation> <translation id="3988213473815854515">Lokasi dibenarkan</translation> <translation id="3988466920954086464">Lihat hasil carian segera dalam panel ini</translation> -<translation id="3997476611815694295">Storan tidak penting</translation> <translation id="4000212216660919741">Rumah Luar Talian</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# jam}other{# jam}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Nama pengguna disalin</translation> <translation id="543509235395288790">Memuat turun <ph name="COUNT" /> fail (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Lompat ke bar alamat</translation> -<translation id="5447201525962359567">Semua storan tapak, termasuk kuki dan data lain yang disimpan setempat</translation> <translation id="545042621069398927">Mempercepatkan muat turun anda.</translation> <translation id="5456381639095306749">Muat turun halaman</translation> <translation id="548278423535722844">Buka dalam apl peta</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb index ed9853a..453fca79f 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_my.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">သင်၏ အခြားစက်ပစ္စည်းများမှ တဘ်များကိုအသုံးပြုရန် လက်မှတ်ထိုးဝင်ပြီး စင့်ခ်ကို ဖွင့်ပါ</translation> <translation id="3587482841069643663">အားလုံး</translation> <translation id="3587596251841506391">ဝဘ်တွင် လုံခြုံရေးကောင်းအောင် ကူညီပါ</translation> -<translation id="3590487821116122040">Chrome က အရေးကြီးသည်ဟု မယူဆသည့် ဆိုက်သိုလှောင်ခန်း (ဥပမာ၊ သိမ်းဆည်းထားသည့် ဆက်တင်များမရှိသော သို့မဟုတ် သင်သိပ်မကြည့်ဖြစ်သော ဆိုက်များ)</translation> <translation id="3594780231884063836">ဗီဒီယိုကို အသံပိတ်ရန်</translation> <translation id="3599863153486145794">လက်မှတ်ထိုးဝင်ထားသော စက်ပစ္စည်းအားလုံးထဲမှ မှတ်တမ်းများကို ဖျက်လိုက်ပါလိမ့်မည်။ သင့် Google အကောင့်က ဖွင့်ကြည့်ထားသောမှတ်တမ်းသည် <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> တွင် အခြားပုံစံများဖြင့် ရှိနေနိုင်ပါသည်။</translation> <translation id="3616113530831147358">အသံ</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">လင့်ခ်ကူးယူမည်</translation> <translation id="3988213473815854515">တည်နေရာအား ခွင့်ပြု၏</translation> <translation id="3988466920954086464">ဤအကန့်တွင် လက်ငင်းရှာဖွေမှု ရလဒ်များကို ကြည့်ရန်</translation> -<translation id="3997476611815694295">အရေးမကြီးသည့် သိုလှောင်ခန်း</translation> <translation id="4000212216660919741">အော့ဖ်လိုင်း ပင်မစာမျက်နှာ</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# နာရီ}other{# နာရီ}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -455,7 +453,7 @@ <translation id="4616150815774728855"><ph name="WEBAPK_NAME" /> ကို ဖွင့်ပါ</translation> <translation id="4634124774493850572">စကားဝှက်ကို အသုံးပြုရန်</translation> <translation id="4650364565596261010">စက်စနစ် မူရင်း</translation> -<translation id="465657074423018424">'လုံခြုံစွာ ဖွင့်ကြည့်ခြင်း' က သင့်ကို လှည့်ဖြားတတ်သော ဝဘ်ဆိုက်များမှ ကာကွယ်ပေးသည်။ ၎င်းကိုပိတ်လိုက်ပါက ဖွင့်ကြည့်ချိန်တွင် အထူးသဖြင့် စကားဝှက်မထည့်မီတွင် အလွန်ဂရုစိုက်ပါ။</translation> +<translation id="465657074423018424">'လုံခြုံစွာ ဖွင့်ကြည့်ခြင်း' က သင့်ကို လှည့်ဖြားတတ်သော ဝဘ်ဆိုက်များမှ ကာကွယ်ပေးသည်။ ၎င်းကိုပိတ်လိုက်ပါက ဖွင့်ကြည့်ချိန်တွင် အထူးသဖြင့် စကားဝှက်မထည့်မီတွင် အထူးဂရုစိုက်ပါ။</translation> <translation id="4662373422909645029">ကိန်းဂဏန်းများ မပါဝင်ရပါ</translation> <translation id="4663756553811254707"><ph name="NUMBER_OF_BOOKMARKS" /> စာညှပ် တွေ့ရှိပါသည်</translation> <translation id="4665282149850138822"><ph name="NAME" />ကို သင်၏ ပင်မ မျက်နှာပြင်သို့ ထည့်ပေးခဲ့သည်</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">အသုံးပြုသူအမည်ကို ကူးပြီးပါပြီ</translation> <translation id="543509235395288790">ဖိုင် <ph name="COUNT" /> ခုကို ဒေါင်းလုဒ်လုပ်နေသည် (<ph name="MEGABYTES" />)။</translation> <translation id="5441522332038954058">လိပ်စာဘားတန်းသို့ ပြန်သွားရန်</translation> -<translation id="5447201525962359567">ကွတ်ကီးများနှင့် စက်အတွင်းသိမ်းဆည်းထားသည့် အခြားဒေတာများအပါအဝင် ဆိုက်သိုလှောင်ခန်းအားလုံး</translation> <translation id="545042621069398927">သင်၏ ဒေါင်းလုဒ်ကို အရှိန်မြှင့်တင်ခြင်း။</translation> <translation id="5456381639095306749">ဒေါင်းလုဒ်စာမျက်နှာ</translation> <translation id="548278423535722844">မြေပုံအက်ပ်တွင် ဖွင့်ပါ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb index ad576fd..0d29598 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ne.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">आफ्ना अन्य यन्त्रहरूबाट आफ्ना ट्याबहरू प्राप्त गर्न साइन इन गरी सिंक गर्ने सुविधा सक्रिय गर्नुहोस्</translation> <translation id="3587482841069643663">सबै</translation> <translation id="3587596251841506391">वेब प्रयोग गर्ने सबै जनालाई सुरक्षित रहन मद्दत गर्नुहोस्</translation> -<translation id="3590487821116122040">साइटको Chrome लाई महत्वपूर्ण नलाग्ने भण्डारण (उदाहरणका लागि सुरक्षित गरिएका सेटिङहरू नभएका वा तपाईं प्रायजसो नजाने साइटहरू)</translation> <translation id="3594780231884063836">भिडियो म्युट गर्नुहोस्</translation> <translation id="3599863153486145794">साइन इन गरिएका सबै यन्त्रहरूबाट इतिहास खाली गर्दछ। तपाईंको Google खाताको <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> मा अन्य किसिमका ब्राउजिङ इतिहास रहेका हुन सक्छन्।</translation> <translation id="3616113530831147358">अडियो</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">लिंक प्रतिलिपि गर्नुहोस्</translation> <translation id="3988213473815854515">स्थानलाई अनुमति दिइएको छ</translation> <translation id="3988466920954086464">यस प्यानलमा खोजका तात्कालिक परिणामहरू हेर्नुहोस्</translation> -<translation id="3997476611815694295">अनावश्यक भण्डारण</translation> <translation id="4000212216660919741">अफलाइन गृहपृष्ठ</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# घन्टा}other{# घन्टा}}</translation> <translation id="4056223980640387499">सेपिया</translation> @@ -561,7 +559,6 @@ <translation id="5433691172869980887">प्रयोगकर्ताको नाम प्रतिलिपि गरियो</translation> <translation id="543509235395288790"><ph name="COUNT" /> फाइलहरू डाउनलोड गर्दै (<ph name="MEGABYTES" />)।</translation> <translation id="5441522332038954058">ठेगाना पट्टीमा जानुहोस्</translation> -<translation id="5447201525962359567">कुकी र अन्य स्थानीय रूपमा भण्डारण गरिएको डेटा सहित साइटको सबै भण्डारण</translation> <translation id="545042621069398927">तपाईंको डाउनलोडको गति बढाउँदै।</translation> <translation id="5456381639095306749">पृष्ठ डाउनलोड गर्नुहोस्</translation> <translation id="548278423535722844">नक्सा अनुप्रयोगमा खोल्नुहोस्</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb index e6f91d24..d8acf14 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_nl.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Log in en schakel synchronisatie in om de tabbladen van je andere apparaten te bekijken</translation> <translation id="3587482841069643663">Alles</translation> <translation id="3587596251841506391">Bijdragen aan veiliger internet</translation> -<translation id="3590487821116122040">Site-opslag waarvan Chrome denkt dat deze niet belangrijk is (bijvoorbeeld sites zonder opgeslagen instellingen of sites die je niet vaak bezoekt)</translation> <translation id="3594780231884063836">Video dempen</translation> <translation id="3599863153486145794">Hiermee wordt de geschiedenis van alle ingelogde apparaten gewist. Er kunnen andere vormen van browsegeschiedenis zijn opgeslagen voor je Google-account op <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Link kop.</translation> <translation id="3988213473815854515">Locatie is toegestaan</translation> <translation id="3988466920954086464">Instant-zoekresultaten weergeven in dit venster</translation> -<translation id="3997476611815694295">Onbelangrijke opslag</translation> <translation id="4000212216660919741">Homepage voor offline</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# uur}other{# uur}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Gebruikersnaam gekopieerd</translation> <translation id="543509235395288790"><ph name="COUNT" /> bestanden downloaden (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Naar de adresbalk gaan</translation> -<translation id="5447201525962359567">Alle site-opslag, inclusief cookies en andere lokaal opgeslagen gegevens</translation> <translation id="545042621069398927">Je download wordt versneld.</translation> <translation id="5456381639095306749">Pagina downloaden</translation> <translation id="548278423535722844">Openen in app voor passen</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb index af62234..eeaa2e1 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_no.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">For å få fanene dine fra de andre enhetene du bruker, logg på og slå på synkronisering.</translation> <translation id="3587482841069643663">Alle</translation> <translation id="3587596251841506391">Bidra til å gjøre nettet sikrere</translation> -<translation id="3590487821116122040">Nettstedslagring Chrome ikke tror er viktig (for eksempel områder uten lagrede innstillinger eller som du ikke besøker ofte)</translation> <translation id="3594780231884063836">Kutt lyden i videoen</translation> <translation id="3599863153486145794">Tømmer loggen på alle påloggede enheter. Det kan hende Google-kontoen din har andre typer nettleserlogger på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Lyd</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopiér link</translation> <translation id="3988213473815854515">Posisjon er tillatt</translation> <translation id="3988466920954086464">Se umiddelbare søkeresultater i dette panelet</translation> -<translation id="3997476611815694295">Uviktig lagring</translation> <translation id="4000212216660919741">Hjem uten nett</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# t}other{# t}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Brukernavnet er kopiert</translation> <translation id="543509235395288790">Laster ned <ph name="COUNT" /> filer (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Gå til adressefeltet</translation> -<translation id="5447201525962359567">All nettstedslagring, inkludert informasjonskapsler og andre lokalt lagrede data</translation> <translation id="545042621069398927">Øker hastigheten på nedlastingen.</translation> <translation id="5456381639095306749">Last ned siden</translation> <translation id="548278423535722844">Åpne i en kartapp</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb index 79415b7..f83ff70 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_or.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">ଆପଣଙ୍କର ଅନ୍ୟ ଡିଭାଇସ୍ଗୁଡ଼ିକରୁ ନିଜର ଟାବ୍ ପ୍ରାପ୍ତ କରିବା ପାଇଁ, ସାଇନ୍ ଇନ୍ କରି ସିଙ୍କ ଚାଲୁ କରନ୍ତୁ</translation> <translation id="3587482841069643663">ସମସ୍ତ</translation> <translation id="3587596251841506391">ୱେବରେ ସୁରକ୍ଷାକୁ ଉନ୍ନତ କରିବାରେ ସାହାଯ୍ୟ କରନ୍ତୁ</translation> -<translation id="3590487821116122040">Chromeକୁ ସାଇଟ୍ ସଂଗ୍ରହ ମହତ୍ବପୂର୍ଣ୍ଣ ଲାଗୁ ନାହିଁ (ଉ.ଦା. ସାଇଟ୍, ଯେଉଁଥିରେ କୌଣସି ସେଟିଂସ୍ ସେଭ୍ ନାହିଁ ବା ଯେଉଁ ସାଇଟ୍କୁ ଆପଣ ପ୍ରାୟତଃ ଯାଉନଥିବା)</translation> <translation id="3594780231884063836">ଭିଡିଓ ମ୍ୟୁଟ୍ କରନ୍ତୁ</translation> <translation id="3599863153486145794">ସମସ୍ତ ସାଇନ୍-ଇନ୍ ହୋଇଥିବା ଡିଭାଇସ୍ରୁ ଇତିବୃତ୍ତି ଖାଲି କରେ। ଆପଣଙ୍କ Google ଆକାଉଣ୍ଟର <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> ରେ ଅନ୍ୟ ପ୍ରକାରର ବ୍ରାଉଜିଂ ଇତିବୃତ୍ତି ଥାଇପାରେ।</translation> <translation id="3616113530831147358">ଅଡିଓ</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">ଲିଙ୍କ୍ କପି କରନ୍ତୁ</translation> <translation id="3988213473815854515">ଲୋକେସନ୍କୁ ଅନୁମତି ଦିଆଯାଇଛି</translation> <translation id="3988466920954086464">ଏହି ପ୍ୟାନେଲ୍ରେ ତତ୍କ୍ଷଣାତ୍ ସର୍ଚ୍ଚ ପରିଣାମ ଦେଖନ୍ତୁ</translation> -<translation id="3997476611815694295">ଗୁରୁତ୍ୱବିହୀନ ଷ୍ଟୋରେଜ୍</translation> <translation id="4000212216660919741">ଅଫ୍ଲାଇନ୍ ହୋମ୍</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ଘଣ୍ଟା}other{# ଘଣ୍ଟା}}</translation> <translation id="4056223980640387499">ସେପିଆ</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">ଉପଯୋଗକର୍ତ୍ତାଙ୍କର ନାମ କପି କରାଗଲା</translation> <translation id="543509235395288790"><ph name="COUNT" />ଟି ଫାଇଲ୍ (<ph name="MEGABYTES" />) ଡାଉନଲୋଡ୍ ହେଉଛି।</translation> <translation id="5441522332038954058">ଆଡ୍ରେସ୍ ବାର୍କୁ ଯାଆନ୍ତୁ</translation> -<translation id="5447201525962359567">କୁକୀ ଏବଂ ସ୍ଥାନୀୟ ଭାବେ ଷ୍ଟୋର୍ ହୋଇଥିବା ଅନ୍ୟ ଡାଟା ସହ, ସମସ୍ତ ସାଇଟ୍ ଷ୍ଟୋରେଜ୍</translation> <translation id="545042621069398927">ଆପଣଙ୍କ ଡାଇନ୍ଲୋଡ୍ର ଗତି ବଢ଼ାଯାଉଛି।</translation> <translation id="5456381639095306749">ପୃଷ୍ଠା ଡାଉନ୍ଲୋଡ୍ କରନ୍ତୁ</translation> <translation id="548278423535722844">ମ୍ୟାପ୍ସ ଆପ୍ରେ ଖୋଲନ୍ତୁ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb index e37a903..e507d0e 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pa.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">ਆਪਣੇ ਹੋਰ ਡੀਵਾਈਸਾਂ ਤੋਂ ਆਪਣੀਆਂ ਟੈਬਾਂ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ, ਸਾਈਨ-ਇਨ ਕਰਕੇ ਸਮਕਾਲੀਕਰਨ ਚਾਲੂ ਕਰੋ</translation> <translation id="3587482841069643663">ਸਾਰੇ</translation> <translation id="3587596251841506391">ਵੈੱਬ 'ਤੇ ਸੁਰੱਖਿਆ ਨੂੰ ਬਿਹਤਰ ਬਣਾਉਣ ਵਿੱਚ ਮਦਦ ਕਰੋ</translation> -<translation id="3590487821116122040">ਸਾਈਟ ਸਟੋਰੇਜ ਜੋ Chrome ਅਨੁਸਾਰ ਮਹੱਤਵਪੂਰਨ ਨਹੀਂ ਹੈ (ਜਿਵੇਂ ਕਿ ਉਹ ਸਾਈਟਾਂ ਜੋ ਸੈਟਿੰਗਾਂ ਰੱਖਿਅਤ ਨਹੀਂ ਕਰਦੀਆਂ ਜਾਂ ਉਹ ਸਾਈਟਾਂ ਜਿੰਨ੍ਹਾਂ 'ਤੇ ਤੁਸੀਂ ਅਕਸਰ ਨਹੀਂ ਜਾਂਦੇ ਹੋ)</translation> <translation id="3594780231884063836">ਵੀਡੀਓ ਮਿਊਟ ਕਰੋ</translation> <translation id="3599863153486145794">ਸਾਈਨ-ਇਨ ਕੀਤੇ ਸਾਰੇ ਡੀਵਾਈਸਾਂ ਤੋਂ ਇਤਿਹਾਸ ਕਲੀਅਰ ਕਰਦਾ ਹੈ। ਤੁਹਾਡੇ Google ਖਾਤੇ ਵਿੱਚ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> 'ਤੇ ਬ੍ਰਾਊਜ਼ਿੰਗ ਇਤਿਹਾਸ ਦੀਆਂ ਹੋਰ ਕਿਸਮਾਂ ਹੋ ਸਕਦੀਆਂ ਹਨ।</translation> <translation id="3616113530831147358">ਆਡੀਓ</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">ਲਿੰਕ ਕਾਪੀ ਕਰੋ</translation> <translation id="3988213473815854515">ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਦੀ ਆਗਿਆ ਹੈ</translation> <translation id="3988466920954086464">ਇਸ ਪੈਨਲ ਵਿੱਚ ਤਤਕਾਲ ਖੋਜ ਨਤੀਜੇ ਦੇਖੋ</translation> -<translation id="3997476611815694295">ਗੈਰ-ਮਹੱਤਵਪੂਰਨ ਸਟੋਰੇਜ</translation> <translation id="4000212216660919741">ਆਫ਼ਲਾਈਨ ਹੋਮ</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ਘੰਟਾ}one{# ਘੰਟਾ}other{# ਘੰਟੇ}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">ਵਰਤੋਂਕਾਰ ਨਾਮ ਕਾਪੀ ਕੀਤਾ ਗਿਆ</translation> <translation id="543509235395288790"><ph name="COUNT" /> ਫ਼ਾਈਲਾਂ ਨੂੰ ਡਾਊਨਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ (<ph name="MEGABYTES" />)।</translation> <translation id="5441522332038954058">ਪਤਾ ਬਾਰ 'ਤੇ ਜਾਓ</translation> -<translation id="5447201525962359567">ਸਾਰੀ ਸਾਈਟ ਸਟੋਰੇਜ, ਜਿਸ ਵਿੱਚ ਕੁਕੀਜ਼ ਅਤੇ ਹੋਰ ਸਥਾਨਕ ਤੌਰ 'ਤੇ ਸਟੋਰ ਕੀਤਾ ਡਾਟਾ ਸ਼ਾਮਲ ਹੈ</translation> <translation id="545042621069398927">ਤੁਹਾਡੇ ਡਾਊਨਲੋਡ ਦੀ ਗਤੀ ਵਧਾਈ ਜਾ ਰਹੀ ਹੈ।</translation> <translation id="5456381639095306749">ਪੰਨਾ ਡਾਊਨਲੋਡ ਕਰੋ</translation> <translation id="548278423535722844">'ਨਕਸ਼ੇ ਐਪ' ਵਿੱਚ ਖੋਲ੍ਹੋ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb index e16e85d..197308f 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Aby korzystać z kart ze swoich innych urządzeń, zaloguj się i włącz synchronizację</translation> <translation id="3587482841069643663">Wszystkie</translation> <translation id="3587596251841506391">Pomóż poprawić bezpieczeństwo w sieci</translation> -<translation id="3590487821116122040">Dane witryn, które Chrome uznaje za nieistotne (np. witryny, które rzadko odwiedzasz lub które nie mają zapisanych ustawień)</translation> <translation id="3594780231884063836">Wycisz film</translation> <translation id="3599863153486145794">Usuwa historię ze wszystkich urządzeń, na których jesteś zalogowany. Inne rodzaje historii przeglądania mogą być nadal dostępne na Twoim koncie Google na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Dźwięk</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopiuj link</translation> <translation id="3988213473815854515">Lokalizacja jest dozwolona</translation> <translation id="3988466920954086464">Zobacz wyniki wyszukiwania dynamicznego w tym panelu</translation> -<translation id="3997476611815694295">Nieistotne dane</translation> <translation id="4000212216660919741">Ekran główny offline</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# godzina}few{# godziny}many{# godzin}other{# godziny}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Nazwa użytkownika została skopiowana</translation> <translation id="543509235395288790">Pobieram pliki: <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Przejdź do paska adresu</translation> -<translation id="5447201525962359567">Wszystkie dane witryn, w tym pliki cookie i inne dane lokalne</translation> <translation id="545042621069398927">Przyspieszam pobieranie.</translation> <translation id="5456381639095306749">Pobierz stronę</translation> <translation id="548278423535722844">Otwórz w aplikacji z mapami</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb index 40d0b75c..272aadd 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-BR.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">Para ver as guias dos seus outros dispositivos, faça login e ative a sincronização</translation> <translation id="3587482841069643663">Tudo</translation> <translation id="3587596251841506391">Ajudar a melhorar a segurança na Web</translation> -<translation id="3590487821116122040">Dados de armazenamento de site que o Chrome não acredita serem importantes (por exemplo, sites sem configurações salvas ou que você não visita com frequência)</translation> <translation id="3594780231884063836">Desativar som do vídeo</translation> <translation id="3599863153486145794">Limpa o histórico de todos os dispositivos conectados. Sua Conta do Google pode ter outras formas de histórico de navegação em <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Áudio</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">Copiar link</translation> <translation id="3988213473815854515">Está autorizado a usar informações de localização</translation> <translation id="3988466920954086464">Veja neste painel resultados da pesquisa instantâneos</translation> -<translation id="3997476611815694295">Armazenamento sem importância</translation> <translation id="4000212216660919741">Página inicial off-line</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}one{# h}other{# h}}</translation> <translation id="4056223980640387499">Sépia</translation> @@ -566,7 +564,6 @@ <translation id="5433691172869980887">Nome de usuário copiado</translation> <translation id="543509235395288790">Fazendo o download de <ph name="COUNT" /> arquivos (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Ir para a barra de endereço</translation> -<translation id="5447201525962359567">Todos os dados de armazenamento de sites, incluindo cookies e outros dados armazenados localmente</translation> <translation id="545042621069398927">Acelerando seu download.</translation> <translation id="5456381639095306749">Fazer o download da página</translation> <translation id="548278423535722844">Abrir no app de mapa</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb index aef7dd4..4e963e25 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pt-PT.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Para obter os separadores dos seus outros dispositivos, inicie sessão e ative a sincronização.</translation> <translation id="3587482841069643663">Tudo</translation> <translation id="3587596251841506391">Ajude a melhorar a segur. na Web</translation> -<translation id="3590487821116122040">Armazenamento do site que o Chrome não considera importante (por exemplo, sites sem definições guardadas ou aos quais não acede com frequência)</translation> <translation id="3594780231884063836">Desativar o som do vídeo</translation> <translation id="3599863153486145794">Limpa o histórico de todos os dispositivos com sessão iniciada. A sua Conta Google pode ter outras formas do histórico de navegação em <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Áudio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Cop. link</translation> <translation id="3988213473815854515">A localização é permitida</translation> <translation id="3988466920954086464">Veja resultados da pesquisa instantâneos neste painel.</translation> -<translation id="3997476611815694295">Armazenamento desnecessário</translation> <translation id="4000212216660919741">Em casa offline</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}other{# h}}</translation> <translation id="4056223980640387499">Sépia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Nome de utilizador copiado</translation> <translation id="543509235395288790">A transferir <ph name="COUNT" /> ficheiros (<ph name="MEGABYTES" />)…</translation> <translation id="5441522332038954058">Ir para a barra de endereço</translation> -<translation id="5447201525962359567">Todo o armazenamento de sites, incluindo cookies e outros dados armazenados localmente</translation> <translation id="545042621069398927">A acelerar a transferência…</translation> <translation id="5456381639095306749">Transferir página</translation> <translation id="548278423535722844">Abrir na aplicação de mapas</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb index e04844e..12b0ce95 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ro.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Pentru a accesa filele de pe alte dispozitive, conectează-te și activează sincronizarea</translation> <translation id="3587482841069643663">Toate</translation> <translation id="3587596251841506391">Îmbunătățește securitatea pe web</translation> -<translation id="3590487821116122040">Stocare a site-urilor pe care Chrome nu o consideră importantă (de ex., site-uri care nu au setări salvate sau pe care nu le accesezi frecvent)</translation> <translation id="3594780231884063836">Dezactivează sunetul videoclipului</translation> <translation id="3599863153486145794">Șterge istoricul de pe toate dispozitivele conectate. Contul Google poate să ofere alte forme ale istoricului de navigare la <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Copiază linkul</translation> <translation id="3988213473815854515">Accesul la locație este permis</translation> <translation id="3988466920954086464">Afișează rezultatele căutării instantanee în acest panou</translation> -<translation id="3997476611815694295">Stocare neimportantă</translation> <translation id="4000212216660919741">Pagina de pornire offline</translation> <translation id="4034817413553209278">{HOURS,plural, =1{O oră}few{# ore}other{# de ore}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Numele de utilizator a fost copiat</translation> <translation id="543509235395288790">Se descarcă <ph name="COUNT" /> fișiere (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Accesează bara de adrese</translation> -<translation id="5447201525962359567">Toată stocarea site-urilor, inclusiv cookie-urile și alte date stocate local</translation> <translation id="545042621069398927">Se accelerează descărcarea.</translation> <translation id="5456381639095306749">Descarcă pagina</translation> <translation id="548278423535722844">Deschide în aplicația Maps</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb index 3a23e37f..50093c6 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ru.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Чтобы получить доступ к вкладкам на всех устройствах, войдите в аккаунт и включите синхронизацию.</translation> <translation id="3587482841069643663">Все</translation> <translation id="3587596251841506391">Помогать Google делать Интернет безопаснее</translation> -<translation id="3590487821116122040">Маловажные данные сайтов (например, сайты, которые вы редко посещаете или на которых не сохранили настройки)</translation> <translation id="3594780231884063836">Выключить звук для видео</translation> <translation id="3599863153486145794">Удаление истории со всех устройств, на которых выполнен вход в аккаунт. Информация о других ваших действиях в Интернете может также храниться на странице <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Аудио</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Копировать ссылку</translation> <translation id="3988213473815854515">Доступ к геоданным разрешен</translation> <translation id="3988466920954086464">Результаты поиска появятся на этой панели.</translation> -<translation id="3997476611815694295">Маловажные данные</translation> <translation id="4000212216660919741">Офлайн</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# час}one{# час}few{# часа}many{# часов}other{# часа}}</translation> <translation id="4056223980640387499">Сепия</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Имя пользователя скопировано</translation> <translation id="543509235395288790">Скачивание файлов: <ph name="COUNT" /> (<ph name="MEGABYTES" /> МБ).</translation> <translation id="5441522332038954058">Перейти к адресной строке</translation> -<translation id="5447201525962359567">Все данные сайтов, включая файлы cookie и другую информацию, хранящуюся на устройстве</translation> <translation id="545042621069398927">Ускорение скачивания…</translation> <translation id="5456381639095306749">Скачать страницу</translation> <translation id="548278423535722844">Показать на карте</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb index bad8cd4..eb0914f 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_si.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">ඔබගේ වෙනත් උපාංගවලින් ඔබගේ පටිති ලබා ගැනීමට, පුරනය වී සමමුහුර්තය ක්රියාත්මක කරන්න</translation> <translation id="3587482841069643663">සියළු</translation> <translation id="3587596251841506391">වෙබයෙහි ආරක්ෂාව දියුණුවට උදව් ව.</translation> -<translation id="3590487821116122040">Chrome වැදගත් යැයි නොසිතන අඩවි ආචයනය (උදා: සුරැකූ සැකසීම් නැති හෝ ඔබ බොහෝ විට නොපිවිසෙන අඩවි)</translation> <translation id="3594780231884063836">වීඩියෝව නිහඬ කරන්න</translation> <translation id="3599863153486145794">සියලු පුරනය-වූ උපාංගවලින් ඉතිහාසය හිස් කරයි. ඔබේ Google ගිණුමට <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> හිදී බ්රවුස් කිරීමේ ඉතිහාසයේ වෙනත් ආකාරයන් තිබිය හැක.</translation> <translation id="3616113530831147358">ශබ්ද</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">සබැඳිය පිටපත් කරන්න</translation> <translation id="3988213473815854515">පිහිටීමට ඉඩ දී ඇත</translation> <translation id="3988466920954086464">මෙම පුවරුව තුළ ක්ෂණික සෙවීම් ප්රතිඵල බලන්න</translation> -<translation id="3997476611815694295">නොවැදගත් ආචයනය</translation> <translation id="4000212216660919741">නොබැඳි මුල්පිටුව</translation> <translation id="4034817413553209278">{HOURS,plural, =1{පැය #}one{පැය #}other{පැය #}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">පරිශීලක නම පිටපත් කරන ලදී</translation> <translation id="543509235395288790">ගොනු <ph name="COUNT" />ක් බාගනිමින් (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">ලිපින තීරුව වෙත පනින්න</translation> -<translation id="5447201525962359567">කුකීස් සහ අනෙකුත් ස්ථානීයව ගබඩා කළ දත්ත ඇතුළුව, සියලුම අඩවි ආචයනය</translation> <translation id="545042621069398927">ඔබේ බාගැනීම වේගවත් කරමින්.</translation> <translation id="5456381639095306749">පිටුව බාගන්න</translation> <translation id="548278423535722844">සිතියම් යෙදුම තුළ විවෘත කරන්න</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb index 073136c..edb46674 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sk.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Ak chcete získať karty zo svojich ostatných zariadení, prihláste sa a zapnite synchronizáciu</translation> <translation id="3587482841069643663">Všetko</translation> <translation id="3587596251841506391">Lepšie zabezpečenie na internete</translation> -<translation id="3590487821116122040">Úložisko webu, ktoré Chrome nepovažuje za dôležité (napr. webové stránky bez uložených nastavení alebo také, ktoré nenavštevujete často)</translation> <translation id="3594780231884063836">Vypnúť zvuk videa</translation> <translation id="3599863153486145794">Vymaže históriu zo všetkých prihlásených zariadení. Váš účet Google môže mať ďalšie formy histórie prehliadania na adrese <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Zvuk</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopírovať odkaz</translation> <translation id="3988213473815854515">Poloha je povolená</translation> <translation id="3988466920954086464">Zobraziť výsledky dynamického vyhľadávania na tomto paneli</translation> -<translation id="3997476611815694295">Nedôležité úložisko</translation> <translation id="4000212216660919741">Offline domov</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# hod.}few{# hod.}many{# hod.}other{# hod.}}</translation> <translation id="4056223980640387499">Sépia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Používateľské meno bolo skopírované</translation> <translation id="543509235395288790">Sťahuje sa niekoľko súborov (<ph name="COUNT" />) s celkovou veľkosťou <ph name="MEGABYTES" />.</translation> <translation id="5441522332038954058">Prechod na panel s adresou</translation> -<translation id="5447201525962359567">Celé úložisko webu vrátane súborov cookie a ďalších miestne uložených dát</translation> <translation id="545042621069398927">Sťahovanie sa zrýchľuje.</translation> <translation id="5456381639095306749">Stránka sťahovania</translation> <translation id="548278423535722844">Otvorte v aplikácii pre mapy</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb index 55dbcf39..1a0b267d 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sl.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">Če želite dostopati do zavihkov iz drugih naprav, vklopite sinhronizacijo</translation> <translation id="3587482841069643663">Vse</translation> <translation id="3587596251841506391">Izboljšanje varnosti v spletu</translation> -<translation id="3590487821116122040">Shranjeni podatki spletnega mesta, ki se Chromu ne zdijo pomembni (npr. spletna mesta, za katera nimate shranjenih nastavitev ali ki jih ne obiskujete pogosto).</translation> <translation id="3594780231884063836">Izklop videa</translation> <translation id="3599863153486145794">Izbriše zgodovino iz vseh naprav, v katerih ste prijavljeni. V Google Računu so morda druge vrste zgodovine brskanja na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Zvok</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">Kopiranje povezave</translation> <translation id="3988213473815854515">Lokacija je dovoljena</translation> <translation id="3988466920954086464">Ogled rezultatov dinamičnega iskanja v tem podoknu</translation> -<translation id="3997476611815694295">Nepomembni shranjeni podatki</translation> <translation id="4000212216660919741">Začetna stran brez povezave</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# h}one{# h}two{# h}few{# h}other{# h}}</translation> <translation id="4056223980640387499">Sepija</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">Uporabniško ime kopirano</translation> <translation id="543509235395288790">Prenašanje toliko datotek: <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Premik na naslovno vrstico</translation> -<translation id="5447201525962359567">Vsi shranjeni podatki spletnega mesta, vključno s piškotki in drugimi lokalno shranjenimi podatki</translation> <translation id="545042621069398927">Pospeševanje prenosa.</translation> <translation id="5456381639095306749">Prenos strani</translation> <translation id="548278423535722844">Odpiranje v aplikaciji z zemljevidi</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb index 2bfe798..b0bb934 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sq.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Për të marrë skedat nga pajisjet e tjera të tua, identifikohu dhe aktivizo sinkronizimin</translation> <translation id="3587482841069643663">Të gjitha</translation> <translation id="3587596251841506391">Ndihmo në përmirësimin e sigurisë në ueb</translation> -<translation id="3590487821116122040">Hapësira ruajtëse që Chrome nuk e konsideron të rëndësishme (p.sh. sajtet pa cilësime të ruajtura ose ti që nuk i viziton shpesh)</translation> <translation id="3594780231884063836">Çaktivizo zërin e videos</translation> <translation id="3599863153486145794">Pastron historikun nga të gjitha pajisjet ku je identifikuar. Llogaria jote e Google mund të ketë forma të tjera të historikut të shfletimit në <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopjo lidhjen</translation> <translation id="3988213473815854515">Vendndodhja nuk lejohet</translation> <translation id="3988466920954086464">Shiko rezultatet e çastit të kërkimit në këtë panel</translation> -<translation id="3997476611815694295">Hapësirë ruajtëse e parëndësishme</translation> <translation id="4000212216660919741">Shtëpia jashtë linje</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# orë}other{# orë}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Emri i përdoruesit u kopjua</translation> <translation id="543509235395288790">Po shkarkohen <ph name="COUNT" /> skedarë (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Kalo te shiriti i adresës</translation> -<translation id="5447201525962359567">Të gjithë hapësirën ruajtëse të sajtit, duke përfshirë kukit dhe të dhënat e tjera të ruajtura lokalisht</translation> <translation id="545042621069398927">Po të përshpejtohet shkarkimi.</translation> <translation id="5456381639095306749">Shkarko faqen</translation> <translation id="548278423535722844">Hape në aplikacionin e hartave</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb index ea06c698..2eafd89d 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr-Latn.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Da bi vam kartice bile dostupne na drugim uređajima, prijavite se i uključite sinhronizaciju</translation> <translation id="3587482841069643663">Sve</translation> <translation id="3587596251841506391">Poboljšajte bezbednost na vebu</translation> -<translation id="3590487821116122040">Memorijski prostor za sajtove koji Chrome ne smatra važnim (npr. sajtovi bez sačuvanih podešavanja ili sajtovi koje ne posećujete često)</translation> <translation id="3594780231884063836">Isključite zvuk videa</translation> <translation id="3599863153486145794">Briše istoriju sa svih uređaja na kojima ste prijavljeni. Google nalog može da ima druge oblike istorije pregledanja na <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Audio</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopiraj link</translation> <translation id="3988213473815854515">Lokacija je dozvoljena</translation> <translation id="3988466920954086464">Pogledajte instant rezultate pretrage na ovoj tabli</translation> -<translation id="3997476611815694295">Nevažan memorijski prostor</translation> <translation id="4000212216660919741">Oflajn početna stranica</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# č}one{# č}few{# č}other{# č}}</translation> <translation id="4056223980640387499">Sepija</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Korisničko ime je kopirano</translation> <translation id="543509235395288790">Preuzimaju se datoteke (<ph name="COUNT" />: <ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Prelazak na traku za adresu</translation> -<translation id="5447201525962359567">Celokupan memorijski prostor za sajt, uključujući kolačiće i druge lokalno sačuvane podatke</translation> <translation id="545042621069398927">Preuzimanje se ubrzava.</translation> <translation id="5456381639095306749">Preuzmi stranicu</translation> <translation id="548278423535722844">Otvorite u aplikaciji za mape</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb index 5c85492..1b81f69 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sr.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Да би вам картице биле доступне на другим уређајима, пријавите се и укључите синхронизацију</translation> <translation id="3587482841069643663">Све</translation> <translation id="3587596251841506391">Побољшајте безбедност на вебу</translation> -<translation id="3590487821116122040">Меморијски простор за сајтове који Chrome не сматра важним (нпр. сајтови без сачуваних подешавања или сајтови које не посећујете често)</translation> <translation id="3594780231884063836">Искључите звук видеа</translation> <translation id="3599863153486145794">Брише историју са свих уређаја на којима сте пријављени. Google налог може да има друге облике историје прегледања на <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Аудио</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Копирај линк</translation> <translation id="3988213473815854515">Локација је дозвољена</translation> <translation id="3988466920954086464">Погледајте инстант резултате претраге на овој табли</translation> -<translation id="3997476611815694295">Неважан меморијски простор</translation> <translation id="4000212216660919741">Офлајн почетна страница</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ч}one{# ч}few{# ч}other{# ч}}</translation> <translation id="4056223980640387499">Сепија</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Корисничко име је копирано</translation> <translation id="543509235395288790">Преузимају се датотеке (<ph name="COUNT" />: <ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Прелазак на траку за адресу</translation> -<translation id="5447201525962359567">Целокупан меморијски простор за сајт, укључујући колачиће и друге локално сачуване податке</translation> <translation id="545042621069398927">Преузимање се убрзава.</translation> <translation id="5456381639095306749">Преузми страницу</translation> <translation id="548278423535722844">Отворите у апликацији за мапе</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb index 95e2f63..bd5d47c0 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Logga in och aktivera synkronisering om du vill ha samma flikar tillgängliga på alla enheter</translation> <translation id="3587482841069643663">Alla</translation> <translation id="3587596251841506391">Förbättra säkerheten på webben</translation> -<translation id="3590487821116122040">Webbplatslagring som Chrome bedömer som oviktig (t.ex. webbplatser utan sparade inställningar eller som du inte besöker ofta)</translation> <translation id="3594780231884063836">Stäng av ljudet för videon</translation> <translation id="3599863153486145794">Historik rensas från alla inloggade enheter. Det kan finnas andra former av webbhistorik i Google-kontot på <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Ljud</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopiera länk</translation> <translation id="3988213473815854515">Platsen är tillåten</translation> <translation id="3988466920954086464">Visa snabba sökresultat i panelen</translation> -<translation id="3997476611815694295">Oviktig lagring</translation> <translation id="4000212216660919741">Startsida offline</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# tim}other{# tim}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Användarnamnet har kopierats</translation> <translation id="543509235395288790"><ph name="COUNT" /> filer (<ph name="MEGABYTES" />) laddas ned.</translation> <translation id="5441522332038954058">Hoppa till adressfältet</translation> -<translation id="5447201525962359567">All webbplatslagring, inklusive cookies och annan lokalt sparad data</translation> <translation id="545042621069398927">Nedladdningen görs snabbare.</translation> <translation id="5456381639095306749">Ladda ned sida</translation> <translation id="548278423535722844">Öppna i kartapp</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb index ed7fc08..5edb1cf 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_sw.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">Ingia katika akaunti na uwashe kipengele cha usawazishaji ili upate vichupo vyako kutoka vifaa vyako vingine</translation> <translation id="3587482841069643663">Zote</translation> <translation id="3587596251841506391">Tusaidie kuboresha usalama kwenye wavuti</translation> -<translation id="3590487821116122040">Hifadhi ya tovuti ambayo Chrome haidhani ni muhimu (k.m. tovuti ambazo hazina mipangilio iliyohifadhiwa au ambazo hutembelei sana)</translation> <translation id="3594780231884063836">Zima video</translation> <translation id="3599863153486145794">Hufuta historia kwenye vifaa vyote ulivyotumia kuingia katika akaunti. Huenda Akaunti yako ya Google ikawa na aina nyingine za historia ya kuvinjari kwenye <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Sauti</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">Nakili kiungo</translation> <translation id="3988213473815854515">Mahali panaruhusiwa</translation> <translation id="3988466920954086464">Angalia matokeo ya utafutaji wa moja kwa moja katika kidirisha hiki</translation> -<translation id="3997476611815694295">Hifadhi ambayo si muhimu</translation> <translation id="4000212216660919741">Skrini ya Kwanza, Nje ya Mtandao</translation> <translation id="4034817413553209278">{HOURS,plural, =1{Saa #}other{Saa #}}</translation> <translation id="4056223980640387499">Sepia</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">Jina la mtumiaji limenakiliwa</translation> <translation id="543509235395288790">Inapakua faili <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Rudi kwenye sehemu ya anwani</translation> -<translation id="5447201525962359567">Hifadhi yote ya tovuti, ikiwa ni pamoja na vidakuzi na data nyingine iliyohifadhiwa ndani</translation> <translation id="545042621069398927">Inaongeza kasi ya kupakua faili yako.</translation> <translation id="5456381639095306749">Pakua ukurasa</translation> <translation id="548278423535722844">Fungua katika programu ya ramani</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb index a7a6dd3..0300db1 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">உங்கள் பிற சாதனங்களிலிருந்து தாவல்களைப் பெற, உள்நுழைந்து, ஒத்திசைவை இயக்கவும்</translation> <translation id="3587482841069643663">அனைத்தும்</translation> <translation id="3587596251841506391">இணையத்தில் பாதுகாப்பை மேம்படுத்த உதவுங்கள்</translation> -<translation id="3590487821116122040">முக்கியமில்லை என்று Chrome கருதும் தளச் சேமிப்பகம் (எ.கா: சேமித்த அமைப்புகள் இல்லாத அல்லது நீங்கள் அடிக்கடி பார்க்காத தளங்கள்)</translation> <translation id="3594780231884063836">வீடியோவின் ஒலியை முடக்கு</translation> <translation id="3599863153486145794">உள்நுழைந்த எல்லாச் சாதனங்களிலிருந்தும் வரலாற்றை அழிக்கும். உங்கள் Google கணக்கு, <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> என்ற இணைப்பில் உலாவல் வரலாறு தொடர்பான பிற தகவல்களைக் கொண்டிருக்கக்கூடும்.</translation> <translation id="3616113530831147358">ஆடியோ</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">இணைப்பை நகலெடு</translation> <translation id="3988213473815854515">இருப்பிடம் அனுமதிக்கப்படும்</translation> <translation id="3988466920954086464">இந்தப் பேனலில் உடனடித் தேடல் முடிவுகளைப் பார்க்கவும்</translation> -<translation id="3997476611815694295">முக்கியமில்லா சேமிப்பகம்</translation> <translation id="4000212216660919741">Home ஆஃப்லைனில் உள்ளது</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# மணிநேரம்}other{# மணிநேரம்}}</translation> <translation id="4056223980640387499">செபியா</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">பயனர்பெயர் நகலெடுக்கப்பட்டது</translation> <translation id="543509235395288790"><ph name="COUNT" /> கோப்புகளைப் பதிவிறக்குகிறது (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">முகவரிப் பட்டிக்குச் செல்லும்</translation> -<translation id="5447201525962359567">குக்கீகள் மற்றும் சாதனத்தில் சேமிக்கப்பட்ட பிற தரவு உள்பட எல்லா தளச் சேமிப்பகமும்</translation> <translation id="545042621069398927">பதிவிறக்கத்தின் வேகத்தை அதிகப்படுத்துகிறது.</translation> <translation id="5456381639095306749">பக்கத்தைப் பதிவிறக்குக</translation> <translation id="548278423535722844">வரைபடப் பயன்பாட்டில் திற</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb index 30fe07d..a71eb61 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_te.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">మీ ఇతర పరికరాలలో ఉన్న మీ అన్ని ట్యాబ్లను పొందాలనుకుంటే, సైన్ ఇన్ చేసి, సమకాలీకరణ ఎంపికను ఆన్ చేయాలి</translation> <translation id="3587482841069643663">మొత్తం</translation> <translation id="3587596251841506391">వెబ్ భద్రతనుపెంచడంలో సాయపడుతుంది</translation> -<translation id="3590487821116122040">Chrome ముఖ్యమైనదిగా భావించని సైట్ నిల్వ (ఉదా. సేవ్ చేసిన సెట్టింగ్లు లేని సైట్లు లేదా మీరు తరచుగా సందర్శించని సైట్లు)</translation> <translation id="3594780231884063836">వీడియోను మ్యూట్ చేయండి</translation> <translation id="3599863153486145794">సైన్ ఇన్ చేసిన అన్ని పరికరాల నుండి చరిత్రను తొలగిస్తుంది. మీ Google ఖాతా <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />లో ఇతర రూపాల్లో ఉన్న బ్రౌజింగ్ చరిత్రను కలిగి ఉండవచ్చు.</translation> <translation id="3616113530831147358">ఆడియో</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">లింక్ను కాపీ చేయి</translation> <translation id="3988213473815854515">స్థానం అనుమతించబడింది</translation> <translation id="3988466920954086464">ఈ ప్యానెల్లో తక్షణ శోధన ఫలితాలను చూడండి</translation> -<translation id="3997476611815694295">ప్రధానం కాని నిల్వ</translation> <translation id="4000212216660919741">ఆఫ్లైన్ హోమ్</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# గం}other{# గం}}</translation> <translation id="4056223980640387499">సెపియా</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">వినియోగదారు పేరు కాపీ చేయబడింది</translation> <translation id="543509235395288790"><ph name="COUNT" /> ఫైల్లను డౌన్లోడ్ చేస్తోంది (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">చిరునామా పట్టీకి వెళ్లండి</translation> -<translation id="5447201525962359567">కుక్కీలు, స్థానికంగా నిల్వ చేసిన ఇతర డేటాతో సహా మొత్తం సైట్ నిల్వ</translation> <translation id="545042621069398927">మీ డౌన్లోడ్ను వేగవంతం చేస్తోంది.</translation> <translation id="5456381639095306749">పేజీని డౌన్లోడ్ చేయండి</translation> <translation id="548278423535722844">మ్యాప్స్ యాప్లో తెరువు</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb index 16df0ef..88025b8 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_th.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">ลงชื่อเข้าใช้และเปิดการซิงค์เพื่อรับแท็บจากอุปกรณ์เครื่องอื่นๆ ของคุณ</translation> <translation id="3587482841069643663">ทั้งหมด</translation> <translation id="3587596251841506391">ช่วยปรับปรุงความปลอดภัยในอินเทอร์เน็ต</translation> -<translation id="3590487821116122040">พื้นที่เก็บข้อมูลเว็บไซต์ที่ Chrome คิดว่าไม่สำคัญ (เช่น เว็บไซต์ที่ไม่มีการตั้งค่าที่บันทึกไว้หรือที่คุณไม่ได้เข้าชมบ่อยครั้ง)</translation> <translation id="3594780231884063836">ปิดเสียงวิดีโอ</translation> <translation id="3599863153486145794">ล้างประวัติจากอุปกรณ์ที่ลงชื่อเข้าใช้ทั้งหมด บัญชี Google อาจมีประวัติการท่องเว็บรูปแบบอื่นๆ ที่ <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /></translation> <translation id="3616113530831147358">เสียง</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">คัดลอกลิงก์</translation> <translation id="3988213473815854515">อนุญาตตำแหน่ง</translation> <translation id="3988466920954086464">ดูผลการค้นหาทันใจในแผงนี้</translation> -<translation id="3997476611815694295">พื้นที่เก็บข้อมูลที่ไม่สำคัญ</translation> <translation id="4000212216660919741">หน้าแรกออฟไลน์</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ชม.}other{# ชม.}}</translation> <translation id="4056223980640387499">ซีเปีย</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">คัดลอกชื่อผู้ใช้แล้ว</translation> <translation id="543509235395288790">กำลังดาวน์โหลด <ph name="COUNT" /> ไฟล์ (<ph name="MEGABYTES" />)</translation> <translation id="5441522332038954058">ข้ามไปยังแถบที่อยู่เว็บ</translation> -<translation id="5447201525962359567">พื้นที่เก็บข้อมูลเว็บไซต์ทั้งหมด รวมถึงคุกกี้และข้อมูลอื่นๆ ที่เก็บไว้ในเครื่อง</translation> <translation id="545042621069398927">กำลังเพิ่มความเร็วในการดาวน์โหลด</translation> <translation id="5456381639095306749">ดาวน์โหลดหน้า</translation> <translation id="548278423535722844">เปิดในแอปแผนที่</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb index 9cc174a..262e302 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_tr.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Diğer cihazlarınızdaki sekmelerinize ulaşmak için oturum açın ve senkronizasyonu etkinleştirin</translation> <translation id="3587482841069643663">Tümü</translation> <translation id="3587596251841506391">Web'de güvenliğin iyileştirilmesine yardımcı olun</translation> -<translation id="3590487821116122040">Chrome'un önemli olmadığını düşündüğü site depolama alanı (ör. kayıtlı ayarları bulunmayan veya sık ziyaret etmediğiniz siteler)</translation> <translation id="3594780231884063836">Videonun sesini kapat</translation> <translation id="3599863153486145794">Oturumunuzun açık olduğu tüm cihazlarda geçmişi temizler. Google Hesabınızın <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> adresinde başka biçimlerde tarama geçmişi olabilir.</translation> <translation id="3616113530831147358">Ses</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Bağlantıyı kopyala</translation> <translation id="3988213473815854515">Konuma izin veriliyor</translation> <translation id="3988466920954086464">Anında arama sonuçlarını bu panelde görün</translation> -<translation id="3997476611815694295">Önemli olmayan depolama alanı</translation> <translation id="4000212216660919741">Çevrimdışı Ana Sayfa</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# sa.}other{# sa.}}</translation> <translation id="4056223980640387499">Sepya Tonu</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Kullanıcı adı kopyalandı</translation> <translation id="543509235395288790"><ph name="COUNT" /> dosya indiriliyor (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Adres çubuğuna gider</translation> -<translation id="5447201525962359567">Çerezler ve yerel olarak depolanmış diğer veriler de dahil olmak üzere tüm site depolama alanı</translation> <translation id="545042621069398927">İndirme işleminiz hızlandırılıyor.</translation> <translation id="5456381639095306749">Sayfayı indir</translation> <translation id="548278423535722844">Haritalar uygulamasında aç</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb index 5424354f..8768bbe 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uk.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Щоб мати доступ до вкладок з інших пристроїв, увійдіть в обліковий запис і ввімкніть синхронізацію</translation> <translation id="3587482841069643663">Все</translation> <translation id="3587596251841506391">Покращувати безпеку в Інтернеті</translation> -<translation id="3590487821116122040">Дані сайтів, які Chrome визначив як неважливі, зокрема сайтів із незбереженими налаштуваннями або тих, які ви рідко відвідуєте</translation> <translation id="3594780231884063836">Вимкнути звук у відео</translation> <translation id="3599863153486145794">Видалення історії на всіх пристроях, на яких ви ввійшли в обліковий запис. Історія веб-перегляду може також зберігатися у вашому обліковому записі Google на сторінці <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Аудіо</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Копіювати</translation> <translation id="3988213473815854515">Доступ до геоданих надано</translation> <translation id="3988466920954086464">Переглядайте миттєві результати пошуку на цій панелі</translation> -<translation id="3997476611815694295">Неважливі дані</translation> <translation id="4000212216660919741">Дім у режимі офлайн</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# год}one{# год}few{# год}many{# год}other{# год}}</translation> <translation id="4056223980640387499">Сепія</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Ім’я користувача скопійовано</translation> <translation id="543509235395288790">Завантажується файлів: <ph name="COUNT" /> (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Перейти до адресного рядка</translation> -<translation id="5447201525962359567">Усі дані сайтів, зокрема файли cookie й інші локально збережені дані</translation> <translation id="545042621069398927">Прискорюється завантаження.</translation> <translation id="5456381639095306749">Завантажити сторінку</translation> <translation id="548278423535722844">Відкрити в додатку Карти</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb index 8f775d7..4e7d24cb 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ur.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">اپنے دیگر آلات سے اپنے ٹیبز حاصل کرنے کیلئے، سائن ان کریں اور سِنک کو آن کریں</translation> <translation id="3587482841069643663">سبھی</translation> <translation id="3587596251841506391">ویب پر سیکیورٹی کو بہتر بنانے میں مدد کریں</translation> -<translation id="3590487821116122040">سائٹ کا وہ اسٹوریج جسے Chrome اہم نہیں خیال کرتا ہے (مثلاً بغیر محفوظ کردہ ترتیبات والی سائٹس یا وہ جنہیں آپ اکثر ملاحظہ نہیں کرتے ہیں)</translation> <translation id="3594780231884063836">ویڈیو خاموش کریں</translation> <translation id="3599863153486145794">سبھی سائن ان کردہ آلات سے سرگزشت صاف کر دیتا ہے۔ ممکن ہے کہ <ph name="BEGIN_LINK" />myactivity.google<ph name="END_LINK" /> پر آپ کے Google اکاؤنٹ میں براؤزنگ کی سرگزشت کی دیگر شکلیں موجود ہوں۔</translation> <translation id="3616113530831147358">آڈیو</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">لنک کاپی کریں</translation> <translation id="3988213473815854515">مقام کی اجازت ہے</translation> <translation id="3988466920954086464">اس پینل میں فوری تلاش کے نتائج دیکھیں</translation> -<translation id="3997476611815694295">غیر اہم اسٹوریج</translation> <translation id="4000212216660919741">آف لائن ہوم</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# گھنٹہ}other{# گھنٹے}}</translation> <translation id="4056223980640387499">سیپیا</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">صارف نام کاپی ہو گیا</translation> <translation id="543509235395288790"><ph name="COUNT" /> فائلیں (<ph name="MEGABYTES" />) ڈاؤن لوڈ ہو رہی ہیں۔</translation> <translation id="5441522332038954058">پتہ بار پر جائیں</translation> -<translation id="5447201525962359567">کوکیز اور دیگر مقامی طور پر اسٹور کردہ ڈیٹا سمیت، سائٹ کا سبھی اسٹوریج</translation> <translation id="545042621069398927">آپ کے ڈاؤن لوڈ کی رفتار بڑھائی جا رہی ہے۔</translation> <translation id="5456381639095306749">صفحہ ڈاؤن لوڈ کریں</translation> <translation id="548278423535722844">نقشہ کی ایپ میں کھولیں</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb index 2f69dd39..8d0092a4 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_uz.xtb
@@ -332,7 +332,6 @@ <translation id="3568688522516854065">Boshqa qurilmalaringizdagi brauzer sahifalarini ko‘rish uchun hisobingizga kiring va sinxronizatsiyani yoqing</translation> <translation id="3587482841069643663">Barchasi</translation> <translation id="3587596251841506391">Himoyani oshirishga yordam bering</translation> -<translation id="3590487821116122040">Chrome muhim emas deb hisoblaydigan sayt xotirasi (masalan, saqlanmaydigan yoki kam kiriladigan saytlar)</translation> <translation id="3594780231884063836">Video ovozini oʻchirish</translation> <translation id="3599863153486145794">Barcha kirilgan qurilmalardagi tarix o‘chiriladi. Google hisobingiz orqali bajargan internetdagi faoliyatingizni <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> orqali ko‘rishingiz mumkin.</translation> <translation id="3616113530831147358">Audio</translation> @@ -386,7 +385,6 @@ <translation id="3987993985790029246">Nusxalash</translation> <translation id="3988213473815854515">Joylashuvni ishlatishga ruxsat berilgan</translation> <translation id="3988466920954086464">Qidiruv natijalari shu panelda paydo bo‘ladi</translation> -<translation id="3997476611815694295">Muhim bo‘lmagan xotira</translation> <translation id="4000212216660919741">Uy oflayn</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# soat}other{# soat}}</translation> <translation id="4056223980640387499">Sepiya</translation> @@ -565,7 +563,6 @@ <translation id="5433691172869980887">Foydalanuvchi nomi nusxalandi</translation> <translation id="543509235395288790"><ph name="COUNT" /> ta fayl yuklab olinmoqda (<ph name="MEGABYTES" />).</translation> <translation id="5441522332038954058">Manzil qatoriga o‘tish</translation> -<translation id="5447201525962359567">Barcha sayt ma’lumotlari saqlanadigan xotira, shuningdek, cookie-fayllar va boshqa kompyuterga saqlangan ma’lumotlar</translation> <translation id="545042621069398927">Yuklab olish tezlashtirilmoqda.</translation> <translation id="5456381639095306749">Sahifani yuklab olish</translation> <translation id="548278423535722844">Xaritalar ilovasida ochish</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb index 2014022..18aef74 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Để sử dụng các thẻ từ những thiết bị khác, hãy đăng nhập và bật tính năng đồng bộ hóa</translation> <translation id="3587482841069643663">Tất cả</translation> <translation id="3587596251841506391">Giúp tăng cường an ninh trên web</translation> -<translation id="3590487821116122040">Bộ nhớ trang web mà Chrome cho rằng không quan trọng (ví dụ: những trang web không có cài đặt đã lưu nào hoặc trang web mà bạn không truy cập thường xuyên)</translation> <translation id="3594780231884063836">Tắt tiếng video</translation> <translation id="3599863153486145794">Xóa lịch sử khỏi tất cả các thiết bị đã đăng nhập. Tài khoản Google của bạn có thể có các dạng lịch sử duyệt web khác tại <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Âm thanh</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Sao chép đường liên kết</translation> <translation id="3988213473815854515">Vị trí được cho phép</translation> <translation id="3988466920954086464">Xem kết quả tìm kiếm tức thì trong bảng điều khiển này</translation> -<translation id="3997476611815694295">Bộ nhớ không quan trọng</translation> <translation id="4000212216660919741">Nhà ở chế độ không kết nối Internet</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# giờ}other{# giờ}}</translation> <translation id="4056223980640387499">Màu nâu đỏ</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Đã sao chép tên người dùng</translation> <translation id="543509235395288790">Đang tải <ph name="COUNT" /> tệp (<ph name="MEGABYTES" />) xuống.</translation> <translation id="5441522332038954058">Chuyển đến thanh địa chỉ</translation> -<translation id="5447201525962359567">Tất cả bộ nhớ trang web, bao gồm cookie và các dữ liệu được lưu trữ cục bộ khác</translation> <translation id="545042621069398927">Đang tăng tốc độ tải xuống.</translation> <translation id="5456381639095306749">Tải trang xuống</translation> <translation id="548278423535722844">Mở trong ứng dụng bản đồ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb index 165fd27..c5a6f49 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-CN.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">要访问您在其他设备上的标签页,请登录您的帐号并开启同步功能</translation> <translation id="3587482841069643663">全部</translation> <translation id="3587596251841506391">帮助我们改善网络安全环境</translation> -<translation id="3590487821116122040">Chrome 认为不重要的网站(例如未保存任何设置的网站或您不常访问的网站)存储的数据</translation> <translation id="3594780231884063836">将视频静音</translation> <translation id="3599863153486145794">清除所有登录过的设备上的历史记录。您的 Google 帐号在 <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> 上可能有其他形式的浏览记录。</translation> <translation id="3616113530831147358">音频</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">复制链接</translation> <translation id="3988213473815854515">允许访问位置信息</translation> <translation id="3988466920954086464">您可以在此面板查看即时搜索结果</translation> -<translation id="3997476611815694295">不重要网站的存储数据</translation> <translation id="4000212216660919741">离线版首页</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# 小时}other{# 小时}}</translation> <translation id="4056223980640387499">棕色调</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">已复制用户名</translation> <translation id="543509235395288790">正在下载 <ph name="COUNT" /> 个文件(共 <ph name="MEGABYTES" />)。</translation> <translation id="5441522332038954058">跳转到地址栏</translation> -<translation id="5447201525962359567">所有网站存储数据,包括 Cookie 及其他本地存储的数据</translation> <translation id="545042621069398927">正在加快您的下载速度。</translation> <translation id="5456381639095306749">下载网页</translation> <translation id="548278423535722844">在地图应用中打开</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb index 4bbc646..d5c4ef7b 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-HK.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">如要取得其他裝置上的分頁,請登入並開啟同步處理功能</translation> <translation id="3587482841069643663">全部</translation> <translation id="3587596251841506391">協助改善網絡安全</translation> -<translation id="3590487821116122040">Chrome 認為不重要的網站 (例如未儲存任何設定的網站,或您不常瀏覽的網站) 儲存空間的資料</translation> <translation id="3594780231884063836">將影片靜音</translation> <translation id="3599863153486145794">清除所有已登入裝置上的記錄。您的 Google 帳戶在 <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" /> 上可能有其他形式的瀏覽記錄。</translation> <translation id="3616113530831147358">音效檔案</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">複製連結</translation> <translation id="3988213473815854515">位置已獲允許</translation> <translation id="3988466920954086464">您可以在此面板查看即時搜尋結果</translation> -<translation id="3997476611815694295">不重要網站的儲存空間資料量</translation> <translation id="4000212216660919741">離線首頁</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# 小時}other{# 小時}}</translation> <translation id="4056223980640387499">棕褐色</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">已複製使用者名稱</translation> <translation id="543509235395288790">正在下載 <ph name="COUNT" /> 個檔案 (<ph name="MEGABYTES" />)。</translation> <translation id="5441522332038954058">跳至網址列</translation> -<translation id="5447201525962359567">所有網站儲存空間的資料,包括 Cookie 和其他儲存在本機上的資料</translation> <translation id="545042621069398927">正在加快下載速度。</translation> <translation id="5456381639095306749">下載網頁</translation> <translation id="548278423535722844">在地圖應用程式中開啟</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb index 26ac28b..06cf3496 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zh-TW.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">如要存取你在其他裝置上開啟的分頁,請登入並開啟同步處理功能</translation> <translation id="3587482841069643663">全部</translation> <translation id="3587596251841506391">協助改善網路安全</translation> -<translation id="3590487821116122040">Chrome 認定為不重要的網站 (例如未儲存任何設定的網站,或是您不常造訪的網站) 所儲存的資料</translation> <translation id="3594780231884063836">將影片設為靜音</translation> <translation id="3599863153486145794">將歷史記錄從所有登入帳戶的裝置上清除。你的 Google 帳戶可能會儲存其他形式的瀏覽記錄,請參閱 <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />。</translation> <translation id="3616113530831147358">音訊</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">複製連結</translation> <translation id="3988213473815854515">禁止存取位置資訊</translation> <translation id="3988466920954086464">你可以在這個面板中查看即時搜尋結果</translation> -<translation id="3997476611815694295">不重要網站的儲存資料量</translation> <translation id="4000212216660919741">離線首頁</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# 小時}other{# 小時}}</translation> <translation id="4056223980640387499">深褐色調</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">已複製使用者名稱</translation> <translation id="543509235395288790">正在下載 <ph name="COUNT" /> 個檔案 (共 <ph name="MEGABYTES" /> MB)。</translation> <translation id="5441522332038954058">切換到網址列</translation> -<translation id="5447201525962359567">所有網站儲存的資料,包括 Cookie 和其他儲存在本機上的資料</translation> <translation id="545042621069398927">正在加快下載速度。</translation> <translation id="5456381639095306749">下載網頁</translation> <translation id="548278423535722844">在地圖應用程式中開啟</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb index 91bbbf0..8f568cae 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_zu.xtb
@@ -331,7 +331,6 @@ <translation id="3568688522516854065">Ukuze uthole amathebhu akho kusukela kwamanye amadivayisi akho, ngena ngemvume uphinde uvule ukuvumelanisa</translation> <translation id="3587482841069643663">Konke</translation> <translation id="3587596251841506391">Siza ukuthuthukisa ukuvikeleka kuwebhu</translation> -<translation id="3590487821116122040">I-Chrome yesitoreji sesayithi asicabangi ukuthi kubalulekile (isb. amasayithi anezilungiselelo ezingalondoloziwe noma ongawavakasheli kaningi)</translation> <translation id="3594780231884063836">Thulisa ividiyo</translation> <translation id="3599863153486145794">Isula umlando kusukela onke amadivayisi angene ngemvume. I-akhawunti ye-Google kungenzeka ibe namanye amafomu omlando wokuphequlula ku-<ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> <translation id="3616113530831147358">Umsindo</translation> @@ -384,7 +383,6 @@ <translation id="3987993985790029246">Kopisha isixhumanisi</translation> <translation id="3988213473815854515">Indawo ivunyelwe</translation> <translation id="3988466920954086464">Bona imiphumela yosesho esheshayo kule phaneli</translation> -<translation id="3997476611815694295">Isitoreji engabalulekile</translation> <translation id="4000212216660919741">Ikhaya elingaxhunyiwe ku-inthanethi</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# hr}one{# amahora}other{# amahora}}</translation> <translation id="4056223980640387499">I-Sepia</translation> @@ -562,7 +560,6 @@ <translation id="5433691172869980887">Igama lomsebenzisi likopishiwe</translation> <translation id="543509235395288790">Ilanda amafayela angu-<ph name="COUNT" /> (<ph name="MEGABYTES" />)</translation> <translation id="5441522332038954058">Yeqela kubha yekheli</translation> -<translation id="5447201525962359567">Sonke isitoreji sesayithi, kufaka phakathi amakhukhi nenye idatha elondolozwe ngokwendawo</translation> <translation id="545042621069398927">Isheshisa ukulanda kwakho.</translation> <translation id="5456381639095306749">Landa ikhasi</translation> <translation id="548278423535722844">Uhlelo lokusebenza lokuvula kumamephu</translation>
diff --git a/chrome/browser/ui/app_list/arc/arc_app_icon.cc b/chrome/browser/ui/app_list/arc/arc_app_icon.cc index 786befa..cb1f8904 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_icon.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_icon.cc
@@ -465,10 +465,12 @@ if (!base::PathExists(background_path)) { // For non-adaptive icon, there could be a |foreground_icon_path| file // only without a |background_icon_path| file. + base::UmaHistogramBoolean("Arc.AdaptiveIconLoad.FromArcAppIcon", false); return ArcAppIcon::ReadFile(false /* request_to_install */, scale_factor, false /* resize_allowed */, foreground_path); } + base::UmaHistogramBoolean("Arc.AdaptiveIconLoad.FromArcAppIcon", true); return ArcAppIcon::ReadFiles(false /* request_to_install */, scale_factor, false /* resize_allowed */, foreground_path, background_path); @@ -506,11 +508,14 @@ !base::PathExists(default_app_background_path)) { // For non-adaptive icon, there could be a |default_app_foreground_path| // file only without a |default_app_background_path| file. + base::UmaHistogramBoolean("Arc.AdaptiveIconLoad.FromArcDefaultAppIcon", + false); return ArcAppIcon::ReadFile(true /* request_to_install */, scale_factor, true /* resize_allowed */, default_app_foreground_path); } + base::UmaHistogramBoolean("Arc.AdaptiveIconLoad.FromArcDefaultAppIcon", true); return ArcAppIcon::ReadFiles( true /* request_to_install */, scale_factor, true /* resize_allowed */, default_app_foreground_path, default_app_background_path);
diff --git a/chrome/browser/ui/app_list/icon_standardizer.cc b/chrome/browser/ui/app_list/icon_standardizer.cc index a347097d..0093b75 100644 --- a/chrome/browser/ui/app_list/icon_standardizer.cc +++ b/chrome/browser/ui/app_list/icon_standardizer.cc
@@ -278,9 +278,52 @@ gfx::ImageSkia final_image; gfx::ImageSkia standard_size_image = app_list::StandardizeSize(image); - // If icon is already circle shaped, then return the original image. - if (IsIconCircleShaped(standard_size_image)) - return standard_size_image; + // If icon is already circle shaped, then return the original image and make + // sure the image is scaled down if its icon size takes up too much space + // within the bitmap. + if (IsIconCircleShaped(standard_size_image)) { + for (gfx::ImageSkiaRep rep : standard_size_image.image_reps()) { + SkBitmap unscaled_bitmap(rep.GetBitmap()); + int width = unscaled_bitmap.width(); + int height = unscaled_bitmap.height(); + + SkBitmap final_bitmap; + final_bitmap.allocN32Pixels(width, height); + final_bitmap.eraseColor(SK_ColorTRANSPARENT); + + float dis_to_center = GetFarthestVisiblePointFromCenter(unscaled_bitmap); + float icon_to_bitmap_size_ratio = dis_to_center * 2.0f / width; + + if (icon_to_bitmap_size_ratio > kBackgroundCircleScale) { + SkCanvas canvas(final_bitmap); + SkPaint paint_icon; + paint_icon.setMaskFilter(nullptr); + paint_icon.setBlendMode(SkBlendMode::kSrcOver); + + float icon_scale = kBackgroundCircleScale / icon_to_bitmap_size_ratio; + + gfx::Size scaled_icon_size = + gfx::ScaleToRoundedSize(rep.pixel_size(), icon_scale); + const SkBitmap scaled_bitmap = skia::ImageOperations::Resize( + unscaled_bitmap, skia::ImageOperations::RESIZE_BEST, + scaled_icon_size.width(), scaled_icon_size.height()); + + int target_left = (width - scaled_icon_size.width()) / 2; + int target_top = (height - scaled_icon_size.height()) / 2; + + // Draw the scaled down bitmap and add that to the final image. + canvas.drawBitmap(scaled_bitmap, target_left, target_top, &paint_icon); + final_image.AddRepresentation( + gfx::ImageSkiaRep(final_bitmap, rep.scale())); + } else { + // No need to scale down the icon, so just use the |unscaled_bitmap|. + final_image.AddRepresentation( + gfx::ImageSkiaRep(unscaled_bitmap, rep.scale())); + } + } + + return final_image; + } for (gfx::ImageSkiaRep rep : standard_size_image.image_reps()) { SkBitmap unscaled_bitmap(rep.GetBitmap());
diff --git a/chrome/browser/ui/app_list/icon_standardizer_unittest.cc b/chrome/browser/ui/app_list/icon_standardizer_unittest.cc index ebff92d..3c3b41bf 100644 --- a/chrome/browser/ui/app_list/icon_standardizer_unittest.cc +++ b/chrome/browser/ui/app_list/icon_standardizer_unittest.cc
@@ -7,16 +7,40 @@ #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_operations.h" +namespace { + +constexpr int kIconSize = 64; + +constexpr float kMaxCircleIconSize = 176.0f / 192.0f; +constexpr float kStandardCircleRadius = kIconSize * kMaxCircleIconSize / 2.0f; + +// Returns whether the bitmaps are equal. +bool AreBitmapsEqual(const SkBitmap& first_bitmap, + const SkBitmap& second_bitmap) { + const size_t size = first_bitmap.computeByteSize(); + bool bitmaps_equal = true; + + uint8_t* first_data = reinterpret_cast<uint8_t*>(first_bitmap.getPixels()); + uint8_t* second_data = reinterpret_cast<uint8_t*>(second_bitmap.getPixels()); + for (size_t i = 0; i < size; ++i) { + if (first_data[i] != second_data[i]) { + bitmaps_equal = false; + break; + } + } + + return bitmaps_equal; +} + +} // namespace + using CreateStandardIconTest = testing::Test; // Test that a square icon gets scaled down and drawn on top of a circular // background when converted to a standard icon. TEST_F(CreateStandardIconTest, SquareIconToStandardIcon) { - const int test_width = 64; - const int test_height = 64; - SkBitmap square_icon_bitmap; - square_icon_bitmap.allocN32Pixels(test_width, test_height); + square_icon_bitmap.allocN32Pixels(kIconSize, kIconSize); square_icon_bitmap.eraseColor(SK_ColorRED); gfx::ImageSkia standard_icon = app_list::CreateStandardIconImage( @@ -25,77 +49,81 @@ // Create |test_standard_bitmap| which will be a manually created standard // icon, with background circle and a scaled down square icon inside. SkBitmap test_standard_bitmap; - test_standard_bitmap.allocN32Pixels(test_width, test_height); + test_standard_bitmap.allocN32Pixels(kIconSize, kIconSize); test_standard_bitmap.eraseColor(SK_ColorTRANSPARENT); SkCanvas canvas(test_standard_bitmap); - float circle_diameter = test_width * (176.0f / 192.0f); SkPaint paint_background_circle; paint_background_circle.setAntiAlias(true); paint_background_circle.setColor(SK_ColorWHITE); paint_background_circle.setStyle(SkPaint::kFill_Style); canvas.drawCircle( - SkPoint::Make((test_width - 1) / 2.0f, (test_width - 1) / 2.0f), - circle_diameter / 2.0f, paint_background_circle); + SkPoint::Make((kIconSize - 1) / 2.0f, (kIconSize - 1) / 2.0f), + kStandardCircleRadius, paint_background_circle); const SkBitmap scaled_bitmap = skia::ImageOperations::Resize( square_icon_bitmap, skia::ImageOperations::RESIZE_BEST, 36, 36); canvas.drawBitmap(scaled_bitmap, 14, 14); - // Test that |standard_icon| has an identical bitmap to - // |test_standard_bitmap|. - const size_t size = standard_icon.bitmap()->computeByteSize(); - bool bitmaps_equal = true; - - uint8_t* first_data = - reinterpret_cast<uint8_t*>(standard_icon.bitmap()->getPixels()); - uint8_t* second_data = - reinterpret_cast<uint8_t*>(test_standard_bitmap.getPixels()); - for (size_t i = 0; i < size; ++i) { - if (first_data[i] != second_data[i]) { - bitmaps_equal = false; - break; - } - } - EXPECT_TRUE(bitmaps_equal); + EXPECT_TRUE(AreBitmapsEqual(*standard_icon.bitmap(), test_standard_bitmap)); } -// Test that a circular icon stays the same when converted to a standard icon. +// Test that a large circular icon gets scaled down when converted to a standard +// icon. TEST_F(CreateStandardIconTest, CircularIconToStandardIcon) { - const int test_width = 64; - const int test_height = 64; - - // Create a bitmap with a red circle as a placeholder circular icon. + // Create a bitmap for drawing a red circle as a placeholder circular icon. SkBitmap circle_icon_bitmap; - circle_icon_bitmap.allocN32Pixels(test_width, test_height); + circle_icon_bitmap.allocN32Pixels(kIconSize, kIconSize); circle_icon_bitmap.eraseColor(SK_ColorTRANSPARENT); SkCanvas canvas(circle_icon_bitmap); - SkPaint paint_cirlce_icon; - paint_cirlce_icon.setAntiAlias(true); - paint_cirlce_icon.setColor(SK_ColorRED); - paint_cirlce_icon.setStyle(SkPaint::kFill_Style); - canvas.drawCircle(SkPoint::Make(test_width / 2, test_width / 2), - test_width / 2, paint_cirlce_icon); + SkPaint paint_circle_icon; + paint_circle_icon.setAntiAlias(true); + paint_circle_icon.setColor(SK_ColorRED); + paint_circle_icon.setStyle(SkPaint::kFill_Style); + canvas.drawCircle(SkPoint::Make(kIconSize / 2, kIconSize / 2), kIconSize / 2, + paint_circle_icon); + + // Get the standard icon version of the red circle icon. + gfx::ImageSkia generated_standard_icon = app_list::CreateStandardIconImage( + gfx::ImageSkia(gfx::ImageSkiaRep(circle_icon_bitmap, 2.0f))); + + // Scale the bitmap to fit the size of a standardized circle icon. + SkBitmap scaled_bitmap = skia::ImageOperations::Resize( + circle_icon_bitmap, skia::ImageOperations::RESIZE_BEST, 58, 58); + + // Draw the |scaled_bitmap| to |manually_scaled_bitmap| to ensure the size + // of the bitmap is the same as the |generated_standard_icon| for comparison. + SkBitmap manually_scaled_bitmap; + manually_scaled_bitmap.allocN32Pixels(kIconSize, kIconSize); + manually_scaled_bitmap.eraseColor(SK_ColorTRANSPARENT); + SkCanvas canvas2(manually_scaled_bitmap); + canvas2.drawBitmap(scaled_bitmap, 3, 3); + + EXPECT_TRUE(AreBitmapsEqual(*generated_standard_icon.bitmap(), + manually_scaled_bitmap)); +} + +// Test that a circle icon that is already standard size, keeps the same size +// when standardized. +TEST_F(CreateStandardIconTest, StandardCircularIconToStandardIcon) { + // Create a bitmap with a red circle as a placeholder circular icon. + SkBitmap circle_icon_bitmap; + circle_icon_bitmap.allocN32Pixels(kIconSize, kIconSize); + circle_icon_bitmap.eraseColor(SK_ColorTRANSPARENT); + + SkCanvas canvas(circle_icon_bitmap); + SkPaint paint_circle_icon; + paint_circle_icon.setAntiAlias(true); + paint_circle_icon.setColor(SK_ColorRED); + paint_circle_icon.setStyle(SkPaint::kFill_Style); + canvas.drawCircle(SkPoint::Make(kIconSize / 2.0f, kIconSize / 2.0f), + kStandardCircleRadius, paint_circle_icon); // Get the standard icon version of the red circle icon. gfx::ImageSkia standard_icon = app_list::CreateStandardIconImage( gfx::ImageSkia(gfx::ImageSkiaRep(circle_icon_bitmap, 2.0f))); - // Test that |standard_icon| has an identical bitmap to |circle_icon_bitmap|. - const size_t size = standard_icon.bitmap()->computeByteSize(); - bool bitmaps_equal = true; - - uint8_t* first_data = - reinterpret_cast<uint8_t*>(standard_icon.bitmap()->getPixels()); - uint8_t* second_data = - reinterpret_cast<uint8_t*>(circle_icon_bitmap.getPixels()); - for (size_t i = 0; i < size; ++i) { - if (first_data[i] != second_data[i]) { - bitmaps_equal = false; - break; - } - } - EXPECT_TRUE(bitmaps_equal); + EXPECT_TRUE(AreBitmapsEqual(*standard_icon.bitmap(), circle_icon_bitmap)); }
diff --git a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc index 5857022e..b7cf75d 100644 --- a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc +++ b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.cc
@@ -20,6 +20,8 @@ #include "chrome/browser/apps/app_service/app_service_metrics.h" #include "chrome/browser/chromeos/plugin_vm/plugin_vm_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/release_notes/release_notes_storage.h" +#include "chrome/browser/chromeos/web_applications/default_web_app_ids.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/session_sync_service_factory.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" @@ -69,13 +71,6 @@ /*recommendable=*/true, /*searchable=*/false, /*show_in_launcher=*/false, apps::BuiltInAppName::kContinueReading, - /*searchable_string_resource_id=*/0}, - - {ash::kReleaseNotesAppId, IDS_RELEASE_NOTES_NOTIFICATION_TITLE, - IDR_RELEASE_NOTES_APP_192, - /*recommendable=*/true, - /*searchable=*/false, - /*show_in_launcher=*/false, apps::BuiltInAppName::kReleaseNotes, /*searchable_string_resource_id=*/0}}); static base::NoDestructor<std::vector<InternalApp>> internal_app_list; @@ -83,6 +78,17 @@ internal_app_list->insert(internal_app_list->begin(), internal_app_list_static->begin(), internal_app_list_static->end()); + + if (!base::FeatureList::IsEnabled(chromeos::features::kHelpAppReleaseNotes)) { + internal_app_list->push_back( + {ash::kReleaseNotesAppId, IDS_RELEASE_NOTES_NOTIFICATION_TITLE, + IDR_RELEASE_NOTES_APP_192, + /*recommendable=*/true, + /*searchable=*/false, + /*show_in_launcher=*/false, apps::BuiltInAppName::kReleaseNotes, + /*searchable_string_resource_id=*/0}); + } + const bool add_discover_app = get_all || !chromeos::ProfileHelper::IsEphemeralUserProfile(profile); if (base::FeatureList::IsEnabled(chromeos::features::kDiscoverApp) && @@ -118,14 +124,21 @@ return GetInternalAppListImpl(false, profile); } -bool IsSuggestionChip(const std::string& app_id) { - // App IDs for internal apps which should only be shown as suggestion chips. - static const char* kSuggestionChipIds[] = {ash::kInternalAppIdContinueReading, - ash::kReleaseNotesAppId}; +bool IsSuggestionChip(const std::string& app_id, Profile* profile) { + if (base::LowerCaseEqualsASCII(app_id, ash::kInternalAppIdContinueReading)) + return true; - for (size_t i = 0; i < base::size(kSuggestionChipIds); ++i) { - if (base::LowerCaseEqualsASCII(app_id, kSuggestionChipIds[i])) + if (!base::FeatureList::IsEnabled(chromeos::features::kHelpAppReleaseNotes)) { + if (base::LowerCaseEqualsASCII(app_id, ash::kReleaseNotesAppId)) return true; + } else { + // We show the Help App as a release notes suggestion chip a certain + // number of times. + if (chromeos::ReleaseNotesStorage(profile).ShouldShowSuggestionChip() && + base::LowerCaseEqualsASCII(app_id, + chromeos::default_web_apps::kHelpAppId)) { + return true; + } } return false; }
diff --git a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.h b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.h index 5e9c59cd19..5803e7a 100644 --- a/chrome/browser/ui/app_list/internal_app/internal_app_metadata.h +++ b/chrome/browser/ui/app_list/internal_app/internal_app_metadata.h
@@ -54,7 +54,7 @@ const std::vector<InternalApp>& GetInternalAppList(const Profile* profile); // Returns true if the app should only be shown as a suggestion chip. -bool IsSuggestionChip(const std::string& app_id); +bool IsSuggestionChip(const std::string& app_id, Profile* profile); // Returns InternalApp by |app_id|. // Returns nullptr if |app_id| does not correspond to an internal app.
diff --git a/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc b/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc index d16a226..e9db52f 100644 --- a/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc +++ b/chrome/browser/ui/app_list/search/app_list_search_browsertest.cc
@@ -9,9 +9,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind_test_util.h" #include "base/test/scoped_feature_list.h" -#include "chrome/browser/chromeos/login/login_manager_test.h" -#include "chrome/browser/chromeos/login/test/login_manager_mixin.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/browser/chromeos/web_applications/default_web_app_ids.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" @@ -19,8 +17,14 @@ #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/search_controller.h" #include "chrome/browser/ui/app_list/test/chrome_app_list_test_support.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/web_applications/system_web_app_manager.h" +#include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/common/chrome_paths.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/in_process_browser_test.h" #include "chromeos/constants/chromeos_features.h" +#include "components/prefs/pref_service.h" #include "content/public/test/browser_test.h" namespace app_list { @@ -30,13 +34,12 @@ // results that would be displayed via the AppListModelUpdater. This class is // also intended as in-code documentation for how to create future app list // search integration tests. -class AppListSearchBrowserTest : public chromeos::LoginManagerTest { +class AppListSearchBrowserTest : public InProcessBrowserTest { public: using ResultType = ash::AppListSearchResultType; + using DisplayType = ash::SearchResultDisplayType; - AppListSearchBrowserTest() : LoginManagerTest() { - login_mixin_.AppendRegularUsers(1); - } + AppListSearchBrowserTest() {} ~AppListSearchBrowserTest() override = default; AppListSearchBrowserTest(const AppListSearchBrowserTest&) = delete; @@ -110,39 +113,7 @@ // Session helpers //---------------- - Profile* GetProfile() { - auto* profile = ProfileManager::GetActiveUserProfile(); - CHECK(profile); - return profile; - } - - base::FilePath GetProfileDir() { return profile_dir_; } - - void DoLogin() { LoginUser(login_mixin_.users()[0].account_id); } - - //----- - // Misc - //----- - - // LoginManagerTest: - bool SetUpUserDataDirectory() override { - base::FilePath user_data_dir; - base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); - const std::string& email = - login_mixin_.users()[0].account_id.GetUserEmail(); - const std::string user_id_hash = - chromeos::ProfileHelper::GetUserIdHashByUserIdForTesting(email); - profile_dir_ = user_data_dir.Append( - chromeos::ProfileHelper::GetUserProfileDir(user_id_hash)); - base::CreateDirectory(profile_dir_); - - return true; - } - - protected: - base::FilePath profile_dir_; - - chromeos::LoginManagerMixin login_mixin_{&mixin_host_}; + Profile* GetProfile() { return browser()->profile(); } }; // Test fixture for OS settings search. This subclass exists because changing a @@ -166,9 +137,27 @@ base::test::ScopedFeatureList scoped_feature_list_; }; +// Test fixture for Release notes search. This subclass exists because changing +// a feature flag has to be done in the constructor. Otherwise, it could use +// AppListSearchBrowserTest directly. +class ReleaseNotesSearchBrowserTest : public AppListSearchBrowserTest { + public: + ReleaseNotesSearchBrowserTest() : AppListSearchBrowserTest() { + scoped_feature_list_.InitWithFeatures( + {chromeos::features::kHelpAppReleaseNotes}, {}); + } + ~ReleaseNotesSearchBrowserTest() override = default; + + ReleaseNotesSearchBrowserTest(const ReleaseNotesSearchBrowserTest&) = delete; + ReleaseNotesSearchBrowserTest& operator=( + const ReleaseNotesSearchBrowserTest&) = delete; + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + // Simply tests that neither zero-state nor query-based search cause a crash. IN_PROC_BROWSER_TEST_F(AppListSearchBrowserTest, SearchDoesntCrash) { - DoLogin(); // This won't catch everything, because not all providers run on all queries, // and so we can't wait for all providers to finish. Instead, we wait on one // app and one non-app provider. Note file search (kLauncher) is generally the @@ -181,7 +170,9 @@ // Test that searching for "wifi" correctly returns a settings result for wifi. IN_PROC_BROWSER_TEST_F(OsSettingsSearchBrowserTest, AppListSearchForSettings) { - DoLogin(); + web_app::WebAppProvider::Get(GetProfile()) + ->system_web_app_manager() + .InstallSystemAppsForTesting(); SearchAndWaitForProviders("wifi", {ResultType::kOsSettings}); auto* result = FindResult("os-settings://networks?type=WiFi"); @@ -190,4 +181,52 @@ "Wi-Fi networks, Network, Settings"); } +// Test that Help App shows up as Release notes if pref shows we have some times +// left to show it. +IN_PROC_BROWSER_TEST_F(ReleaseNotesSearchBrowserTest, + AppListSearchHasSuggestionChip) { + web_app::WebAppProvider::Get(GetProfile()) + ->system_web_app_manager() + .InstallSystemAppsForTesting(); + GetProfile()->GetPrefs()->SetInteger( + prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 1); + + SearchAndWaitForProviders("", + {ResultType::kInstalledApp, ResultType::kLauncher}); + + auto* result = FindResult(chromeos::default_web_apps::kHelpAppId); + ASSERT_TRUE(result); + // Has Release notes title. + EXPECT_EQ(base::UTF16ToASCII(result->title()), + "See what's new on your Chrome device"); + // Displayed in first position. + EXPECT_EQ(result->position_priority(), 1.0f); + // Has override url defined for updates tab. + EXPECT_EQ(result->query_url(), GURL("chrome://help-app/updates")); + EXPECT_EQ(result->display_type(), DisplayType::kChip); +} + +// Test that Help App shows up normally if pref shows we should no longer show +// as suggestion chip. +IN_PROC_BROWSER_TEST_F(ReleaseNotesSearchBrowserTest, AppListSearchHasApp) { + web_app::WebAppProvider::Get(GetProfile()) + ->system_web_app_manager() + .InstallSystemAppsForTesting(); + GetProfile()->GetPrefs()->SetInteger( + prefs::kReleaseNotesSuggestionChipTimesLeftToShow, 0); + + SearchAndWaitForProviders("", + {ResultType::kInstalledApp, ResultType::kLauncher}); + + auto* result = FindResult(chromeos::default_web_apps::kHelpAppId); + ASSERT_TRUE(result); + // Has regular app name as title. + EXPECT_EQ(base::UTF16ToASCII(result->title()), "Explore"); + // No priority for position. + EXPECT_EQ(result->position_priority(), 0); + // No override url (will open app at default page). + EXPECT_FALSE(result->query_url().has_value()); + EXPECT_EQ(result->display_type(), DisplayType::kTile); +} + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/app_search_provider.cc b/chrome/browser/ui/app_list/search/app_search_provider.cc index c23fa6ed..bc65b06 100644 --- a/chrome/browser/ui/app_list/search/app_search_provider.cc +++ b/chrome/browser/ui/app_list/search/app_search_provider.cc
@@ -33,6 +33,7 @@ #include "chrome/browser/chromeos/crostini/crostini_manager.h" #include "chrome/browser/chromeos/extensions/gfx_utils.h" #include "chrome/browser/chromeos/release_notes/release_notes_storage.h" +#include "chrome/browser/chromeos/web_applications/default_web_app_ids.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/session_sync_service_factory.h" @@ -42,11 +43,13 @@ #include "chrome/browser/ui/app_list/search/app_service_app_result.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/app_search_result_ranker.h" #include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h" +#include "chrome/grit/generated_resources.h" #include "chromeos/components/string_matching/fuzzy_tokenized_string_match.h" #include "chromeos/components/string_matching/tokenized_string.h" #include "chromeos/components/string_matching/tokenized_string_match.h" #include "components/sync/base/model_type.h" #include "components/sync_sessions/session_sync_service.h" +#include "ui/chromeos/devicetype_utils.h" namespace { @@ -509,6 +512,18 @@ app->data_source()->CreateResult(app->id(), list_controller_, true); result->SetTitle(title); + if (app->id() == chromeos::default_web_apps::kHelpAppId) { + auto release_notes_storage = + std::make_unique<chromeos::ReleaseNotesStorage>(profile_); + // If we should show the release notes suggestion chip, change the title + // and url of the Help App. Otherwise leave as normal. + if (release_notes_storage->ShouldShowSuggestionChip()) { + result->SetTitle(ui::SubstituteChromeOSDeviceType( + IDS_RELEASE_NOTES_DEVICE_SPECIFIC_NOTIFICATION_TITLE)); + result->SetQueryUrl(GURL("chrome://help-app/updates")); + } + } + const auto find_in_app_list = id_to_app_list_index.find(app->id()); const base::Time time = app->GetLastActivityTime();
diff --git a/chrome/browser/ui/app_list/search/app_service_app_result.cc b/chrome/browser/ui/app_list/search/app_service_app_result.cc index 516e4d4..e2f78be 100644 --- a/chrome/browser/ui/app_list/search/app_service_app_result.cc +++ b/chrome/browser/ui/app_list/search/app_service_app_result.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/chromeos/release_notes/release_notes_storage.h" +#include "chrome/browser/chromeos/web_applications/default_web_app_ids.h" #include "chrome/browser/favicon/large_icon_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_list_client_impl.h" @@ -19,6 +20,8 @@ #include "chrome/browser/ui/app_list/app_service/app_service_context_menu.h" #include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" +#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" +#include "chrome/browser/web_applications/system_web_app_manager.h" #include "chrome/common/chrome_features.h" #include "components/favicon/core/large_icon_service.h" #include "components/services/app_service/public/cpp/app_update.h" @@ -74,7 +77,7 @@ break; } - if (IsSuggestionChip(id())) + if (IsSuggestionChip(id(), profile)) HandleSuggestionChip(profile); } @@ -154,6 +157,13 @@ apps::AppServiceProxy* proxy = apps::AppServiceProxyFactory::GetForProfile(profile()); + if (id() == chromeos::default_web_apps::kHelpAppId && + query_url().has_value()) { + proxy->LaunchAppWithUrl(app_id(), event_flags, query_url().value(), + launch_source, controller()->GetAppListDisplayId()); + return; + } + // For Chrome apps or Web apps, if it is non-platform app, it could be // selecting an existing delegate for the app, so call // ChromeLauncherController's ActivateApp interface. Platform apps or ARC @@ -236,7 +246,9 @@ SetDisplayIndex(ash::SearchResultDisplayIndex::kFirstIndex); SetDisplayType(ash::SearchResultDisplayType::kChip); - if (id() == ash::kReleaseNotesAppId) { + // Either of these apps could be shown as the release notes suggestion chip. + if (id() == ash::kReleaseNotesAppId || + id() == chromeos::default_web_apps::kHelpAppId) { SetNotifyVisibilityChange(true); // Make sure that if both Continue Reading and Release Notes are available, // Release Notes shows up first in the suggestion chip container.
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc index e03b55d..632fd12 100644 --- a/chrome/browser/ui/browser_navigator.cc +++ b/chrome/browser/ui/browser_navigator.cc
@@ -33,6 +33,7 @@ #include "chrome/browser/ui/status_bubble.h" #include "chrome/browser/ui/tab_helpers.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" @@ -465,6 +466,37 @@ params->initiating_profile = source_browser->profile(); DCHECK(params->initiating_profile); + if (source_browser && + platform_util::IsBrowserLockedFullscreen(source_browser)) { + // Block any navigation requests in locked fullscreen mode. + return; + } + + // Open System Apps in their standalone window if necessary. + // TODO(crbug.com/1096345): Remove this code after we integrate with intent + // handling. + const base::Optional<web_app::SystemAppType> capturing_system_app_type = + web_app::GetCapturingSystemAppForURL(params->initiating_profile, + params->url); + if (capturing_system_app_type && + (!params->browser || + !web_app::IsBrowserForSystemWebApp(params->browser, + capturing_system_app_type.value()))) { + params->browser = web_app::LaunchSystemWebApp( + params->initiating_profile, capturing_system_app_type.value(), + params->url); + + // It's okay to early return here, because LaunchSystemWebApp uses a + // different logic to choose (and create if necessary) a browser window for + // system apps. + // + // It's okay to skip the checks and cleanups below. The link captured system + // app will either open in its own browser window, or navigate an existing + // browser window exclusively used by this app. For the initiating browser, + // the navigation should appear to be cancelled. + return; + } + if (!AdjustNavigateParamsForURL(params)) return; @@ -478,12 +510,6 @@ params->url = GURL(chrome::kExtensionInvalidRequestURL); #endif - if (source_browser && - platform_util::IsBrowserLockedFullscreen(source_browser)) { - // Block any navigation requests in locked fullscreen mode. - return; - } - // Trying to open a background tab when in an app browser results in // focusing a regular browser window an opening a tab in the background // of that window. Change the disposition to NEW_FOREGROUND_TAB so that @@ -529,7 +555,8 @@ #if defined(OS_CHROMEOS) if (source_browser) { // Open OS settings in PWA, even when user types in URL bar. - if (params->url.host() == chrome::kChromeUIOSSettingsHost && + if (params->url.GetOrigin() == + GURL(chrome::kChromeUIOSSettingsURL).GetOrigin() && !allow_os_settings_in_tab) { chrome::SettingsWindowManager* settings_window_manager = chrome::SettingsWindowManager::GetInstance();
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 3121e73..3c5b31b 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -301,7 +301,7 @@ // Called from toolbar subviews during their show/hide animations. virtual void ToolbarSizeChanged(bool is_animating) = 0; - // Called when the accociated window's tab dragging status changed. + // Called when the associated window's tab dragging status changed. virtual void TabDraggingStatusChanged(bool is_dragging) = 0; // Focuses the app menu like it was a menu bar.
diff --git a/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm b/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm index 088c16cd..38a58ff 100644 --- a/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm +++ b/chrome/browser/ui/cocoa/renderer_context_menu/render_view_context_menu_mac_cocoa.mm
@@ -199,6 +199,7 @@ void RenderViewContextMenuMacCocoa::Show() { menu_controller_.reset([[MenuControllerCocoa alloc] initWithModel:&menu_model_ + delegate:nil useWithPopUpButtonCell:NO]); gfx::Point params_position(params_.x, params_.y);
diff --git a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm index c960930e7..ad6eda0 100644 --- a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm +++ b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm
@@ -110,11 +110,13 @@ if (!toolTip) { menu_.reset([[MenuControllerCocoa alloc] initWithModel:model + delegate:nil useWithPopUpButtonCell:NO]); } else { // When using a popup button cell menu controller, an extra blank item is // added at index 0. Use this item for the tooltip. menu_.reset([[MenuControllerCocoa alloc] initWithModel:model + delegate:nil useWithPopUpButtonCell:YES]); NSMenuItem* toolTipItem = [[menu_ menu] itemAtIndex:0]; [toolTipItem setTitle:toolTip];
diff --git a/chrome/browser/ui/popup_browsertest.cc b/chrome/browser/ui/popup_browsertest.cc index 675c7d8..414f23e 100644 --- a/chrome/browser/ui/popup_browsertest.cc +++ b/chrome/browser/ui/popup_browsertest.cc
@@ -16,6 +16,8 @@ #include "content/public/test/browser_test.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/views/widget/widget.h" +#include "ui/views/widget/widget_observer.h" #include "url/gurl.h" namespace { @@ -39,47 +41,184 @@ "WindowPlacement"); } + display::Display GetDisplayNearestBrowser(const Browser* browser) const { + return display::Screen::GetScreen()->GetDisplayNearestWindow( + browser->window()->GetNativeWindow()); + } + + Browser* OpenPopup(Browser* browser, const std::string& script) const { + auto* contents = browser->tab_strip_model()->GetActiveWebContents(); + content::ExecuteScriptAsync(contents, script); + Browser* popup = ui_test_utils::WaitForBrowserToOpen(); + EXPECT_NE(popup, browser); + auto* popup_contents = popup->tab_strip_model()->GetActiveWebContents(); + EXPECT_TRUE(WaitForRenderFrameReady(popup_contents->GetMainFrame())); + return popup; + } + private: DISALLOW_COPY_AND_ASSIGN(PopupBrowserTest); }; INSTANTIATE_TEST_SUITE_P(All, PopupBrowserTest, ::testing::Bool()); -// Ensure that popup windows are clamped within the available screen space. -IN_PROC_BROWSER_TEST_P(PopupBrowserTest, WindowClampedToScreenSpace) { - auto* contents = browser()->tab_strip_model()->GetActiveWebContents(); - auto* screen = display::Screen::GetScreen(); - const auto& displays = screen->GetAllDisplays(); - EXPECT_GE(displays.size(), 1U) << "Expected at least one display"; - const auto display = - screen->GetDisplayNearestWindow(browser()->window()->GetNativeWindow()); - EXPECT_TRUE(display.bounds().Contains(browser()->window()->GetBounds())) - << "The browser window bounds should be contained by its display"; +// A helper class to wait for widget bounds changes beyond given thresholds. +class WidgetBoundsChangeWaiter : public views::WidgetObserver { + public: + WidgetBoundsChangeWaiter(views::Widget* widget, int move_by, int resize_by) + : widget_(widget), + move_by_(move_by), + resize_by_(resize_by), + initial_bounds_(widget->GetWindowBoundsInScreen()) { + widget_->AddObserver(this); + } - // Attempt to open a window outside the bounds of the originator's display. - const char OPEN_POPUP_OFFSCREEN[] = - "var l = screen.availLeft + screen.availWidth + 100;" - "var t = screen.availTop + 100;" - "window.open(\"\", \"\"," - " \"left=\"+l+\",top=\"+t+\",width=300,height=300\");"; - contents->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( - base::ASCIIToUTF16(OPEN_POPUP_OFFSCREEN)); - Browser* popup = ui_test_utils::WaitForBrowserToOpen(); - EXPECT_NE(popup, browser()); + WidgetBoundsChangeWaiter(const WidgetBoundsChangeWaiter&) = delete; + WidgetBoundsChangeWaiter& operator=(const WidgetBoundsChangeWaiter&) = delete; + ~WidgetBoundsChangeWaiter() final { widget_->RemoveObserver(this); } - // The popup window should be clamped within the available screen space. - // With experimental WindowPlacement, the popup may be on another display. - const auto popup_display = - screen->GetDisplayNearestWindow(popup->window()->GetNativeWindow()); - if (!GetParam()) - EXPECT_EQ(display, popup_display); + // views::WidgetObserver: + void OnWidgetBoundsChanged(views::Widget* widget, + const gfx::Rect& rect) final { + if (BoundsChangeMeetsThreshold(rect)) { + widget_->RemoveObserver(this); + run_loop_.Quit(); + } + } - auto popup_display_bounds = popup_display.bounds(); -#if defined(OS_WIN) - // TODO(crbug.com/1023054) Windows should more strictly clamp popup bounds. - popup_display_bounds.Inset(-20, -20); -#endif // OS_WIN - EXPECT_TRUE(popup_display_bounds.Contains(popup->window()->GetBounds())); + // Wait for changes to occur, or return immediately if they already have. + void Wait() { + if (!BoundsChangeMeetsThreshold(widget_->GetWindowBoundsInScreen())) + run_loop_.Run(); + } + + private: + bool BoundsChangeMeetsThreshold(const gfx::Rect& rect) const { + return (std::abs(rect.x() - initial_bounds_.x()) >= move_by_ || + std::abs(rect.y() - initial_bounds_.y()) >= move_by_) && + (std::abs(rect.width() - initial_bounds_.width()) >= resize_by_ || + std::abs(rect.height() - initial_bounds_.height()) >= resize_by_); + } + + views::Widget* const widget_; + const int move_by_, resize_by_; + const gfx::Rect initial_bounds_; + base::RunLoop run_loop_; +}; + +// Ensure popups are opened in the available space of the opener's display. +IN_PROC_BROWSER_TEST_P(PopupBrowserTest, OpenClampedToCurrentDisplay) { + const auto display = GetDisplayNearestBrowser(browser()); + EXPECT_TRUE(display.work_area().Contains(browser()->window()->GetBounds())) + << "The browser window should be contained by its display's work area"; + + // Attempt to open a popup outside the bounds of the opener's display. + const char* const open_scripts[] = { + "open('.', '', 'left=' + (screen.availLeft - 50));", + "open('.', '', 'left=' + (screen.availLeft + screen.availWidth + 50));", + "open('.', '', 'top=' + (screen.availTop - 50));", + "open('.', '', 'top=' + (screen.availTop + screen.availHeight + 50));", + "open('.', '', 'left=' + (screen.availLeft - 50) + " + "',top=' + (screen.availTop - 50));", + "open('.', '', 'left=' + (screen.availLeft - 50) + " + "',top=' + (screen.availTop - 50) + " + "',width=300,height=300');", + "open('.', '', 'left=' + (screen.availLeft + screen.availWidth + 50) + " + "',top=' + (screen.availTop + screen.availHeight + 50) + " + "',width=300,height=300');", + "open('.', '', 'left=' + screen.availLeft + ',top=' + screen.availTop + " + "',width=' + (screen.availWidth + 300) + ',height=300');", + "open('.', '', 'left=' + screen.availLeft + ',top=' + screen.availTop + " + "',width=300,height='+ (screen.availHeight + 300));", + "open('.', '', 'left=' + screen.availLeft + ',top=' + screen.availTop + " + "',width=' + (screen.availWidth + 300) + " + "',height='+ (screen.availHeight + 300));", + }; + for (auto* const script : open_scripts) { + Browser* popup = OpenPopup(browser(), script); + // The popup should be constrained to the opener's available display space. + // TODO(crbug.com/897300): Wait for the final window placement to occur; + // this is flakily checking initial or intermediate window placement bounds. + EXPECT_EQ(display, GetDisplayNearestBrowser(popup)); + EXPECT_TRUE(display.work_area().Contains(popup->window()->GetBounds())) + << " script: " << script + << " work_area: " << display.work_area().ToString() + << " popup: " << popup->window()->GetBounds().ToString(); + } +} + +// Ensure popups cannot be moved beyond the available display space by script. +IN_PROC_BROWSER_TEST_P(PopupBrowserTest, MoveClampedToCurrentDisplay) { + const auto display = GetDisplayNearestBrowser(browser()); + const char kOpenPopup[] = + "open('.', '', 'left=' + (screen.availLeft + 50) + " + "',top=' + (screen.availTop + 50) + " + "',width=300,height=300');"; + const char* const kMoveScripts[] = { + "moveBy(screen.availWidth * 2, 0);", + "moveBy(screen.availWidth * -2, 0);", + "moveBy(0, screen.availHeight * 2);", + "moveBy(0, screen.availHeight * -2);", + "moveBy(screen.availWidth * 2, screen.availHeight * 2);", + "moveBy(screen.availWidth * -2, screen.availHeight * -2);", + "moveTo(screen.availLeft + screen.availWidth + 50, screen.availTop);", + "moveTo(screen.availLeft - 50, screen.availTop);", + "moveTo(screen.availLeft, screen.availTop + screen.availHeight + 50);", + "moveTo(screen.availLeft, screen.availTop - 50);", + "moveTo(screen.availLeft + screen.availWidth + 50, " + "screen.availTop + screen.availHeight + 50);", + "moveTo(screen.availLeft - 50, screen.availTop - 50);", + }; + for (auto* const script : kMoveScripts) { + Browser* popup = OpenPopup(browser(), kOpenPopup); + auto popup_bounds = popup->window()->GetBounds(); + auto* popup_contents = popup->tab_strip_model()->GetActiveWebContents(); + auto* widget = views::Widget::GetWidgetForNativeWindow( + popup->window()->GetNativeWindow()); + + content::ExecuteScriptAsync(popup_contents, script); + // Wait for the substantial move, widgets may move during initialization. + WidgetBoundsChangeWaiter(widget, /*move_by=*/40, /*resize_by=*/0).Wait(); + EXPECT_NE(popup_bounds.origin(), popup->window()->GetBounds().origin()); + EXPECT_EQ(popup_bounds.size(), popup->window()->GetBounds().size()); + EXPECT_TRUE(display.work_area().Contains(popup->window()->GetBounds())) + << " script: " << script + << " work_area: " << display.work_area().ToString() + << " popup: " << popup_bounds.ToString(); + } +} + +// Ensure popups cannot be resized beyond the available display space by script. +IN_PROC_BROWSER_TEST_P(PopupBrowserTest, ResizeClampedToCurrentDisplay) { + const auto display = GetDisplayNearestBrowser(browser()); + const char kOpenPopup[] = + "open('.', '', 'left=' + (screen.availLeft + 50) + " + "',top=' + (screen.availTop + 50) + " + "',width=300,height=300');"; + // The popup cannot be resized beyond the current screen by script. + const char* const kResizeScripts[] = { + "resizeBy(screen.availWidth * 2, 0);", + "resizeBy(0, screen.availHeight * 2);", + "resizeTo(screen.availWidth + 200, 200);", + "resizeTo(200, screen.availHeight + 200);", + "resizeTo(screen.availWidth + 200, screen.availHeight + 200);", + }; + for (auto* const script : kResizeScripts) { + Browser* popup = OpenPopup(browser(), kOpenPopup); + auto popup_bounds = popup->window()->GetBounds(); + auto* popup_contents = popup->tab_strip_model()->GetActiveWebContents(); + auto* widget = views::Widget::GetWidgetForNativeWindow( + popup->window()->GetNativeWindow()); + + content::ExecuteScriptAsync(popup_contents, script); + // Wait for the substantial resize, widgets may move during initialization. + WidgetBoundsChangeWaiter(widget, /*move_by=*/0, /*resize_by=*/100).Wait(); + EXPECT_NE(popup_bounds.size(), popup->window()->GetBounds().size()); + EXPECT_TRUE(display.work_area().Contains(popup->window()->GetBounds())) + << " script: " << script + << " work_area: " << display.work_area().ToString() + << " popup: " << popup_bounds.ToString(); + } } } // namespace
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index f1837fb..35d9c77 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -87,6 +87,7 @@ #include "chrome/common/buildflags.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" +#include "chrome/services/machine_learning/machine_learning_tflite_buildflags.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_manager.h" #include "components/blocked_content/popup_blocker_tab_helper.h" @@ -186,6 +187,10 @@ #include "chrome/browser/supervised_user/supervised_user_navigation_observer.h" #endif +#if BUILDFLAG(BUILD_WITH_TFLITE_LIB) +#include "chrome/browser/tflite_experiment/tflite_experiment_observer.h" +#endif + using content::WebContents; namespace { @@ -255,6 +260,11 @@ InstallableManager::CreateForWebContents(web_contents); IsolatedPrerenderTabHelper::CreateForWebContents(web_contents); LiteVideoObserver::MaybeCreateForWebContents(web_contents); + +#if BUILDFLAG(BUILD_WITH_TFLITE_LIB) + TFLiteExperimentObserver::CreateForWebContents(web_contents); +#endif + if (MediaEngagementService::IsEnabled()) MediaEngagementService::CreateWebContentsObserver(web_contents); if (base::FeatureList::IsEnabled(media::kUseMediaHistoryStore))
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc index 69e6678b..71ea200a 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -180,18 +180,15 @@ .SetTitle(l10n_util::GetStringUTF16( already_bookmarked ? IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARK : IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARKED)) - .SetAcceptCallback(base::BindOnce(&BookmarkBubbleDelegate::ApplyEdits, - base::Unretained(bubble_delegate))) - .SetCancelCallback( - base::BindOnce(&BookmarkBubbleDelegate::RemoveBookmark, - base::Unretained(bubble_delegate))) .SetWindowClosingCallback( base::BindOnce(&BookmarkBubbleDelegate::OnWindowClosing, base::Unretained(bubble_delegate))) - .AddDialogButton(ui::DIALOG_BUTTON_OK, - l10n_util::GetStringUTF16(IDS_DONE)) - .AddDialogButton( - ui::DIALOG_BUTTON_CANCEL, + .AddOkButton(base::BindOnce(&BookmarkBubbleDelegate::ApplyEdits, + base::Unretained(bubble_delegate)), + l10n_util::GetStringUTF16(IDS_DONE)) + .AddCancelButton( + base::BindOnce(&BookmarkBubbleDelegate::RemoveBookmark, + base::Unretained(bubble_delegate)), l10n_util::GetStringUTF16(IDS_BOOKMARK_BUBBLE_REMOVE_BOOKMARK), ui::DialogModelButton::Params().AddAccelerator( ui::Accelerator(ui::VKEY_R, ui::EF_ALT_DOWN)))
diff --git a/chrome/browser/ui/views/borealis/OWNERS b/chrome/browser/ui/views/borealis/OWNERS new file mode 100644 index 0000000..1f1a286 --- /dev/null +++ b/chrome/browser/ui/views/borealis/OWNERS
@@ -0,0 +1,3 @@ +file://chrome/browser/chromeos/borealis/OWNERS + +# Please also consider adding an owner from chrome/browser/ui/views/OWNERS.
diff --git a/chrome/browser/ui/views/borealis/borealis_installer_view.cc b/chrome/browser/ui/views/borealis/borealis_installer_view.cc new file mode 100644 index 0000000..614487c --- /dev/null +++ b/chrome/browser/ui/views/borealis/borealis_installer_view.cc
@@ -0,0 +1,441 @@ +// 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/ui/views/borealis/borealis_installer_view.h" + +#include <memory> + +#include "ash/public/cpp/shelf_types.h" +#include "ash/public/cpp/window_properties.h" +#include "base/bind.h" +#include "base/optional.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/chromeos/borealis/borealis_installer_factory.h" +#include "chrome/browser/chromeos/borealis/borealis_util.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_navigator_params.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" +#include "chrome/grit/chrome_unscaled_resources.h" +#include "chrome/grit/generated_resources.h" +#include "content/public/browser/browser_thread.h" +#include "ui/accessibility/ax_enums.mojom.h" +#include "ui/accessibility/ax_node_data.h" +#include "ui/aura/window.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/geometry/insets.h" +#include "ui/strings/grit/ui_strings.h" +#include "ui/views/border.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/controls/progress_bar.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/view_class_properties.h" + +namespace { + +BorealisInstallerView* g_borealis_installer_view = nullptr; + +constexpr gfx::Insets kButtonRowInsets(0, 64, 32, 64); +constexpr int kWindowWidth = 768; +constexpr int kWindowHeight = 636; + +} // namespace + +// Defined in chrome/browser/chromeos/borealis/borealis_util.h. +void borealis::ShowBorealisInstallerView(Profile* profile) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (!g_borealis_installer_view) { + g_borealis_installer_view = new BorealisInstallerView(profile); + views::DialogDelegate::CreateDialogWidget(g_borealis_installer_view, + nullptr, nullptr); + // TODO(danielng): link dialog to shelf item with real values. + g_borealis_installer_view->GetWidget()->GetNativeWindow()->SetProperty( + ash::kShelfIDKey, + ash::ShelfID("lgjpclljbbmphhnalkeplcmnborealis").Serialize()); + } + g_borealis_installer_view->SetButtonRowInsets(kButtonRowInsets); + g_borealis_installer_view->GetWidget()->Show(); +} + +// We need a separate class so that we can alert screen readers appropriately +// when the text changes. +class BorealisInstallerView::TitleLabel : public views::Label { + public: + using Label::Label; + TitleLabel() {} + ~TitleLabel() override {} + + void GetAccessibleNodeData(ui::AXNodeData* node_data) override { + node_data->SetName(GetText()); + node_data->role = ax::mojom::Role::kStatus; + } +}; + +// TODO(danielng):revisit UI elements when UX input is provided. +// Currently using the UI specs that the Plugin VM installer use. +BorealisInstallerView::BorealisInstallerView(Profile* profile) + : app_name_(l10n_util::GetStringUTF16(IDS_BOREALIS_APP_NAME)), + borealis_installer_( + borealis::BorealisInstallerFactory::GetForProfile(profile)) { + // Layout constants from the spec used for the plugin vm installer. + gfx::Insets kDialogInsets(60, 64, 0, 64); + const int kPrimaryMessageHeight = views::style::GetLineHeight( + CONTEXT_HEADLINE, views::style::STYLE_PRIMARY); + const int kSecondaryMessageHeight = views::style::GetLineHeight( + CONTEXT_BODY_TEXT_LARGE, views::style::STYLE_SECONDARY); + const int kInstallationProgressMessageHeight = views::style::GetLineHeight( + CONTEXT_BODY_TEXT_SMALL, views::style::STYLE_SECONDARY); + constexpr int kProgressBarHeight = 5; + constexpr int kProgressBarTopMargin = 32; + + SetDefaultButton(ui::DIALOG_BUTTON_OK); + SetCanMinimize(true); + set_draggable(true); + // Removed margins so dialog insets specify it instead. + set_margins(gfx::Insets()); + + views::BoxLayout* layout = + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, kDialogInsets)); + + views::View* upper_container_view = + AddChildView(std::make_unique<views::View>()); + upper_container_view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, gfx::Insets())); + AddChildView(upper_container_view); + + views::View* lower_container_view = + AddChildView(std::make_unique<views::View>()); + lower_container_layout_ = + lower_container_view->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); + AddChildView(lower_container_view); + + primary_message_label_ = new TitleLabel(GetPrimaryMessage(), CONTEXT_HEADLINE, + views::style::STYLE_PRIMARY); + primary_message_label_->SetProperty( + views::kMarginsKey, gfx::Insets(kPrimaryMessageHeight, 0, 0, 0)); + primary_message_label_->SetMultiLine(false); + primary_message_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + upper_container_view->AddChildView(primary_message_label_); + + views::View* secondary_message_container_view = + AddChildView(std::make_unique<views::View>()); + secondary_message_container_view->SetLayoutManager( + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, + gfx::Insets(kSecondaryMessageHeight, 0, 0, 0))); + upper_container_view->AddChildView(secondary_message_container_view); + secondary_message_label_ = + new views::Label(GetSecondaryMessage(), CONTEXT_BODY_TEXT_LARGE, + views::style::STYLE_SECONDARY); + secondary_message_label_->SetMultiLine(true); + secondary_message_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + secondary_message_container_view->AddChildView(secondary_message_label_); + + progress_bar_ = new views::ProgressBar(kProgressBarHeight); + progress_bar_->SetProperty( + views::kMarginsKey, + gfx::Insets(kProgressBarTopMargin - kProgressBarHeight, 0, 0, 0)); + upper_container_view->AddChildView(progress_bar_); + + installation_progress_message_label_ = new views::Label( + base::string16(), CONTEXT_BODY_TEXT_SMALL, views::style::STYLE_SECONDARY); + installation_progress_message_label_->SetEnabledColor(gfx::kGoogleGrey700); + installation_progress_message_label_->SetProperty( + views::kMarginsKey, + gfx::Insets(kInstallationProgressMessageHeight, 0, 0, 0)); + installation_progress_message_label_->SetMultiLine(false); + installation_progress_message_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + upper_container_view->AddChildView(installation_progress_message_label_); + + big_image_ = new views::ImageView(); + lower_container_view->AddChildView(big_image_); + + // Make sure the lower_container_view is pinned to the bottom of the dialog. + lower_container_layout_->set_main_axis_alignment( + views::BoxLayout::MainAxisAlignment::kEnd); + layout->SetFlexForView(lower_container_view, 1, true); +} + +BorealisInstallerView::~BorealisInstallerView() { + borealis_installer_->RemoveObserver(this); + g_borealis_installer_view = nullptr; +} + +// static +BorealisInstallerView* BorealisInstallerView::GetActiveViewForTesting() { + return g_borealis_installer_view; +} + +bool BorealisInstallerView::ShouldShowCloseButton() const { + return true; +} + +bool BorealisInstallerView::ShouldShowWindowTitle() const { + return false; +} + +bool BorealisInstallerView::Accept() { + if (state_ == State::kConfirmInstall) { + StartInstallation(); + return false; + } + + if (state_ == State::kCompleted) { + // Launch button has been clicked. + // TODO(danielng): Link to launch VM command, once implemented. + return true; + } + + DCHECK_EQ(state_, State::kError); + // Retry button has been clicked to retry setting of Borealis environment + // after error occurred. + StartInstallation(); + return false; +} + +bool BorealisInstallerView::Cancel() { + if (state_ == State::kConfirmInstall || state_ == State::kInstalling) { + borealis_installer_->Cancel(); + } + + return true; +} + +void BorealisInstallerView::OnStateUpdated(InstallingState new_state) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK_EQ(state_, State::kInstalling); + DCHECK_NE(new_state, InstallingState::kInactive); + installing_state_ = new_state; + OnStateUpdated(); +} + +void BorealisInstallerView::OnProgressUpdated(double fraction_complete) { + progress_bar_->SetValue(fraction_complete); +} + +void BorealisInstallerView::OnInstallationEnded( + borealis::BorealisInstaller::InstallationResult result) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + switch (result) { + using ResultEnum = borealis::BorealisInstaller::InstallationResult; + case ResultEnum::kCompleted: + DCHECK_EQ(installing_state_, InstallingState::kInstallingDlc); + state_ = State::kCompleted; + break; + case ResultEnum::kCancelled: + break; + // At this point we know an error has occurred. + default: + state_ = State::kError; + result_ = result; + break; + } + installing_state_ = InstallingState::kInactive; + OnStateUpdated(); +} + +gfx::Size BorealisInstallerView::CalculatePreferredSize() const { + return gfx::Size(kWindowWidth, kWindowHeight); +} + +base::string16 BorealisInstallerView::GetPrimaryMessage() const { + switch (state_) { + case State::kConfirmInstall: + return l10n_util::GetStringFUTF16( + IDS_BOREALIS_INSTALLER_CONFIRMATION_TITLE, app_name_); + case State::kInstalling: + return l10n_util::GetStringFUTF16( + IDS_BOREALIS_INSTALLER_ENVIRONMENT_SETTING_TITLE, app_name_); + case State::kCompleted: + return l10n_util::GetStringUTF16(IDS_BOREALIS_INSTALLER_FINISHED_TITLE); + case State::kError: + DCHECK(result_); + switch (*result_) { + case borealis::BorealisInstaller::InstallationResult::kNotAllowed: + return l10n_util::GetStringFUTF16( + IDS_BOREALIS_INSTALLER_NOT_ALLOWED_TITLE, app_name_); + default: + return l10n_util::GetStringUTF16(IDS_BOREALIS_INSTALLER_ERROR_TITLE); + } + } +} + +base::string16 BorealisInstallerView::GetSecondaryMessage() const { + switch (state_) { + case State::kConfirmInstall: + return l10n_util::GetStringUTF16( + IDS_BOREALIS_INSTALLER_CONFIRMATION_MESSAGE); + case State::kInstalling: + return l10n_util::GetStringUTF16( + IDS_BOREALIS_INSTALLER_IMPORTING_MESSAGE); + case State::kCompleted: + return l10n_util::GetStringFUTF16(IDS_BOREALIS_INSTALLER_IMPORTED_MESSAGE, + app_name_); + case State::kError: + using ResultEnum = borealis::BorealisInstaller::InstallationResult; + DCHECK(result_); + switch (*result_) { + default: + case ResultEnum::kOperationInProgress: + return l10n_util::GetStringFUTF16( + IDS_BOREALIS_GENERIC_ERROR_MESSAGE, app_name_, + base::NumberToString16( + static_cast<std::underlying_type_t<ResultEnum>>(*result_))); + case ResultEnum::kNotAllowed: + case ResultEnum::kDlcUnsupported: + return l10n_util::GetStringFUTF16( + IDS_BOREALIS_INSTALLER_NOT_ALLOWED_MESSAGE, app_name_, + base::NumberToString16( + static_cast<std::underlying_type_t<ResultEnum>>(*result_))); + // DLC Failures. + case ResultEnum::kDlcInternal: + return l10n_util::GetStringFUTF16( + IDS_BOREALIS_DLC_INTERNAL_FAILED_MESSAGE, app_name_); + case ResultEnum::kDlcBusy: + return l10n_util::GetStringFUTF16( + IDS_BOREALIS_DLC_BUSY_FAILED_MESSAGE, app_name_); + case ResultEnum::kDlcNeedReboot: + return l10n_util::GetStringFUTF16( + IDS_BOREALIS_DLC_NEED_REBOOT_FAILED_MESSAGE, app_name_); + case ResultEnum::kDlcNeedSpace: + return l10n_util::GetStringFUTF16( + IDS_BOREALIS_INSUFFICIENT_DISK_SPACE_MESSAGE, app_name_); + case ResultEnum::kDlcUnknown: + return l10n_util::GetStringFUTF16(IDS_BOREALIS_GENERIC_ERROR_MESSAGE, + app_name_); + } + } +} + +int BorealisInstallerView::GetCurrentDialogButtons() const { + switch (state_) { + case State::kInstalling: + return ui::DIALOG_BUTTON_CANCEL; + case State::kConfirmInstall: + case State::kCompleted: + return ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK; + case State::kError: + DCHECK(result_); + switch (*result_) { + case borealis::BorealisInstaller::InstallationResult::kNotAllowed: + return ui::DIALOG_BUTTON_CANCEL; + default: + return ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK; + } + } +} + +base::string16 BorealisInstallerView::GetCurrentDialogButtonLabel( + ui::DialogButton button) const { + switch (state_) { + case State::kConfirmInstall: + return l10n_util::GetStringUTF16( + button == ui::DIALOG_BUTTON_OK ? IDS_BOREALIS_INSTALLER_INSTALL_BUTTON + : IDS_APP_CANCEL); + case State::kInstalling: + DCHECK_EQ(button, ui::DIALOG_BUTTON_CANCEL); + return l10n_util::GetStringUTF16(IDS_APP_CANCEL); + case State::kCompleted: { + return l10n_util::GetStringUTF16( + button == ui::DIALOG_BUTTON_OK ? IDS_BOREALIS_INSTALLER_LAUNCH_BUTTON + : IDS_APP_CLOSE); + } + case State::kError: { + DCHECK(result_); + switch (*result_) { + case borealis::BorealisInstaller::InstallationResult::kNotAllowed: + DCHECK_EQ(button, ui::DIALOG_BUTTON_CANCEL); + return l10n_util::GetStringUTF16(IDS_APP_CANCEL); + default: + return l10n_util::GetStringUTF16( + button == ui::DIALOG_BUTTON_OK + ? IDS_BOREALIS_INSTALLER_RETRY_BUTTON + : IDS_APP_CANCEL); + } + } + } +} + +void BorealisInstallerView::OnStateUpdated() { + SetPrimaryMessageLabel(); + SetSecondaryMessageLabel(); + SetImage(); + + // todo(danielng): ensure button labels meet a11y requirements. + int buttons = GetCurrentDialogButtons(); + SetButtons(buttons); + if (buttons & ui::DIALOG_BUTTON_OK) { + SetButtonLabel(ui::DIALOG_BUTTON_OK, + GetCurrentDialogButtonLabel(ui::DIALOG_BUTTON_OK)); + } + if (buttons & ui::DIALOG_BUTTON_CANCEL) { + SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, + GetCurrentDialogButtonLabel(ui::DIALOG_BUTTON_CANCEL)); + } + + const bool progress_bar_visible = state_ == State::kInstalling; + progress_bar_->SetVisible(progress_bar_visible); + + DialogModelChanged(); + primary_message_label_->NotifyAccessibilityEvent( + ax::mojom::Event::kLiveRegionChanged, + /* send_native_event = */ true); +} + +void BorealisInstallerView::AddedToWidget() { + // At this point GetWidget() is guaranteed to return non-null. + OnStateUpdated(); +} + +void BorealisInstallerView::SetPrimaryMessageLabel() { + primary_message_label_->SetText(GetPrimaryMessage()); + primary_message_label_->SetVisible(true); + primary_message_label_->NotifyAccessibilityEvent( + ax::mojom::Event::kTextChanged, true); +} + +void BorealisInstallerView::SetSecondaryMessageLabel() { + secondary_message_label_->SetText(GetSecondaryMessage()); + secondary_message_label_->SetVisible(true); + secondary_message_label_->NotifyAccessibilityEvent( + ax::mojom::Event::kTextChanged, true); +} + +void BorealisInstallerView::SetImage() { + constexpr gfx::Size kRegularImageSize(314, 191); + constexpr gfx::Size kErrorImageSize(264, 264); + constexpr int kRegularImageBottomInset = 52 + 57; + constexpr int kErrorImageBottomInset = 52; + + auto setImage = [this](int image_id, gfx::Size size, int bottom_inset) { + big_image_->SetImageSize(size); + lower_container_layout_->set_inside_border_insets( + gfx::Insets(0, 0, bottom_inset, 0)); + big_image_->SetImage( + ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(image_id)); + }; + + // todo(danielng):Use Borealis images. + if (state_ == State::kError) { + setImage(IDR_PLUGIN_VM_INSTALLER_ERROR, kErrorImageSize, + kErrorImageBottomInset); + return; + } + setImage(IDR_PLUGIN_VM_INSTALLER, kRegularImageSize, + kRegularImageBottomInset); +} + +void BorealisInstallerView::StartInstallation() { + state_ = State::kInstalling; + progress_bar_->SetValue(0); + OnStateUpdated(); + + borealis_installer_->AddObserver(this); + borealis_installer_->Start(); +}
diff --git a/chrome/browser/ui/views/borealis/borealis_installer_view.h b/chrome/browser/ui/views/borealis/borealis_installer_view.h new file mode 100644 index 0000000..65b4c90 --- /dev/null +++ b/chrome/browser/ui/views/borealis/borealis_installer_view.h
@@ -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. + +#ifndef CHROME_BROWSER_UI_VIEWS_BOREALIS_BOREALIS_INSTALLER_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_BOREALIS_BOREALIS_INSTALLER_VIEW_H_ + +#include "base/callback.h" +#include "base/macros.h" +#include "chrome/browser/chromeos/borealis/borealis_installer_impl.h" +#include "ui/views/window/dialog_delegate.h" + +namespace views { +class BoxLayout; +class ImageView; +class Label; +class ProgressBar; +} // namespace views + +class Profile; + +// The front end for the Borealis installation process, works closely with +// "chrome/browser/chromeos/borealis/borealis_installer.h". +class BorealisInstallerView : public views::DialogDelegateView, + public borealis::BorealisInstaller::Observer { + public: + explicit BorealisInstallerView(Profile* profile); + + // Disallow copy and assign. + BorealisInstallerView(const BorealisInstallerView&) = delete; + BorealisInstallerView& operator=(const BorealisInstallerView&) = delete; + + static BorealisInstallerView* GetActiveViewForTesting(); + + // views::DialogDelegateView implementation. + bool ShouldShowCloseButton() const override; + bool ShouldShowWindowTitle() const override; + bool Accept() override; + bool Cancel() override; + gfx::Size CalculatePreferredSize() const override; + + // borealis::BorealisInstaller::Observer implementation. + void OnStateUpdated( + borealis::BorealisInstaller::InstallingState new_state) override; + void OnProgressUpdated(double fraction_complete) override; + void OnInstallationEnded( + borealis::BorealisInstaller::InstallationResult result) override; + void OnCancelInitiated() override {} + + // Public for testing purposes. + base::string16 GetPrimaryMessage() const; + base::string16 GetSecondaryMessage() const; + + private: + class TitleLabel; + enum class State { + kConfirmInstall, // Waiting for user to start installation. + kInstalling, // Installation in progress. + kCompleted, // Installation process completed. + kError, // Something unexpected happened. + }; + + using InstallingState = borealis::BorealisInstaller::InstallingState; + + ~BorealisInstallerView() override; + + // Returns the dialog buttons that should be displayed, based on the current + // |state_| and error |reason_| (if relevant). + int GetCurrentDialogButtons() const; + // Returns the label for a dialog |button|, based on the current |state_| + // and error |reason_| (if relevant). + base::string16 GetCurrentDialogButtonLabel(ui::DialogButton button) const; + + void OnStateUpdated(); + + // views::DialogDelegateView implementation. + void AddedToWidget() override; + + void SetPrimaryMessageLabel(); + void SetSecondaryMessageLabel(); + void SetImage(); + + void StartInstallation(); + + base::string16 app_name_; + views::Label* primary_message_label_ = nullptr; + views::Label* secondary_message_label_ = nullptr; + views::ProgressBar* progress_bar_ = nullptr; + views::Label* installation_progress_message_label_ = nullptr; + views::BoxLayout* lower_container_layout_ = nullptr; + views::ImageView* big_image_ = nullptr; + + borealis::BorealisInstaller* borealis_installer_ = nullptr; + State state_ = State::kConfirmInstall; + InstallingState installing_state_ = InstallingState::kInactive; + base::Optional<borealis::BorealisInstaller::InstallationResult> result_; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_BOREALIS_BOREALIS_INSTALLER_VIEW_H_
diff --git a/chrome/browser/ui/views/content_test_utils.cc b/chrome/browser/ui/views/content_test_utils.cc index ca0c829..eca2c3fb 100644 --- a/chrome/browser/ui/views/content_test_utils.cc +++ b/chrome/browser/ui/views/content_test_utils.cc
@@ -32,7 +32,11 @@ // Replace the dialog content with a single text input element and focus it. ASSERT_TRUE(content::WaitForLoadStop(contents)); ASSERT_TRUE(content::ExecuteScript(contents, R"( - document.body.innerHTML = '<input type="text" id="text-id">'; + document.body.innerHTML = trustedTypes.emptyHTML; + const input = document.createElement('input'); + input.type = 'text'; + input.id = 'text-id'; + document.body.appendChild(input); document.getElementById('text-id').focus(); )"));
diff --git a/chrome/browser/ui/views/download/download_item_view.cc b/chrome/browser/ui/views/download/download_item_view.cc index 7afff4b..ae97dfb5 100644 --- a/chrome/browser/ui/views/download/download_item_view.cc +++ b/chrome/browser/ui/views/download/download_item_view.cc
@@ -461,9 +461,9 @@ return; } - base::string16 new_tip = model_->GetTooltipText(); - if (new_tip != tooltip_text_) { - tooltip_text_ = new_tip; + const base::string16 new_tooltip_text = model_->GetTooltipText(); + if (new_tooltip_text != tooltip_text_) { + tooltip_text_ = new_tooltip_text; TooltipTextChanged(); } } @@ -508,10 +508,10 @@ } void DownloadItemView::MaybeSubmitDownloadToFeedbackService( - DownloadCommands::Command download_command) { + DownloadCommands::Command command) { if (!model_->ShouldAllowDownloadFeedback() || - !SubmitDownloadToFeedbackService(download_command)) - ExecuteCommand(download_command); + !SubmitDownloadToFeedbackService(command)) + ExecuteCommand(command); } gfx::Size DownloadItemView::CalculatePreferredSize() const { @@ -571,29 +571,16 @@ } void DownloadItemView::OnPaint(gfx::Canvas* canvas) { - // TODO(pkasting): Refactor to simplify. - OnPaintBackground(canvas); const bool use_new_warnings = UseNewWarnings(); - if (mode_ != Mode::kNormal && !use_new_warnings) { - const gfx::ImageSkia icon = ui::ThemedVectorIcon(GetIcon().GetVectorIcon()) - .GetImageSkia(GetNativeTheme()); - const int icon_x = - GetMirroredXWithWidthInView(kStartPadding, icon.size().width()); - const int icon_y = CenterY(icon.size().height()); - canvas->DrawImageInt(icon, icon_x, icon_y); - - OnPaintBorder(canvas); - return; - } - const gfx::Image* const file_icon_image = g_browser_process->icon_manager()->LookupIconFromFilepath( model_->GetTargetFilePath(), IconLoader::SMALL); - const gfx::ImageSkia* file_icon = - file_icon_image ? file_icon_image->ToImageSkia() : nullptr; + const gfx::ImageSkia* file_icon = (file_icon_image && mode_ == Mode::kNormal) + ? file_icon_image->ToImageSkia() + : nullptr; // Paint download progress. // TODO(pkasting): Use a child view to display this. @@ -630,8 +617,8 @@ file_icon = &file_icon_; } + // Draw the file icon. if (file_icon) { - // Draw the file icon. const int offset = (progress_bounds.height() - file_icon->height()) / 2; cc::PaintFlags flags; // Use an alpha to make the image look disabled. @@ -639,19 +626,18 @@ flags.setAlpha(120); canvas->DrawImageInt(*file_icon, progress_x + offset, progress_y + offset, flags); + } - // Overlay the warning icon if appropriate. - if (mode_ != Mode::kNormal) { - constexpr int kDangerIconOffset = 8; - const gfx::ImageSkia icon = - ui::ThemedVectorIcon(GetIcon().GetVectorIcon()) - .GetImageSkia(GetNativeTheme()); - const int icon_x = - GetMirroredXWithWidthInView(kStartPadding, icon.size().width()) + - kDangerIconOffset; - const int icon_y = CenterY(icon.size().height()) + kDangerIconOffset; - canvas->DrawImageInt(icon, icon_x, icon_y); - } + // Overlay the warning icon if appropriate. + if (mode_ != Mode::kNormal) { + const int offset = use_new_warnings ? 8 : 0; + const gfx::ImageSkia icon = ui::ThemedVectorIcon(GetIcon().GetVectorIcon()) + .GetImageSkia(GetNativeTheme()); + const int icon_x = + GetMirroredXWithWidthInView(kStartPadding, icon.size().width()) + + offset; + const int icon_y = CenterY(icon.size().height()) + offset; + canvas->DrawImageInt(icon, icon_x, icon_y); } OnPaintBorder(canvas); @@ -1183,22 +1169,21 @@ } bool DownloadItemView::SubmitDownloadToFeedbackService( - DownloadCommands::Command download_command) { + DownloadCommands::Command command) const { #if BUILDFLAG(FULL_SAFE_BROWSING) safe_browsing::SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service(); if (!sb_service) return false; - safe_browsing::DownloadProtectionService* download_protection_service = + safe_browsing::DownloadProtectionService* dp_service = sb_service->download_protection_service(); - if (!download_protection_service) + if (!dp_service) return false; // TODO(shaktisahu): Enable feedback service for offline item. if (model_->download()) { - return download_protection_service->MaybeBeginFeedbackForDownload( - shelf_->browser()->profile(), model_->download(), download_command); + return dp_service->MaybeBeginFeedbackForDownload( + shelf_->browser()->profile(), model_->download(), command); } - // WARNING: |this| has been deleted! return true; #else NOTREACHED();
diff --git a/chrome/browser/ui/views/download/download_item_view.h b/chrome/browser/ui/views/download/download_item_view.h index 8c24a3d..d1e9d27 100644 --- a/chrome/browser/ui/views/download/download_item_view.h +++ b/chrome/browser/ui/views/download/download_item_view.h
@@ -105,10 +105,9 @@ const DownloadUIModel* model() const { return model_.get(); } // Submits download to download feedback service if the user has approved and - // the download is suitable for submission, then applies |download_command|. + // the download is suitable for submission, then applies |command|. // If user hasn't seen SBER opt-in text before, show SBER opt-in dialog first. - void MaybeSubmitDownloadToFeedbackService( - DownloadCommands::Command download_command); + void MaybeSubmitDownloadToFeedbackService(DownloadCommands::Command command); protected: // views::View: @@ -170,7 +169,7 @@ // buttons are given the same size). gfx::Size GetButtonSize() const; - // Returns the file name to report to user. It might be elided to fit into + // Returns the file name to report to the user. It might be elided to fit into // the text width. |label| dictates the default text style. base::string16 ElidedFilename(const views::StyledLabel& label) const; @@ -202,10 +201,9 @@ void OpenDownloadDuringAsyncScanning(); // Submits the downloaded file to the safebrowsing download feedback service. - // Applies |download_command| if submission succeeds. Returns whether - // submission was successful. - bool SubmitDownloadToFeedbackService( - DownloadCommands::Command download_command); + // Applies |command| if submission succeeds. Returns whether submission was + // successful. + bool SubmitDownloadToFeedbackService(DownloadCommands::Command command) const; // Forwards |command| to |commands_|; useful for callbacks. void ExecuteCommand(DownloadCommands::Command command);
diff --git a/chrome/browser/ui/views/download/download_shelf_view.cc b/chrome/browser/ui/views/download/download_shelf_view.cc index 9fe2826..6bb4552 100644 --- a/chrome/browser/ui/views/download/download_shelf_view.cc +++ b/chrome/browser/ui/views/download/download_shelf_view.cc
@@ -199,8 +199,7 @@ void DownloadShelfView::AnimationProgressed(const gfx::Animation* animation) { if (animation == &new_item_animation_) { - Layout(); - SchedulePaint(); + InvalidateLayout(); } else if (animation == &shelf_animation_) { // Force a re-layout of the parent, which will call back into // GetPreferredSize, where we will do our animation. In the case where the @@ -242,15 +241,15 @@ } } - // If we had keyboard focus, calling SetVisible(false) causes keyboard focus - // to be completely lost. To prevent this, we focus another view: the web - // contents. TODO(collinbaker): https://crbug.com/846466 Fix - // AccessiblePaneView::SetVisible or FocusManager to make this unnecessary. + // Make the shelf non-visible. + // + // If we had keyboard focus, calling SetVisible(false) will cause keyboard + // focus to be completely lost. To prevent this, focus the web contents. + // TODO(crbug.com/846466): Fix AccessiblePaneView::SetVisible() or + // FocusManager to make this unnecessary. auto* focus_manager = GetFocusManager(); - if (focus_manager && Contains(focus_manager->GetFocusedView())) { + if (focus_manager && Contains(focus_manager->GetFocusedView())) parent_->contents_web_view()->RequestFocus(); - } - SetVisible(false); } @@ -285,8 +284,7 @@ Close(); else AutoClose(); - Layout(); - SchedulePaint(); + InvalidateLayout(); } void DownloadShelfView::ConfigureButtonForTheme(views::MdTextButton* button) {
diff --git a/chrome/browser/ui/views/download/download_shelf_view.h b/chrome/browser/ui/views/download/download_shelf_view.h index 8af4cc34..dc88ff0 100644 --- a/chrome/browser/ui/views/download/download_shelf_view.h +++ b/chrome/browser/ui/views/download/download_shelf_view.h
@@ -95,6 +95,8 @@ // The download views. These are also child Views, and deleted when // the DownloadShelfView is deleted. + // TODO(pkasting): Remove this in favor of making these the children of a + // nested view, so they can easily be laid out and iterated. std::vector<DownloadItemView*> download_views_; // Button for showing all downloads (chrome://downloads).
diff --git a/chrome/browser/ui/views/exclusive_access_bubble_views.cc b/chrome/browser/ui/views/exclusive_access_bubble_views.cc index e92f78f..c2bbac9 100644 --- a/chrome/browser/ui/views/exclusive_access_bubble_views.cc +++ b/chrome/browser/ui/views/exclusive_access_bubble_views.cc
@@ -51,13 +51,30 @@ bubble_first_hide_callback_(std::move(bubble_first_hide_callback)), animation_(new gfx::SlideAnimation(this)) { // Create the contents view. + view_ = new SubtleNotificationView(); + +#if defined(OS_CHROMEOS) + // Technically the exit fullscreen key on ChromeOS is F11 and the + // "Fullscreen" key on the keyboard is just translated to F11 or F4 (which + // is also a toggle-fullscreen command on ChromeOS). However most Chromebooks + // have media keys - including "fullscreen" - but not function keys, so + // instructing the user to "Press [F11] to exit fullscreen" isn't useful. + // + // An obvious solution might be to change the primary accelerator to the + // fullscreen key, but since translation to a function key is done at system + // level we can't actually do that. Instead we provide specific messaging for + // the platform here. (See crbug.com/1110468 for details.) + browser_fullscreen_exit_accelerator_ = + l10n_util::GetStringUTF16(IDS_APP_FULLSCREEN_KEY); +#else ui::Accelerator accelerator(ui::VKEY_UNKNOWN, ui::EF_NONE); bool got_accelerator = bubble_view_context_->GetAcceleratorProvider() ->GetAcceleratorForCommandId(IDC_FULLSCREEN, &accelerator); DCHECK(got_accelerator); - view_ = new SubtleNotificationView(); browser_fullscreen_exit_accelerator_ = accelerator.GetShortcutText(); +#endif + UpdateViewContent(bubble_type_); // Initialize the popup.
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 2a92095..bbe9474 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1209,10 +1209,14 @@ gfx::Rect bounds = GetBounds(); bounds.set_width(bounds.width() + width_diff); bounds.set_height(bounds.height() + height_diff); - SetBounds(bounds); - DCHECK_EQ(GetContentsSize().width(), size.width()); - DCHECK_EQ(GetContentsSize().height(), size.height()); + // Constrain the final bounds to the current screen's available area. Bounds + // enforcement applied earlier does not know the specific frame dimensions. + // Changes to the window size should not generally trigger screen changes. + auto display = + display::Screen::GetScreen()->GetDisplayNearestWindow(GetNativeWindow()); + bounds.AdjustToFit(display.work_area()); + SetBounds(bounds); } bool BrowserView::IsMaximized() const { @@ -2404,8 +2408,9 @@ gfx::Rect* bounds, ui::WindowShowState* show_state) const { chrome::GetSavedWindowBoundsAndShowState(browser_.get(), bounds, show_state); - - if (chrome::SavedBoundsAreContentBounds(browser_.get())) { + // TODO(crbug.com/897300): Generalize this code for app and non-app popups? + if (chrome::SavedBoundsAreContentBounds(browser_.get()) && + browser_->is_type_popup()) { // This is normal non-app popup window. The value passed in |bounds| // represents two pieces of information: // - the position of the window, in screen coordinates (outer position). @@ -2421,25 +2426,28 @@ bounds->height() + toolbar_->GetPreferredSize().height()); } - gfx::Rect window_rect = frame_->non_client_view()-> - GetWindowBoundsForClientBounds(*bounds); - window_rect.set_origin(bounds->origin()); + gfx::Rect rect = + frame_->non_client_view()->GetWindowBoundsForClientBounds(*bounds); + rect.set_origin(bounds->origin()); // When we are given x/y coordinates of 0 on a created popup window, // assume none were given by the window.open() command. - if (window_rect.x() == 0 && window_rect.y() == 0) { - gfx::Size size = window_rect.size(); - window_rect.set_origin(WindowSizer::GetDefaultPopupOrigin(size)); - } + if (rect.origin().IsOrigin()) + rect.set_origin(WindowSizer::GetDefaultPopupOrigin(rect.size())); - *bounds = window_rect; + // Constrain the final bounds to the target screen's available area. Bounds + // enforcement applied earlier does not know the specific frame dimensions, + // but generally yields bounds on the appropriate screen. + auto display = display::Screen::GetScreen()->GetDisplayMatching(rect); + rect.AdjustToFit(display.work_area()); + + *bounds = rect; *show_state = ui::SHOW_STATE_NORMAL; } // We return true because we can _always_ locate reasonable bounds using the // WindowSizer, and we don't want to trigger the Window's built-in "size to - // default" handling because the browser window has no default preferred - // size. + // default" handling because the browser window has no default preferred size. return true; }
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc index 818abb8..33b45860 100644 --- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc +++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
@@ -5,6 +5,9 @@ #include "chrome/browser/ui/views/frame/glass_browser_frame_view.h" #include <dwmapi.h> + +#include <algorithm> +#include <memory> #include <utility> #include "base/trace_event/common/trace_event_common.h" @@ -82,11 +85,7 @@ GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, BrowserView* browser_view) - : BrowserNonClientFrameView(frame, browser_view), - window_icon_(nullptr), - window_title_(nullptr), - throbber_running_(false), - throbber_frame_(0) { + : BrowserNonClientFrameView(frame, browser_view) { // We initialize all fields despite some of them being unused in some modes, // since it's possible for modes to flip dynamically (e.g. if the user enables // a high-contrast theme). Throbber icons are only used when ShowSystemIcon() @@ -135,8 +134,7 @@ browser_view->browser()->is_focus_mode() ? 0 : kTopResizeFrameArea; } -GlassBrowserFrameView::~GlassBrowserFrameView() { -} +GlassBrowserFrameView::~GlassBrowserFrameView() = default; /////////////////////////////////////////////////////////////////////////////// // GlassBrowserFrameView, BrowserNonClientFrameView implementation: @@ -564,9 +562,6 @@ void GlassBrowserFrameView::PaintTitlebar(gfx::Canvas* canvas) const { TRACE_EVENT0("views.frame", "GlassBrowserFrameView::PaintTitlebar"); - cc::PaintFlags flags; - gfx::ScopedCanvas scoped_canvas(canvas); - float scale = canvas->UndoDeviceScaleFactor(); // This is the pixel-accurate version of WindowTopY(). Scaling the DIP values // here compounds precision error, which exposes unpainted client area. When // restored it uses the system dsf instead of the per-monitor dsf to match @@ -595,6 +590,9 @@ const int color_id = ShouldPaintAsActive() ? ThemeProperties::COLOR_ACCENT_BORDER_ACTIVE : ThemeProperties::COLOR_ACCENT_BORDER_INACTIVE; + gfx::ScopedCanvas scoped_canvas(canvas); + float scale = canvas->UndoDeviceScaleFactor(); + cc::PaintFlags flags; flags.setColor(color_utils::GetResultingPaintColor( GetThemeProvider()->GetColor(color_id), titlebar_color)); canvas->DrawRect(gfx::RectF(0, 0, width() * scale, y), flags); @@ -638,7 +636,6 @@ if (!ShowCustomIcon() && !ShowCustomTitle()) return; - gfx::Rect window_icon_bounds; const int icon_size = display::win::ScreenWin::GetSystemMetricsInDIP(SM_CYSMICON); const int titlebar_visual_height = @@ -654,7 +651,8 @@ int next_trailing_x = MinimizeButtonX(); const int y = window_top + (titlebar_visual_height - icon_size) / 2; - window_icon_bounds = gfx::Rect(next_leading_x, y, icon_size, icon_size); + const gfx::Rect window_icon_bounds = + gfx::Rect(next_leading_x, y, icon_size, icon_size); constexpr int kIconTitleSpacing = 5; if (ShowCustomIcon()) {
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.h b/chrome/browser/ui/views/frame/glass_browser_frame_view.h index 9ee97faa..d79a851 100644 --- a/chrome/browser/ui/views/frame/glass_browser_frame_view.h +++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.h
@@ -31,6 +31,8 @@ // Constructs a non-client view for an BrowserFrame. GlassBrowserFrameView(BrowserFrame* frame, BrowserView* browser_view); + GlassBrowserFrameView(const GlassBrowserFrameView&) = delete; + GlassBrowserFrameView& operator=(const GlassBrowserFrameView&) = delete; ~GlassBrowserFrameView() override; // BrowserNonClientFrameView: @@ -74,7 +76,7 @@ SkColor GetTitlebarColor() const; - views::Label* window_title_for_testing() { return window_title_; } + const views::Label* window_title_for_testing() const { return window_title_; } protected: // views::View: @@ -156,8 +158,8 @@ base::win::ScopedHICON big_window_icon_; // Icon and title. Only used when custom-drawing the titlebar for popups. - TabIconView* window_icon_; - views::Label* window_title_; + TabIconView* window_icon_ = nullptr; + views::Label* window_title_ = nullptr; // The container holding the caption buttons (minimize, maximize, close, etc.) // @@ -170,10 +172,10 @@ GlassBrowserCaptionButtonContainer* caption_button_container_; // Whether or not the window throbber is currently animating. - bool throbber_running_; + bool throbber_running_ = false; // The index of the current frame of the throbber animation. - int throbber_frame_; + int throbber_frame_ = 0; // How much extra space to reserve in non-maximized windows for a drag handle. int drag_handle_padding_; @@ -181,8 +183,6 @@ static const int kThrobberIconCount = 24; static HICON throbber_icons_[kThrobberIconCount]; static void InitThrobberIcons(); - - DISALLOW_COPY_AND_ASSIGN(GlassBrowserFrameView); }; #endif // CHROME_BROWSER_UI_VIEWS_FRAME_GLASS_BROWSER_FRAME_VIEW_H_
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc index c93150c..25943a0 100644 --- a/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc +++ b/chrome/browser/ui/views/frame/glass_browser_frame_view_browsertest_win.cc
@@ -19,6 +19,10 @@ class WebAppGlassBrowserFrameViewTest : public InProcessBrowserTest { public: WebAppGlassBrowserFrameViewTest() = default; + WebAppGlassBrowserFrameViewTest(const WebAppGlassBrowserFrameViewTest&) = + delete; + WebAppGlassBrowserFrameViewTest& operator=( + const WebAppGlassBrowserFrameViewTest&) = delete; ~WebAppGlassBrowserFrameViewTest() override = default; GURL GetAppURL() { return GURL("https://test.org"); } @@ -67,9 +71,6 @@ BrowserView* browser_view_ = nullptr; GlassBrowserFrameView* glass_frame_view_ = nullptr; WebAppFrameToolbarView* web_app_frame_toolbar_ = nullptr; - - private: - DISALLOW_COPY_AND_ASSIGN(WebAppGlassBrowserFrameViewTest); }; IN_PROC_BROWSER_TEST_F(WebAppGlassBrowserFrameViewTest, ThemeColor) {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index d5eed6fa..0dd7853 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -50,6 +50,7 @@ #include "components/strings/grit/components_strings.h" #include "components/url_formatter/elide_url.h" #include "components/url_formatter/url_fixer.h" +#include "components/url_formatter/url_formatter.h" #include "components/vector_icons/vector_icons.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -158,6 +159,21 @@ canvas->DrawRect(rect, flags); } +// Returns true if the substring indicated by |range| overflows +// |omnibox_view|'s current local bounds. +bool TextRangeOverflowsView(OmniboxViewViews* omnibox_view, + gfx::RenderText* render_text, + const gfx::Range& range) { + // The RenderText must be in NO_ELIDE mode to attempt to retrieve the bounds + // of |range| (which could be outside its display area). + DCHECK_EQ(gfx::NO_ELIDE, render_text->elide_behavior()); + + gfx::Rect range_rect; + for (const auto& rect : render_text->GetSubstringBounds(range)) + range_rect.Union(rect); + return omnibox_view->GetLocalBounds().width() < range_rect.width(); +} + } // namespace OmniboxViewViews::ElideAnimation::ElideAnimation(OmniboxViewViews* view, @@ -1250,24 +1266,46 @@ unelide_bounds) { return; } + SkColor starting_color = hover_elide_or_unelide_animation_->GetCurrentColor(); if (starting_color == gfx::kPlaceholderColor) starting_color = SK_ColorTRANSPARENT; hover_elide_or_unelide_animation_->Stop(); + // Figure out where we are uneliding from so that the hover animation can - // fade the surrounding text in. If the user has already interacted with the - // page, then we elided to the simplified domain and that is what we are - // uneliding from now. Otherwise, only the scheme and possibly a trivial - // subdomain have been elided and those components now need to be faded in. + // fade in the surrounding text (|ranges_to_fade_in|). If the user has + // already interacted with the page, then we elided to the simplified domain + // and that is what we are uneliding from now. Otherwise, only the scheme + // and possibly a trivial subdomain have been elided and those components + // now need to be faded in. std::vector<gfx::Range> ranges_to_fade_in; + // |minimum_visible_range| will contain either the simplified domain or the + // full hostname, depending on which is currently supposed to be showing. If + // |minimum_visible_range| does not currently fit in the omnibox bounds, + // then we don't do any hover animation. This is for simplicity, because + // ElideAnimation doesn't know how to position the text so that the most + // important part of the hostname is showing if it doesn't all fit. + // Furthermore, it doesn't seem necessary to do hover animation when the + // hostname doesn't fit because nothing is being elided beyond what has to + // be to fit in the local bounds. + gfx::Range minimum_visible_range; if (elide_after_web_contents_interaction_animation_ || !OmniboxFieldTrial::ShouldHidePathQueryRefOnInteraction()) { - GetSimplifiedDomainBounds(&ranges_to_fade_in); + // The URL has been elided to the simplified domain. We want to fade in + // everything surrounding the simplified domain. + minimum_visible_range = GetSimplifiedDomainBounds(&ranges_to_fade_in); } else { + // The full URL is showing, except for the scheme and trivial subdomain. + // We want to fade in the scheme and trivial subdomain. url::Component host = GetHostComponentAfterTrivialSubdomain(); ranges_to_fade_in.emplace_back(0, host.begin); + minimum_visible_range = gfx::Range(host.begin, host.end()); } + + if (TextRangeOverflowsView(this, GetRenderText(), minimum_visible_range)) + return; + hover_elide_or_unelide_animation_->Start( unelide_bounds, OmniboxFieldTrial::UnelideURLOnHoverThresholdMs(), ranges_to_fade_in, starting_color, @@ -1304,6 +1342,7 @@ // avoid over-eliding when some of the text is not visible due to display // offset. GetRenderText()->SetElideBehavior(gfx::NO_ELIDE); + // Figure out where to elide to. If the user has already interacted with the // page or reveal-on-interaction is disabled, then elide to the simplified // domain; otherwise just hide the scheme and trivial subdomain (if any). @@ -1312,6 +1351,10 @@ std::vector<gfx::Range> ranges_surrounding_simplified_domain; gfx::Range simplified_domain = GetSimplifiedDomainBounds(&ranges_surrounding_simplified_domain); + // If the simplified domain overflows the local bounds, then hover + // animations are disabled for simplicity. + if (TextRangeOverflowsView(this, GetRenderText(), simplified_domain)) + return; hover_elide_or_unelide_animation_->Start( simplified_domain, 0 /* delay_ms */, ranges_surrounding_simplified_domain, starting_color, @@ -1319,6 +1362,12 @@ } else { base::string16 text = GetText(); url::Component host = GetHostComponentAfterTrivialSubdomain(); + // If the hostname overflows the local bounds, then hover animations are + // disabled for simplicity. + if (TextRangeOverflowsView(this, GetRenderText(), + gfx::Range(host.begin, host.end()))) { + return; + } hover_elide_or_unelide_animation_->Start( gfx::Range(host.begin, text.size()), 0 /* delay_ms */, std::vector<gfx::Range>{gfx::Range(0, host.begin)}, starting_color, @@ -2406,9 +2455,9 @@ } // TODO(estark): push this inside ParseForEmphasizeComponents()? - std::string simplified_domain = + base::string16 simplified_domain = url_formatter::IDNToUnicode( net::registry_controlled_domains::GetDomainAndRegistry( - url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES)); if (simplified_domain.empty()) { ranges_surrounding_simplified_domain->emplace_back(0, host.begin); @@ -2416,8 +2465,7 @@ return gfx::Range(host.begin, host.end()); } - size_t simplified_domain_pos = - text.rfind(base::ASCIIToUTF16(simplified_domain), host.end()); + size_t simplified_domain_pos = text.rfind(simplified_domain); DCHECK_NE(simplified_domain_pos, std::string::npos); ranges_surrounding_simplified_domain->emplace_back(0, simplified_domain_pos); ranges_surrounding_simplified_domain->emplace_back(host.end(), text.size()); @@ -2543,17 +2591,37 @@ gfx::Rect shifted_simplified_domain_rect( shifted_simplified_domain_x_pos, old_bounds.y(), simplified_domain_rect.width(), old_bounds.height()); - GetRenderText()->SetDisplayRect(shifted_simplified_domain_rect); - // Scroll the text to where the simplified domain begins, relative to the - // leftmost (rightmost if UI is RTL) edge of the current display rect. - if (base::i18n::IsRTL()) { - GetRenderText()->SetDisplayOffset( - GetRenderText()->GetUpdatedDisplayOffset().x() + old_bounds.right() - - simplified_domain_rect.right()); - } else { + + // Now apply the display rect and offset so that exactly the simplified domain + // is visible. + + // First check if the simplified domain fits in the local bounds. If it + // doesn't, then we need to scroll so that the rightmost side is visible (e.g. + // "evil.com" instead of "victim.com" if the full hostname + // "victim.com.evil.com"). This check is only necessary for LTR mode because + // in RTL mode, we scroll to the rightmost side of the domain automatically. + if (shifted_simplified_domain_rect.width() > GetLocalBounds().width() && + !base::i18n::IsRTL()) { + FitToLocalBounds(); GetRenderText()->SetDisplayOffset( GetRenderText()->GetUpdatedDisplayOffset().x() - - (simplified_domain_rect.x() - old_bounds.x())); + (simplified_domain_rect.right() - + GetRenderText()->display_rect().width())); + } else { + // The simplified domain fits in the local bounds, so we proceed to set the + // display rect and offset to make the simplified domain visible. + GetRenderText()->SetDisplayRect(shifted_simplified_domain_rect); + // Scroll the text to where the simplified domain begins, relative to the + // leftmost (rightmost if UI is RTL) edge of the current display rect. + if (base::i18n::IsRTL()) { + GetRenderText()->SetDisplayOffset( + GetRenderText()->GetUpdatedDisplayOffset().x() + old_bounds.right() - + simplified_domain_rect.right()); + } else { + GetRenderText()->SetDisplayOffset( + GetRenderText()->GetUpdatedDisplayOffset().x() - + (simplified_domain_rect.x() - old_bounds.x())); + } } // GetSubstringBounds() rounds outward internally, so there may be small @@ -2617,13 +2685,30 @@ base::string16 text = GetText(); url::Component host = GetHostComponentAfterTrivialSubdomain(); + // First check if the full hostname can fit in the local bounds. If not, then + // show the rightmost portion of the hostname. gfx::Rect display_url_bounds; - for (const auto& rect : GetRenderText()->GetSubstringBounds( - gfx::Range(host.begin, text.size()))) { - display_url_bounds.Union(rect); + gfx::Range host_range(host.begin, host.end()); + if (TextRangeOverflowsView(this, GetRenderText(), host_range)) { + gfx::Rect host_bounds; + for (const auto& rect : GetRenderText()->GetSubstringBounds(host_range)) + host_bounds.Union(rect); + // The full hostname won't fit, so show as much of it as possible starting + // from the right side. + display_url_bounds.set_x( + current_display_rect.x() + + (host_bounds.right() - current_display_rect.right())); + display_url_bounds.set_y(current_display_rect.y()); + display_url_bounds.set_width(current_display_rect.width()); + display_url_bounds.set_height(current_display_rect.height()); + } else { + for (const auto& rect : GetRenderText()->GetSubstringBounds( + gfx::Range(host.begin, text.size()))) { + display_url_bounds.Union(rect); + } + display_url_bounds.set_height(current_display_rect.height()); + display_url_bounds.set_y(current_display_rect.y()); } - display_url_bounds.set_height(current_display_rect.height()); - display_url_bounds.set_y(current_display_rect.y()); // Set the scheme and trivial subdomain to transparent. This isn't necessary // to hide this portion of the text because it will be scrolled out of
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h index 76bdbf2..e9f0d7e 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -178,6 +178,7 @@ private: FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsRevealOnHoverTest, HoverAndExit); + FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsRevealOnHoverTest, HoverAndExitIDN); FRIEND_TEST_ALL_PREFIXES( OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest, UserInteractionAndHover); @@ -197,6 +198,9 @@ SimplifiedDomainElisionWithNarrowOmnibox); FRIEND_TEST_ALL_PREFIXES( OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest, + SimplifiedDomainElisionWithNarrowOmnibox); + FRIEND_TEST_ALL_PREFIXES( + OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest, HideOnInteractionAfterFocusAndBlur); FRIEND_TEST_ALL_PREFIXES( OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest,
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc index dfc935e2..8b490f8 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -1715,6 +1715,94 @@ kSimplifiedDomainDisplayUrlPath, ShouldElideToRegistrableDomain())); } +// Tests the field trial variation that shows a simplified domain by default and +// reveals the unsimplified URL on hover, using an IDN url. +TEST_P(OmniboxViewViewsRevealOnHoverTest, HoverAndExitIDN) { + // The display URL used in simplified domain display tests. + const base::string16 kSimplifiedDomainDisplayIDNUrl = + base::UTF8ToUTF16("https://テスト.住所の例.test/bar"); + const base::string16 kSimplifiedDomainDisplayIDNUrlHostnameAndScheme = + base::UTF8ToUTF16("https://テスト.住所の例.test"); + const base::string16 kSimplifiedDomainDisplayIDNUrlSubdomainAndScheme = + base::UTF8ToUTF16("https://テスト."); + const base::string16 kSimplifiedDomainDisplayIDNUrlSubdomain = + base::UTF8ToUTF16("テスト."); + const base::string16 kSimplifiedDomainDisplayIDNUrlPath = + base::UTF8ToUTF16("/bar"); + const base::string16 kSimplifiedDomainDisplayIDNUrlScheme = + base::UTF8ToUTF16("https://"); + location_bar_model()->set_url(GURL(kSimplifiedDomainDisplayIDNUrl)); + location_bar_model()->set_url_for_display(kSimplifiedDomainDisplayIDNUrl); + omnibox_view()->model()->ResetDisplayTexts(); + omnibox_view()->RevertAll(); + // Call OnThemeChanged() to create the animations. + omnibox_view()->OnThemeChanged(); + + gfx::RenderText* render_text = omnibox_view()->GetRenderText(); + ASSERT_NO_FATAL_FAILURE(ExpectElidedToSimplifiedDomain( + omnibox_view(), kSimplifiedDomainDisplayIDNUrlScheme, + kSimplifiedDomainDisplayIDNUrlSubdomain, + kSimplifiedDomainDisplayIDNUrlHostnameAndScheme, + kSimplifiedDomainDisplayIDNUrlPath, ShouldElideToRegistrableDomain())); + + // As soon as the mouse hovers over the omnibox, the unelide animation should + // start running. + omnibox_view()->OnMouseMoved(CreateMouseEvent(ui::ET_MOUSE_MOVED, {0, 0})); + OmniboxViewViews::ElideAnimation* hover_animation = + omnibox_view()->GetHoverElideOrUnelideAnimationForTesting(); + ASSERT_TRUE(hover_animation); + EXPECT_TRUE(hover_animation->IsAnimating()); + + // Advance the clock through the animation. + gfx::AnimationContainerElement* hover_animation_as_element = + static_cast<gfx::AnimationContainerElement*>( + hover_animation->GetAnimationForTesting()); + hover_animation_as_element->SetStartTime(base::TimeTicks()); + hover_animation_as_element->Step( + base::TimeTicks() + + base::TimeDelta::FromMilliseconds( + OmniboxFieldTrial::UnelideURLOnHoverThresholdMs())); + // After the extended hover threshold has elapsed, the display text shouldn't + // have changed yet. + ASSERT_NO_FATAL_FAILURE(ExpectElidedToSimplifiedDomain( + omnibox_view(), kSimplifiedDomainDisplayIDNUrlScheme, + kSimplifiedDomainDisplayIDNUrlSubdomain, + kSimplifiedDomainDisplayIDNUrlHostnameAndScheme, + kSimplifiedDomainDisplayIDNUrlPath, ShouldElideToRegistrableDomain())); + + // Now advance through the unelision and check the display text. We assume + // that the animation takes less than 1 second. + hover_animation_as_element->Step(base::TimeTicks() + + base::TimeDelta::FromSeconds(1)); + ASSERT_NO_FATAL_FAILURE(ExpectUnelidedFromSimplifiedDomain( + render_text, gfx::Range(0, kSimplifiedDomainDisplayIDNUrl.size()))); + EXPECT_FALSE(hover_animation->IsAnimating()); + // Check that the path and subdomain are not transparent. + EXPECT_NE(SK_ColorTRANSPARENT, + omnibox_view()->GetLatestColorForRange(gfx::Range( + kSimplifiedDomainDisplayIDNUrlHostnameAndScheme.size(), + kSimplifiedDomainDisplayIDNUrl.size()))); + EXPECT_NE(SK_ColorTRANSPARENT, + omnibox_view()->GetLatestColorForRange(gfx::Range( + 0, kSimplifiedDomainDisplayIDNUrlSubdomainAndScheme.size()))); + + // Now exit the mouse. At this point the elision animation should run. + omnibox_view()->OnMouseExited(CreateMouseEvent(ui::ET_MOUSE_EXITED, {0, 0})); + EXPECT_TRUE(hover_animation->IsAnimating()); + + hover_animation_as_element = static_cast<gfx::AnimationContainerElement*>( + hover_animation->GetAnimationForTesting()); + hover_animation_as_element->SetStartTime(base::TimeTicks()); + // We assume that the animation takes less than 1 second. + hover_animation_as_element->Step(base::TimeTicks() + + base::TimeDelta::FromSeconds(1)); + ASSERT_NO_FATAL_FAILURE(ExpectElidedToSimplifiedDomain( + omnibox_view(), kSimplifiedDomainDisplayIDNUrlScheme, + kSimplifiedDomainDisplayIDNUrlSubdomain, + kSimplifiedDomainDisplayIDNUrlHostnameAndScheme, + kSimplifiedDomainDisplayIDNUrlPath, ShouldElideToRegistrableDomain())); +} + class OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest : public OmniboxViewViewsTest, public ::testing::WithParamInterface<std::pair<bool, bool>> { @@ -2912,8 +3000,9 @@ } } -// Tests that in the reveal-on-hover field trial variation, the RenderText does -// not elide the domain if the omnibox is too narrow to fit it. +// Tests that in the reveal-on-hover field trial variation, domains are aligned +// to the right (truncated from the left) if the omnibox is too narrow to fit +// the whole domain. TEST_P(OmniboxViewViewsRevealOnHoverTest, SimplifiedDomainElisionWithNarrowOmnibox) { const int kOmniboxWidth = 60; @@ -2925,19 +3014,59 @@ SetUpSimplifiedDomainTest(); ASSERT_EQ(kSimplifiedDomainDisplayUrl, render_text->GetDisplayText()); - ASSERT_NO_FATAL_FAILURE(ExpectElidedToSimplifiedDomain( - omnibox_view(), kSimplifiedDomainDisplayUrlScheme, - kSimplifiedDomainDisplayUrlSubdomain, - kSimplifiedDomainDisplayUrlHostnameAndScheme, - kSimplifiedDomainDisplayUrlPath, ShouldElideToRegistrableDomain())); - // The omnibox should contain a substring of the domain. + // The omnibox should contain a substring of the domain, aligned to the right. gfx::Rect hostname_bounds; for (const auto& rect : render_text->GetSubstringBounds( gfx::Range(kSimplifiedDomainDisplayUrlScheme.size(), kSimplifiedDomainDisplayUrlHostnameAndScheme.size()))) { hostname_bounds.Union(rect); } + EXPECT_LT(hostname_bounds.x(), omnibox_view()->GetLocalBounds().x()); + EXPECT_FALSE(omnibox_view()->GetLocalBounds().Contains(hostname_bounds)); + + // No hover animations should run when the omnibox is too narrow to fit the + // simplified domain. + + omnibox_view()->OnMouseMoved(CreateMouseEvent(ui::ET_MOUSE_MOVED, {0, 0})); + OmniboxViewViews::ElideAnimation* elide_animation = + omnibox_view()->GetHoverElideOrUnelideAnimationForTesting(); + ASSERT_TRUE(elide_animation); + EXPECT_FALSE(elide_animation->IsAnimating()); + + omnibox_view()->OnMouseExited(CreateMouseEvent(ui::ET_MOUSE_MOVED, {0, 0})); + elide_animation = omnibox_view()->GetHoverElideOrUnelideAnimationForTesting(); + ASSERT_TRUE(elide_animation); + EXPECT_FALSE(elide_animation->IsAnimating()); +} + +// Tests that in the reveal-on-hover and hide-on-interaction field trial +// variation, domains are aligned to the right (truncated from the left) if the +// omnibox is too narrow to fit the whole domain. +TEST_P(OmniboxViewViewsHideOnInteractionAndRevealOnHoverTest, + SimplifiedDomainElisionWithNarrowOmnibox) { + const int kOmniboxWidth = 60; + gfx::RenderText* render_text = omnibox_view()->GetRenderText(); + gfx::Rect current_bounds = omnibox_view()->GetLocalBounds(); + gfx::Rect bounds(current_bounds.x(), current_bounds.y(), kOmniboxWidth, + current_bounds.height()); + omnibox_view()->SetBoundsRect(bounds); + SetUpSimplifiedDomainTest(); + + content::MockNavigationHandle navigation; + navigation.set_is_same_document(false); + omnibox_view()->DidFinishNavigation(&navigation); + + ASSERT_EQ(kSimplifiedDomainDisplayUrl, render_text->GetDisplayText()); + + // The omnibox should contain a substring of the domain, aligned to the right. + gfx::Rect hostname_bounds; + for (const auto& rect : render_text->GetSubstringBounds( + gfx::Range(kSimplifiedDomainDisplayUrlScheme.size(), + kSimplifiedDomainDisplayUrlHostnameAndScheme.size()))) { + hostname_bounds.Union(rect); + } + EXPECT_LT(hostname_bounds.x(), omnibox_view()->GetLocalBounds().x()); EXPECT_FALSE(omnibox_view()->GetLocalBounds().Contains(hostname_bounds)); }
diff --git a/chrome/browser/ui/views/sharesheet_bubble_view.cc b/chrome/browser/ui/views/sharesheet_bubble_view.cc index 80cc03f..8a2e657 100644 --- a/chrome/browser/ui/views/sharesheet_bubble_view.cc +++ b/chrome/browser/ui/views/sharesheet_bubble_view.cc
@@ -23,6 +23,7 @@ #include "ui/views/controls/button/image_button_factory.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" +#include "ui/views/controls/scroll_view.h" #include "ui/views/controls/styled_label.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/grid_layout.h" @@ -31,14 +32,19 @@ namespace { // Sizes are in px. +// kButtonWidth = 76px width + 2*8px for padding on left and right constexpr int kButtonWidth = 92; +// kButtonHeight = 88px height + 2*8px for padding on top and bottom. constexpr int kButtonHeight = 104; constexpr int kButtonLineHeight = 20; constexpr int kButtonPadding = 8; constexpr int kCornerRadius = 12; constexpr int kMaxTargetsPerRow = 4; +// TargetViewHeight is 2*kButtonHeight + kButtonPadding +constexpr int kTargetViewHeight = 216; constexpr int kBubbleWidth = 416; +constexpr int kShortSpacing = 20; constexpr int kSpacing = 24; constexpr int kTitleLineHeight = 24; constexpr char kTitle[] = "Share"; @@ -133,14 +139,6 @@ views::GridLayout::ColumnSize::kUsePreferred, /* fixed_width */ 0, /*min_width*/ 0); - views::ColumnSet* cs_buttons = - main_layout->AddColumnSet(COLUMN_SET_ID_TARGETS); - for (int i = 0; i < kMaxTargetsPerRow; i++) { - cs_buttons->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, - 0, views::GridLayout::ColumnSize::kFixed, - kButtonWidth, 0); - } - // Add Title label main_layout->StartRow(views::GridLayout::kFixedSize, COLUMN_SET_ID_TITLE, kTitleLineHeight); @@ -150,21 +148,43 @@ title->SetLineHeight(kTitleLineHeight); title->SetEnabledColor(kShareTitleColor); title->SetHorizontalAlignment(gfx::ALIGN_LEFT); + main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing); // Add Targets + auto scrollable_view = std::make_unique<views::View>(); + auto* scroll_layout = + scrollable_view->SetLayoutManager(std::make_unique<views::GridLayout>()); + views::ColumnSet* cs_buttons = + scroll_layout->AddColumnSet(COLUMN_SET_ID_TARGETS); + for (int i = 0; i < kMaxTargetsPerRow; i++) { + cs_buttons->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, + 0, views::GridLayout::ColumnSize::kFixed, + kButtonWidth, 0); + } + size_t i = 0; for (const auto& target : targets_) { if (i % kMaxTargetsPerRow == 0) { - main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing); - main_layout->StartRow(views::GridLayout::kFixedSize, - COLUMN_SET_ID_TARGETS); + if (i != 0) { + scroll_layout->AddPaddingRow(views::GridLayout::kFixedSize, + kButtonPadding); + } + scroll_layout->StartRow(views::GridLayout::kFixedSize, + COLUMN_SET_ID_TARGETS); } auto target_view = std::make_unique<ShareSheetTargetButton>( this, target.display_name, &target.icon); target_view->set_tag(i++); - main_layout->AddView(std::move(target_view)); + scroll_layout->AddView(std::move(target_view)); } - main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kSpacing); + + auto scroll_view = std::make_unique<views::ScrollView>(); + scroll_view->SetContents(std::move(scrollable_view)); + scroll_view->ClipHeightTo(kTargetViewHeight, kTargetViewHeight); + + main_layout->StartRow(views::GridLayout::kFixedSize, COLUMN_SET_ID_TITLE); + main_layout->AddView(std::move(scroll_view)); + main_layout->AddPaddingRow(views::GridLayout::kFixedSize, kShortSpacing); views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(this); GetWidget()->GetRootView()->Layout();
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc index 55d2d809..aac991d5 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -112,9 +112,8 @@ // Because we use "new" badging for feature promos, we cannot use system- // native context menus. (See crbug.com/1109256.) - const int run_flags = views::MenuRunner::HAS_MNEMONICS | - views::MenuRunner::CONTEXT_MENU | - views::MenuRunner::FORCE_VIEWS; + const int run_flags = + views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU; menu_runner_ = std::make_unique<views::MenuRunner>(model_.get(), run_flags); } TabContextMenuContents(const TabContextMenuContents&) = delete;
diff --git a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc index c73b323..7c110e9 100644 --- a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc
@@ -234,9 +234,11 @@ registrar_observer_.Add(&provider->registrar()); - provider->icon_manager().ReadAllIcons( - app_id, base::BindOnce(&WebAppUninstallDialogViews::OnAllIconsRead, - weak_ptr_factory_.GetWeakPtr())); + provider->icon_manager().ReadIcons( + app_id, IconPurpose::ANY, + provider->registrar().GetAppDownloadedIconSizesAny(app_id), + base::BindOnce(&WebAppUninstallDialogViews::OnIconsRead, + weak_ptr_factory_.GetWeakPtr())); } void WebAppUninstallDialogViews::SetDialogShownCallbackForTesting( @@ -244,7 +246,7 @@ dialog_shown_callback_for_testing_ = std::move(callback); } -void WebAppUninstallDialogViews::OnAllIconsRead( +void WebAppUninstallDialogViews::OnIconsRead( std::map<SquareSizePx, SkBitmap> icon_bitmaps) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.h b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.h index 10354ce..11764da7 100644 --- a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.h +++ b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.h
@@ -105,7 +105,7 @@ void OnWebAppUninstalled(const web_app::AppId& app_id) override; void OnAppRegistrarDestroyed() override; - void OnAllIconsRead(std::map<SquareSizePx, SkBitmap> icon_bitmaps); + void OnIconsRead(std::map<SquareSizePx, SkBitmap> icon_bitmaps); // The dialog's parent window. const gfx::NativeWindow parent_;
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.h b/chrome/browser/ui/web_applications/app_browser_controller.h index 547560c..3e5e2d66 100644 --- a/chrome/browser/ui/web_applications/app_browser_controller.h +++ b/chrome/browser/ui/web_applications/app_browser_controller.h
@@ -140,6 +140,11 @@ // Returns true if this controller is for a System Web App. bool is_for_system_web_app() const { return system_app_type_.has_value(); } + // Returns the SystemAppType for this controller. + const base::Optional<SystemAppType>& system_app_type() const { + return system_app_type_; + } + // Returns true if AppId is non-null bool HasAppId() const { return app_id_.has_value(); }
diff --git a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc index 1ae3756..19c55744 100644 --- a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc +++ b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
@@ -200,6 +200,8 @@ } } + // TODO(crbug.com/1114939): Need to make sure the browser is shown on the + // correct desktop, when used in multi-profile mode. browser->window()->Show(); return browser; } @@ -236,6 +238,22 @@ browser->app_controller()->is_for_system_web_app(); } +bool IsBrowserForSystemWebApp(Browser* browser, SystemAppType type) { + DCHECK(browser); + return browser->app_controller() && + browser->app_controller()->system_app_type() == type; +} + +base::Optional<SystemAppType> GetCapturingSystemAppForURL(Profile* profile, + const GURL& url) { + auto* provider = WebAppProvider::Get(profile); + + if (!provider) + return base::nullopt; + + return provider->system_web_app_manager().GetCapturingSystemAppForURL(url); +} + gfx::Size GetSystemWebAppMinimumWindowSize(Browser* browser) { DCHECK(browser); if (!browser->app_controller())
diff --git a/chrome/browser/ui/web_applications/system_web_app_ui_utils.h b/chrome/browser/ui/web_applications/system_web_app_ui_utils.h index e61f8c1..709a7213 100644 --- a/chrome/browser/ui/web_applications/system_web_app_ui_utils.h +++ b/chrome/browser/ui/web_applications/system_web_app_ui_utils.h
@@ -52,6 +52,13 @@ // Returns true if the |browser| is a system web app. bool IsSystemWebApp(Browser* browser); +// Returns the SystemAppType that should capture the |url|. +base::Optional<SystemAppType> GetCapturingSystemAppForURL(Profile* profile, + const GURL& url); + +// Returns whether the |browser| hosts the system app |type|. +bool IsBrowserForSystemWebApp(Browser* browser, SystemAppType type); + // Returns the minimum window size for a system web app, or an empty size if // the app does not specify a minimum size. gfx::Size GetSystemWebAppMinimumWindowSize(Browser* browser);
diff --git a/chrome/browser/ui/web_applications/test/system_web_app_ui_browsertest.cc b/chrome/browser/ui/web_applications/test/system_web_app_ui_browsertest.cc new file mode 100644 index 0000000..3edb81e --- /dev/null +++ b/chrome/browser/ui/web_applications/test/system_web_app_ui_browsertest.cc
@@ -0,0 +1,427 @@ +// 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 <string> +#include <tuple> +#include <utility> +#include <vector> + +#include "base/strings/utf_string_conversions.h" +#include "chrome/app/chrome_command_ids.h" +#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_tabstrip.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/location_bar/location_bar.h" +#include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" +#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h" +#include "chrome/browser/web_applications/system_web_app_manager_browsertest.h" +#include "chrome/browser/web_applications/test/test_system_web_app_installation.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/omnibox/browser/omnibox_edit_model.h" +#include "components/omnibox/browser/omnibox_view.h" +#include "content/public/browser/notification_types.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/test_navigation_observer.h" + +namespace web_app { + +class SystemWebAppLinkCaptureBrowserTest + : public SystemWebAppManagerBrowserTest { + public: + SystemWebAppLinkCaptureBrowserTest() + : SystemWebAppManagerBrowserTest(/*install_mock*/ false) { + maybe_installation_ = + TestSystemWebAppInstallation::SetUpAppThatCapturesNavigation(); + } + ~SystemWebAppLinkCaptureBrowserTest() override = default; + + protected: + Browser* CreateIncognitoBrowser() { + Browser* incognito = new Browser(Browser::CreateParams( + browser()->profile()->GetPrimaryOTRProfile(), true)); + + content::WindowedNotificationObserver observer( + content::NOTIFICATION_LOAD_STOP, + content::NotificationService::AllSources()); + chrome::AddSelectedTabWithURL(incognito, GURL(url::kAboutBlankURL), + ui::PAGE_TRANSITION_AUTO_TOPLEVEL); + observer.Wait(); + + incognito->window()->Show(); + return incognito; + } + const GURL kInitiatingAppUrl = GURL("chrome://initiating-app/pwa.html"); + const SystemAppType kInitiatingAppType = SystemAppType::SETTINGS; +}; + +IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, + OmniboxTypeURLAndNavigate) { + WaitForTestSystemAppInstall(); + + content::TestNavigationObserver observer(maybe_installation_->GetAppUrl()); + observer.StartWatchingNewWebContents(); + ui_test_utils::SendToOmniboxAndSubmit( + browser(), maybe_installation_->GetAppUrl().spec()); + observer.Wait(); + + Browser* app_browser = FindSystemWebAppBrowser( + browser()->profile(), maybe_installation_->GetType()); + EXPECT_TRUE(app_browser); + EXPECT_EQ(app_browser, chrome::FindLastActive()); + EXPECT_EQ(2U, chrome::GetTotalBrowserCount()); + EXPECT_EQ(Browser::TYPE_APP, app_browser->type()); + EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar()); +} + +IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, OmniboxPasteAndGo) { + WaitForTestSystemAppInstall(); + OmniboxEditModel* model = + browser()->window()->GetLocationBar()->GetOmniboxView()->model(); + + content::TestNavigationObserver observer(maybe_installation_->GetAppUrl()); + observer.StartWatchingNewWebContents(); + model->PasteAndGo(base::UTF8ToUTF16(maybe_installation_->GetAppUrl().spec())); + observer.Wait(); + + Browser* app_browser = FindSystemWebAppBrowser( + browser()->profile(), maybe_installation_->GetType()); + EXPECT_TRUE(app_browser); + EXPECT_EQ(app_browser, chrome::FindLastActive()); + EXPECT_EQ(2U, chrome::GetTotalBrowserCount()); + EXPECT_EQ(Browser::TYPE_APP, app_browser->type()); + EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar()); +} + +IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, AnchorLinkClick) { + WaitForTestSystemAppInstall(); + + GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL); + NavigateToURLAndWait(browser(), kInitiatingChromeUrl); + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); + + const std::string kAnchorTargets[] = {"", "_blank", "_self"}; + const std::string kAnchorRelValues[] = {"", "noreferrer", "noopener", + "noreferrer noopener"}; + + for (const auto& target : kAnchorTargets) { + for (const auto& rel : kAnchorRelValues) { + SCOPED_TRACE(testing::Message() << "anchor link: target='" << target + << "', rel='" << rel << "'"); + content::TestNavigationObserver observer( + maybe_installation_->GetAppUrl()); + observer.StartWatchingNewWebContents(); + EXPECT_TRUE(content::ExecuteScript( + browser()->tab_strip_model()->GetActiveWebContents(), + content::JsReplace("{" + " let el = document.createElement('a');" + " el.href = $1;" + " el.target = $2;" + " el.rel = $3;" + " el.textContent = 'target = ' + $2;" + " document.body.appendChild(el);" + " el.click();" + "}", + maybe_installation_->GetAppUrl(), target, rel))); + observer.Wait(); + + Browser* app_browser = FindSystemWebAppBrowser( + browser()->profile(), maybe_installation_->GetType()); + EXPECT_TRUE(app_browser); + EXPECT_EQ(app_browser, chrome::FindLastActive()); + EXPECT_EQ(2U, chrome::GetTotalBrowserCount()); + EXPECT_EQ(Browser::TYPE_APP, app_browser->type()); + EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar()); + app_browser->window()->Close(); + base::RunLoop().RunUntilIdle(); + + // Check the initiating browser window is intact. + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); + } + } +} + +IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, + AnchorLinkContextMenuNewTab) { + WaitForTestSystemAppInstall(); + + GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL); + NavigateToURLAndWait(browser(), kInitiatingChromeUrl); + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); + + content::ContextMenuParams context_menu_params; + context_menu_params.page_url = kInitiatingChromeUrl; + context_menu_params.link_url = maybe_installation_->GetAppUrl(); + + content::TestNavigationObserver observer(maybe_installation_->GetAppUrl()); + observer.StartWatchingNewWebContents(); + + TestRenderViewContextMenu menu( + browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), + context_menu_params); + menu.Init(); + menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, 0); + + observer.Wait(); + + Browser* app_browser = FindSystemWebAppBrowser( + browser()->profile(), maybe_installation_->GetType()); + EXPECT_TRUE(app_browser); + EXPECT_EQ(app_browser, chrome::FindLastActive()); + EXPECT_EQ(2U, chrome::GetTotalBrowserCount()); + EXPECT_EQ(Browser::TYPE_APP, app_browser->type()); + EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar()); + app_browser->window()->Close(); + base::RunLoop().RunUntilIdle(); + + // Check the initiating browser window is intact. + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); +} + +IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, + AnchorLinkContextMenuNewWindow) { + WaitForTestSystemAppInstall(); + + GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL); + NavigateToURLAndWait(browser(), kInitiatingChromeUrl); + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); + + content::ContextMenuParams context_menu_params; + context_menu_params.page_url = kInitiatingChromeUrl; + context_menu_params.link_url = maybe_installation_->GetAppUrl(); + + content::TestNavigationObserver observer(maybe_installation_->GetAppUrl()); + observer.StartWatchingNewWebContents(); + + TestRenderViewContextMenu menu( + browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), + context_menu_params); + menu.Init(); + menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW, 0); + + observer.Wait(); + + Browser* app_browser = FindSystemWebAppBrowser( + browser()->profile(), maybe_installation_->GetType()); + EXPECT_TRUE(app_browser); + EXPECT_EQ(app_browser, chrome::FindLastActive()); + EXPECT_EQ(2U, chrome::GetTotalBrowserCount()); + EXPECT_EQ(Browser::TYPE_APP, app_browser->type()); + EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar()); + app_browser->window()->Close(); + base::RunLoop().RunUntilIdle(); + + // Check the initiating browser window is intact. + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); +} + +IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, ChangeLocationHref) { + WaitForTestSystemAppInstall(); + + GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL); + NavigateToURLAndWait(browser(), kInitiatingChromeUrl); + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); + + content::TestNavigationObserver observer(maybe_installation_->GetAppUrl()); + observer.StartWatchingNewWebContents(); + EXPECT_TRUE(content::ExecuteScript( + browser()->tab_strip_model()->GetActiveWebContents(), + content::JsReplace("location.href=$1;", + maybe_installation_->GetAppUrl()))); + observer.Wait(); + + Browser* app_browser = FindSystemWebAppBrowser( + browser()->profile(), maybe_installation_->GetType()); + EXPECT_TRUE(app_browser); + EXPECT_EQ(app_browser, chrome::FindLastActive()); + EXPECT_EQ(2U, chrome::GetTotalBrowserCount()); + EXPECT_EQ(Browser::TYPE_APP, app_browser->type()); + EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar()); + + // Check the initiating browser window is intact. + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); +} + +IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, WindowOpen) { + WaitForTestSystemAppInstall(); + + GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL); + NavigateToURLAndWait(browser(), kInitiatingChromeUrl); + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); + + const std::string kWindowOpenTargets[] = {"", "_blank"}; + const std::string kWindowOpenFeatures[] = {"", "noreferrer", "noopener", + "noreferrer noopener"}; + + for (const auto& target : kWindowOpenTargets) { + for (const auto& features : kWindowOpenFeatures) { + SCOPED_TRACE(testing::Message() << "window.open: target='" << target + << "', features='" << features << "'"); + content::TestNavigationObserver observer( + maybe_installation_->GetAppUrl()); + observer.StartWatchingNewWebContents(); + EXPECT_TRUE(content::ExecuteScript( + browser()->tab_strip_model()->GetActiveWebContents(), + content::JsReplace("window.open($1, $2, $3);", + maybe_installation_->GetAppUrl(), target, + features))); + observer.Wait(); + + Browser* app_browser = FindSystemWebAppBrowser( + browser()->profile(), maybe_installation_->GetType()); + EXPECT_TRUE(app_browser); + EXPECT_EQ(app_browser, chrome::FindLastActive()); + EXPECT_EQ(2U, chrome::GetTotalBrowserCount()); + EXPECT_EQ(Browser::TYPE_APP, app_browser->type()); + EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar()); + app_browser->window()->Close(); + base::RunLoop().RunUntilIdle(); + + // Check the initiating browser window is intact. + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); + } + } +} + +IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, + WindowOpenFromOtherSWA) { + WaitForTestSystemAppInstall(); + + content::WebContents* initiating_web_contents = LaunchApp(kInitiatingAppType); + + const std::string kWindowOpenTargets[] = {"", "_blank"}; + const std::string kWindowOpenFeatures[] = {"", "noreferrer", "noopener", + "noreferrer noopener"}; + + for (const auto& target : kWindowOpenTargets) { + for (const auto& features : kWindowOpenFeatures) { + SCOPED_TRACE(testing::Message() << "window.open: target='" << target + << "', features='" << features << "'"); + content::TestNavigationObserver observer( + maybe_installation_->GetAppUrl()); + observer.StartWatchingNewWebContents(); + EXPECT_TRUE(content::ExecuteScript( + initiating_web_contents, + content::JsReplace("window.open($1, $2, $3);", + maybe_installation_->GetAppUrl(), target, + features))); + observer.Wait(); + + Browser* app_browser = FindSystemWebAppBrowser( + browser()->profile(), maybe_installation_->GetType()); + EXPECT_TRUE(app_browser); + EXPECT_EQ(app_browser, chrome::FindLastActive()); + + // There should be three browsers: the default one (new tab page), the + // initiating system app, the link capturing system app. + EXPECT_EQ(3U, chrome::GetTotalBrowserCount()); + EXPECT_EQ(Browser::TYPE_APP, app_browser->type()); + EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar()); + app_browser->window()->Close(); + base::RunLoop().RunUntilIdle(); + + // Check the initiating browser window is intact. + EXPECT_EQ(kInitiatingAppUrl, + initiating_web_contents->GetLastCommittedURL()); + } + } +} + +IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, + CaptureToOpenedWindowAndNavigateURL) { + WaitForTestSystemAppInstall(); + + Browser* app_browser; + content::WebContents* web_contents = + LaunchApp(maybe_installation_->GetType(), &app_browser); + + GURL kInitiatingChromeUrl = GURL(chrome::kChromeUIAboutURL); + NavigateToURLAndWait(browser(), kInitiatingChromeUrl); + EXPECT_EQ(kInitiatingChromeUrl, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); + + const GURL kPageURL = maybe_installation_->GetAppUrl().Resolve("/page2.html"); + content::TestNavigationObserver observer(web_contents); + EXPECT_TRUE(content::ExecuteScript( + browser()->tab_strip_model()->GetActiveWebContents(), + content::JsReplace("let el = document.createElement('a');" + "el.href = $1;" + "el.innerHTML = 'Link to SWA Page 2';" + "document.body.appendChild(el);" + "el.click();", + kPageURL))); + observer.Wait(); + + EXPECT_EQ(kPageURL, app_browser->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); +} + +// TODO(crbug.com/1109594): Update this when we decide if SWAs can be +// link-captured to standalone incognito windows. Currently, the SWA gets +// launched into a standalone browser window in incognito profile. +IN_PROC_BROWSER_TEST_P(SystemWebAppLinkCaptureBrowserTest, + IncognitoBrowserOmniboxLinkCapture) { + WaitForTestSystemAppInstall(); + + Browser* incognito_browser = CreateIncognitoBrowser(); + browser()->window()->Close(); + base::RunLoop().RunUntilIdle(); + + content::TestNavigationObserver observer(maybe_installation_->GetAppUrl()); + observer.StartWatchingNewWebContents(); + incognito_browser->window()->GetLocationBar()->FocusLocation(true); + ui_test_utils::SendToOmniboxAndSubmit( + incognito_browser, maybe_installation_->GetAppUrl().spec()); + observer.Wait(); + + Browser* app_browser = FindSystemWebAppBrowser( + incognito_browser->profile(), maybe_installation_->GetType()); + EXPECT_TRUE(app_browser); + EXPECT_EQ(app_browser, chrome::FindLastActive()); + EXPECT_EQ(2U, chrome::GetTotalBrowserCount()); + EXPECT_EQ(Browser::TYPE_APP, app_browser->type()); + EXPECT_FALSE(app_browser->app_controller()->ShouldShowCustomTabBar()); +} + +INSTANTIATE_TEST_SUITE_P(All, + SystemWebAppLinkCaptureBrowserTest, + ::testing::Values(ProviderType::kBookmarkApps, + ProviderType::kWebApps), + ProviderTypeParamToString); + +} // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_browser_controller.cc b/chrome/browser/ui/web_applications/web_app_browser_controller.cc index 3ebdd9d..f70e6c8 100644 --- a/chrome/browser/ui/web_applications/web_app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/web_app_browser_controller.cc
@@ -111,9 +111,9 @@ } #endif - if (provider_.icon_manager().HasSmallestIcon(GetAppId(), + if (provider_.icon_manager().HasSmallestIcon(GetAppId(), {IconPurpose::ANY}, web_app::kWebAppIconSmall)) { - provider_.icon_manager().ReadSmallestIcon( + provider_.icon_manager().ReadSmallestIconAny( GetAppId(), web_app::kWebAppIconSmall, base::BindOnce(&WebAppBrowserController::OnReadIcon, weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc index 9457d603..5188206 100644 --- a/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc +++ b/chrome/browser/ui/webui/chrome_url_data_manager_browsertest.cc
@@ -180,6 +180,9 @@ // This list was derived from chrome://about. :) static constexpr const char* const kChromeUrls[] = { "chrome://accessibility", + // TODO(crbug.com/1114074): DCHECK failure when opening + // chrome://appcache-internals. + // "chrome://appcache-internals", "chrome://apps", "chrome://autofill-internals", "chrome://blob-internals", @@ -195,7 +198,11 @@ "chrome://crashes", "chrome://credits", "chrome://device-log", + // TODO(crbug.com/1114062): Crash when closing chrome://devices. + // "chrome://devices", "chrome://dino", + // TODO(crbug.com/1113446): Test failure due to excessive output. + // "chrome://discards", "chrome://domain-reliability-internals", "chrome://download-internals", "chrome://downloads", @@ -243,14 +250,23 @@ "chrome://sandbox", "chrome://serviceworker-internals", "chrome://settings", + // TODO(crbug.com/1115600): DCHECK failure when opening + // chrome://signin-dice-web-intercept. + // "chrome://signin-dice-web-intercept", "chrome://signin-email-confirmation", "chrome://signin-internals", "chrome://site-engagement", "chrome://snippets-internals", "chrome://suggestions", + // TODO(crbug.com/1099564): Navigating to chrome://sync-confirmation and + // quickly navigating away cause DCHECK failure. + // "chrome://sync-confirmation", "chrome://sync-internals", "chrome://syncfs-internals", "chrome://system", + // TODO(crbug.com/1099565): Navigating to chrome://tab-strip and quickly + // navigating away cause DCHECK failure. + // "chrome://tab-strip", "chrome://terms", "chrome://tracing", "chrome://translate-internals", @@ -271,6 +287,10 @@ "chrome://account-manager-welcome", "chrome://account-migration-welcome", "chrome://add-supervision", + // TODO(crbug.com/1102129): DCHECK failure in + // ArcGraphicsTracingHandler::ArcGraphicsTracingHandler. + // "chrome://arc-graphics-tracing", + // "chrome://arc-overview-tracing", "chrome://assistant-optin", "chrome://bluetooth-pairing", "chrome://cellular-setup", @@ -280,6 +300,7 @@ "chrome://cryptohome", "chrome://drive-internals", "chrome://first-run", + "chrome://help-app", "chrome://internet-config-dialog", "chrome://internet-detail-dialog", "chrome://linux-proxy-config", @@ -288,6 +309,7 @@ "chrome://network", "chrome://oobe", "chrome://os-credits", + "chrome://os-settings", "chrome://power", "chrome://proximity-auth/proximity_auth.html", "chrome://set-time", @@ -296,6 +318,10 @@ "chrome://smb-share-dialog", "chrome://supervised-user-internals", "chrome://sys-internals", + // TODO(crbug.com/1115643): DCHECK failure when opening + // chrome-untrusted://crosh. + // "chrome-untrusted://crosh", + "chrome-untrusted://terminal", #endif };
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 54d0ecf..86819b6b 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -28,10 +28,10 @@ #include "chrome/browser/ui/webui/autofill_and_password_manager_internals/autofill_internals_ui.h" #include "chrome/browser/ui/webui/autofill_and_password_manager_internals/password_manager_internals_ui.h" #include "chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals_ui.h" -#include "chrome/browser/ui/webui/chrome_url_disabled_ui.h" #include "chrome/browser/ui/webui/chromeos/account_manager/account_manager_error_ui.h" #include "chrome/browser/ui/webui/chromeos/account_manager/account_manager_welcome_ui.h" #include "chrome/browser/ui/webui/chromeos/account_manager/account_migration_welcome_ui.h" +#include "chrome/browser/ui/webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.h" #include "chrome/browser/ui/webui/chromeos/in_session_password_change/password_change_ui.h" #include "chrome/browser/ui/webui/components/components_ui.h" #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h" @@ -435,7 +435,7 @@ #if defined(OS_CHROMEOS) if (url.host_piece() == chrome::kChromeUIAppDisabledHost) - return &NewWebUI<ChromeURLDisabledUI>; + return &NewWebUI<chromeos::ChromeURLDisabledUI>; #endif // defined(OS_CHROMEOS) if (url.host_piece() == chrome::kChromeUIBluetoothInternalsHost)
diff --git a/chrome/browser/ui/webui/chromeos/chrome_url_disabled/OWNERS b/chrome/browser/ui/webui/chromeos/chrome_url_disabled/OWNERS new file mode 100644 index 0000000..3bbf43ed2 --- /dev/null +++ b/chrome/browser/ui/webui/chromeos/chrome_url_disabled/OWNERS
@@ -0,0 +1 @@ +ayaelattar@chromium.org \ No newline at end of file
diff --git a/chrome/browser/ui/webui/chrome_url_disabled_ui.cc b/chrome/browser/ui/webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.cc similarity index 90% rename from chrome/browser/ui/webui/chrome_url_disabled_ui.cc rename to chrome/browser/ui/webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.cc index 817d778..a5ec6e0 100644 --- a/chrome/browser/ui/webui/chrome_url_disabled_ui.cc +++ b/chrome/browser/ui/webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.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/ui/webui/chrome_url_disabled_ui.h" +#include "chrome/browser/ui/webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/webui_url_constants.h" @@ -10,6 +10,8 @@ #include "components/strings/grit/components_strings.h" #include "content/public/browser/web_ui_data_source.h" +namespace chromeos { + ChromeURLDisabledUI::ChromeURLDisabledUI(content::WebUI* web_ui) : content::WebUIController(web_ui), weak_factory_(this) { content::WebUIDataSource* html_source = @@ -34,3 +36,5 @@ } ChromeURLDisabledUI::~ChromeURLDisabledUI() = default; + +} // namespace chromeos
diff --git a/chrome/browser/ui/webui/chrome_url_disabled_ui.h b/chrome/browser/ui/webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.h similarity index 63% rename from chrome/browser/ui/webui/chrome_url_disabled_ui.h rename to chrome/browser/ui/webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.h index 54962c1..e23327d 100644 --- a/chrome/browser/ui/webui/chrome_url_disabled_ui.h +++ b/chrome/browser/ui/webui/chromeos/chrome_url_disabled/chrome_url_disabled_ui.h
@@ -2,12 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_WEBUI_CHROME_URL_DISABLED_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_CHROME_URL_DISABLED_UI_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_CHROMEOS_CHROME_URL_DISABLED_CHROME_URL_DISABLED_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_CHROME_URL_DISABLED_CHROME_URL_DISABLED_UI_H_ #include "base/memory/weak_ptr.h" #include "content/public/browser/web_ui_controller.h" +namespace chromeos { + // For chrome:://.* error page when disabled by admin policy. class ChromeURLDisabledUI : public content::WebUIController { public: @@ -18,4 +20,6 @@ base::WeakPtrFactory<ChromeURLDisabledUI> weak_factory_; }; -#endif // CHROME_BROWSER_UI_WEBUI_CHROME_URL_DISABLED_UI_H_ +} // namespace chromeos + +#endif // CHROME_BROWSER_UI_WEBUI_CHROMEOS_CHROME_URL_DISABLED_CHROME_URL_DISABLED_UI_H_
diff --git a/chrome/browser/ui/webui/identity_internals_ui.cc b/chrome/browser/ui/webui/identity_internals_ui.cc index 307f7926..11be9171 100644 --- a/chrome/browser/ui/webui/identity_internals_ui.cc +++ b/chrome/browser/ui/webui/identity_internals_ui.cc
@@ -140,8 +140,8 @@ CHECK(api); // Remove token from the cache. - api->EraseCachedToken(token_revoker->extension_id(), - token_revoker->access_token()); + api->token_cache()->EraseToken(token_revoker->extension_id(), + token_revoker->access_token()); // Update view about the token being removed. base::ListValue result; @@ -223,16 +223,15 @@ void IdentityInternalsUIMessageHandler::GetInfoForAllTokens( const base::ListValue* args) { base::ListValue results; - extensions::IdentityAPI::CachedTokens tokens; + extensions::IdentityTokenCache::CachedTokens tokens; // The API can be null in incognito. extensions::IdentityAPI* api = extensions::IdentityAPI::GetFactoryInstance()->Get( Profile::FromWebUI(web_ui())); if (api) - tokens = api->GetAllCachedTokens(); - for (extensions::IdentityAPI::CachedTokens::const_iterator - iter = tokens.begin(); iter != tokens.end(); ++iter) { - results.Append(GetInfoForToken(iter->first, iter->second)); + tokens = api->token_cache()->GetAllTokens(); + for (const auto& token : tokens) { + results.Append(GetInfoForToken(token.first, token.second)); } web_ui()->CallJavascriptFunctionUnsafe("identity_internals.returnTokens",
diff --git a/chrome/browser/ui/webui/identity_internals_ui_browsertest.cc b/chrome/browser/ui/webui/identity_internals_ui_browsertest.cc index ce00fa1..2036b19 100644 --- a/chrome/browser/ui/webui/identity_internals_ui_browsertest.cc +++ b/chrome/browser/ui/webui/identity_internals_ui_browsertest.cc
@@ -59,5 +59,6 @@ std::set<std::string>(scopes.begin(), scopes.end())); extensions::IdentityAPI::GetFactoryInstance() ->Get(browser()->profile()) - ->SetCachedToken(key, token_cache_value); + ->token_cache() + ->SetToken(key, token_cache_value); }
diff --git a/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.cc b/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.cc index 83e07a8..57ce137 100644 --- a/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.cc +++ b/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.cc
@@ -11,6 +11,10 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search/promos/promo_service.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/chrome_pages.h" +#include "chrome/common/webui_url_constants.h" +#include "ui/base/page_transition_types.h" #include "ui/base/window_open_disposition.h" using promo_browser_command::mojom::ClickInfoPtr; @@ -29,10 +33,7 @@ page_handler_(this, std::move(pending_page_handler)) { if (!base::FeatureList::IsEnabled(features::kPromoBrowserCommands)) return; - - // Explicitly enable supported commands. - command_updater_->UpdateCommandEnabled( - static_cast<int>(Command::kUnknownCommand), true); + EnableCommands(); } PromoBrowserCommandHandler::~PromoBrowserCommandHandler() = default; @@ -44,8 +45,9 @@ const auto disposition = ui::DispositionFromClick( click_info->middle_button, click_info->alt_key, click_info->ctrl_key, click_info->meta_key, click_info->shift_key); - const bool command_executed = command_updater_->ExecuteCommandWithDisposition( - static_cast<int>(command_id), disposition); + const bool command_executed = + GetCommandUpdater()->ExecuteCommandWithDisposition( + static_cast<int>(command_id), disposition); std::move(callback).Run(command_executed); } @@ -59,13 +61,32 @@ case Command::kUnknownCommand: // Nothing to do. break; + case Command::kOpenSafetyCheck: + NavigateToURL(GURL(chrome::GetSettingsUrl(chrome::kSafetyCheckSubPage)), + disposition); + break; default: NOTREACHED() << "Unspecified behavior for command " << id; break; } } -void PromoBrowserCommandHandler::SetCommandUpdaterForTesting( - std::unique_ptr<CommandUpdater> command_updater) { - command_updater_ = std::move(command_updater); +void PromoBrowserCommandHandler::EnableCommands() { + // Explicitly enable supported commands. + GetCommandUpdater()->UpdateCommandEnabled( + static_cast<int>(Command::kUnknownCommand), true); + GetCommandUpdater()->UpdateCommandEnabled( + static_cast<int>(Command::kOpenSafetyCheck), true); +} + +CommandUpdater* PromoBrowserCommandHandler::GetCommandUpdater() { + return command_updater_.get(); +} + +void PromoBrowserCommandHandler::NavigateToURL( + const GURL& url, + WindowOpenDisposition disposition) { + NavigateParams params(profile_, url, ui::PAGE_TRANSITION_LINK); + params.disposition = disposition; + Navigate(¶ms); }
diff --git a/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.h b/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.h index a41057d05..7cfde9e 100644 --- a/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.h +++ b/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.h
@@ -14,8 +14,8 @@ #include "ui/base/window_open_disposition.h" class CommandUpdater; +class GURL; class Profile; -class PromoBrowserCommandHandlerTest; // Handles promo browser commands send from JS. class PromoBrowserCommandHandler @@ -40,12 +40,14 @@ int command_id, WindowOpenDisposition disposition) override; - private: - friend class PromoBrowserCommandHandlerTest; + protected: + void EnableCommands(); - void SetCommandUpdaterForTesting( - std::unique_ptr<CommandUpdater> command_updater); - CommandUpdater* command_updater() { return command_updater_.get(); } + virtual CommandUpdater* GetCommandUpdater(); + + private: + virtual void NavigateToURL(const GURL& url, + WindowOpenDisposition disposition); Profile* profile_; std::unique_ptr<CommandUpdater> command_updater_;
diff --git a/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler_unittest.cc b/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler_unittest.cc index 6c827f0..9f11e04 100644 --- a/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler_unittest.cc +++ b/chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler_unittest.cc
@@ -11,14 +11,57 @@ #include "chrome/browser/browser_features.h" #include "chrome/browser/command_updater_impl.h" #include "chrome/browser/promo_browser_command/promo_browser_command.mojom.h" +#include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/webui/new_tab_page/promo_browser_command/promo_browser_command_handler.h" +#include "chrome/common/webui_url_constants.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/browser_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/window_open_disposition.h" + +using promo_browser_command::mojom::ClickInfo; +using promo_browser_command::mojom::ClickInfoPtr; +using promo_browser_command::mojom::Command; +using promo_browser_command::mojom::CommandHandler; namespace { +class TestCommandHandler : public PromoBrowserCommandHandler { + public: + explicit TestCommandHandler(Profile* profile) + : PromoBrowserCommandHandler(mojo::PendingReceiver<CommandHandler>(), + profile) {} + ~TestCommandHandler() override = default; + + void NavigateToURL(const GURL&, WindowOpenDisposition) override { + // The functionality of opening a URL is removed, as it cannot be executed + // in a unittest. + } + + CommandUpdater* GetCommandUpdater() override { + if (command_updater_) + return command_updater_.get(); + return PromoBrowserCommandHandler::GetCommandUpdater(); + } + + void SetCommandUpdater(std::unique_ptr<CommandUpdater> command_updater) { + command_updater_ = std::move(command_updater); + // Ensure that all commands are also updated in the new |command_updater|. + EnableCommands(); + } + + std::unique_ptr<CommandUpdater> command_updater_; +}; + +class MockCommandHandler : public TestCommandHandler { + public: + explicit MockCommandHandler(Profile* profile) : TestCommandHandler(profile) {} + ~MockCommandHandler() override = default; + + MOCK_METHOD2(NavigateToURL, void(const GURL&, WindowOpenDisposition)); +}; + class MockCommandUpdater : public CommandUpdaterImpl { public: explicit MockCommandUpdater(CommandUpdaterDelegate* delegate) @@ -37,12 +80,13 @@ std::move(quit_closure).Run(); } -} // namespace +// A shorthand for conversion between ClickInfo and WindowOpenDisposition. +WindowOpenDisposition DispositionFromClick(const ClickInfo& info) { + return ui::DispositionFromClick(info.middle_button, info.alt_key, + info.ctrl_key, info.meta_key, info.shift_key); +} -using promo_browser_command::mojom::ClickInfo; -using promo_browser_command::mojom::ClickInfoPtr; -using promo_browser_command::mojom::Command; -using promo_browser_command::mojom::CommandHandler; +} // namespace class PromoBrowserCommandHandlerTest : public testing::Test { public: @@ -50,24 +94,21 @@ ~PromoBrowserCommandHandlerTest() override = default; void SetUp() override { - command_handler_ = std::make_unique<PromoBrowserCommandHandler>( - mojo::PendingReceiver<CommandHandler>(), &profile_); - command_handler_->SetCommandUpdaterForTesting( - std::make_unique<MockCommandUpdater>(command_handler_.get())); + command_handler_ = std::make_unique<MockCommandHandler>(&profile_); } void TearDown() override { testing::Test::TearDown(); } MockCommandUpdater* mock_command_updater() { return static_cast<MockCommandUpdater*>( - command_handler_->command_updater()); + command_handler_->GetCommandUpdater()); } bool ExecuteCommand(Command command_id, ClickInfoPtr click_info) { base::RunLoop run_loop; bool command_executed = false; command_handler_->ExecuteCommand( - Command::kUnknownCommand, ClickInfo::New(), + command_id, std::move(click_info), base::BindOnce(&ExecuteCommandCallback, run_loop.QuitClosure(), &command_executed)); run_loop.Run(); @@ -77,12 +118,16 @@ protected: content::BrowserTaskEnvironment task_environment_; TestingProfile profile_; - std::unique_ptr<PromoBrowserCommandHandler> command_handler_; + std::unique_ptr<MockCommandHandler> command_handler_; }; TEST_F(PromoBrowserCommandHandlerTest, SupportedCommands) { base::HistogramTester histogram_tester; + // Mock out the command updater to test enabling and disabling commands. + command_handler_->SetCommandUpdater( + std::make_unique<MockCommandUpdater>(command_handler_.get())); + // Unsupported commands do not get executed and no histogram is logged. EXPECT_CALL(*mock_command_updater(), SupportsCommand(static_cast<int>(Command::kUnknownCommand))) @@ -128,10 +173,22 @@ // The PromoBrowserCommandHandler instance needs to be recreated for the // feature to take effect. - command_handler_ = std::make_unique<PromoBrowserCommandHandler>( - mojo::PendingReceiver<CommandHandler>(), &profile_); + command_handler_ = std::make_unique<MockCommandHandler>(&profile_); EXPECT_FALSE(ExecuteCommand(Command::kUnknownCommand, ClickInfo::New())); histogram_tester.ExpectTotalCount( PromoBrowserCommandHandler::kPromoBrowserCommandHistogramName, 0); } + +TEST_F(PromoBrowserCommandHandlerTest, OpenSafetyCheckCommand) { + // The OpenSafetyCheck command opens a new settings window with the Safety + // Check, and the correct disposition. + ClickInfoPtr info = ClickInfo::New(); + info->middle_button = true; + info->meta_key = true; + EXPECT_CALL( + *command_handler_, + NavigateToURL(GURL(chrome::GetSettingsUrl(chrome::kSafetyCheckSubPage)), + DispositionFromClick(*info))); + EXPECT_TRUE(ExecuteCommand(Command::kOpenSafetyCheck, std::move(info))); +}
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc index bf732da..1e436337d0 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -222,15 +222,17 @@ base::Optional<std::string> icon_big; base::Optional<std::string> icon_small; - if (HasMatchingOrGreaterThanIcon(registrar.GetAppDownloadedIconSizes(app_id), - kWebAppIconLargeNonDefault)) { + if (HasMatchingOrGreaterThanIcon( + registrar.GetAppDownloadedIconSizesAny(app_id), + kWebAppIconLargeNonDefault)) { icon_big = apps::AppIconSource::GetIconURL(app_id, kWebAppIconLargeNonDefault) .spec(); } - if (HasMatchingOrGreaterThanIcon(registrar.GetAppDownloadedIconSizes(app_id), - kWebAppIconSmallNonDefault)) { + if (HasMatchingOrGreaterThanIcon( + registrar.GetAppDownloadedIconSizesAny(app_id), + kWebAppIconSmallNonDefault)) { icon_small = apps::AppIconSource::GetIconURL(app_id, kWebAppIconSmallNonDefault) .spec();
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom index 9025301..7b8cd9c 100644 --- a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom +++ b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
@@ -168,6 +168,8 @@ kShowInputOptionsInShelf = 1201, kShowPersonalInformationSuggestions = 1202, kShowEmojiSuggestions = 1203, + kChangeSystemLanguage = 1204, + kOfferTranslation = 1205, // Files section. kGoogleDriveConnection = 1300,
diff --git a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc index 100ca39..078de61 100644 --- a/chrome/browser/ui/webui/settings/chromeos/languages_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/languages_section.cc
@@ -25,7 +25,7 @@ namespace settings { namespace { -const std::vector<SearchConcept>& GetLanguagesSearchConcepts() { +const std::vector<SearchConcept>& GetLanguagesSearchConceptsV1() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT, mojom::kLanguagesAndInputDetailsSubpagePath, @@ -57,7 +57,7 @@ return *tags; } -const std::vector<SearchConcept>& GetUpdatedLanguagesSearchConcepts() { +const std::vector<SearchConcept>& GetLanguagesPageSearchConceptsV2() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_LANGUAGES, mojom::kLanguagesSubpagePath, @@ -65,12 +65,44 @@ mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSubpage, {.subpage = mojom::Subpage::kLanguages}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_CHANGE_SYSTEM_LANGUAGE, + mojom::kLanguagesSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kChangeSystemLanguage}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT_ADD_LANGUAGE, + mojom::kLanguagesSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kAddLanguage}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_OFFER_TRANSLATION, + mojom::kLanguagesSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kOfferTranslation}}, + }); + return *tags; +} + +const std::vector<SearchConcept>& GetInputPageSearchConceptsV2() { + static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_INPUT, mojom::kInputSubpagePath, mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium, mojom::SearchResultType::kSubpage, {.subpage = mojom::Subpage::kInput}}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT_INPUT_OPTIONS_SHELF, + mojom::kInputSubpagePath, + mojom::SearchResultIcon::kGlobe, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kShowInputOptionsInShelf}, + {IDS_OS_SETTINGS_TAG_LANGUAGES_INPUT_INPUT_OPTIONS_SHELF_ALT1, + SearchConcept::kAltTagEnd}}, }); return *tags; } @@ -200,6 +232,33 @@ AddLocalizedStringsBulk(html_source, kLocalizedStrings); } +void AddLanguagesPageStringsV2(content::WebUIDataSource* html_source) { + static constexpr webui::LocalizedString kLocalizedStrings[] = { + {"systemLanguageTitle", IDS_OS_SETTINGS_LANGUAGES_SYSTEM_LANGUAGE_TITLE}, + {"systemLanguageDescription", + IDS_OS_SETTINGS_LANGUAGES_SYSTEM_LANGUAGE_DESCRIPTION}, + {"changeSystemLanguageLabel", + IDS_OS_SETTINGS_LANGUAGES_CHANGE_SYSTEM_LANGUAGE_BUTTON_LABEL}, + {"changeSystemLanguageButtonDescription", + IDS_OS_SETTINGS_LANGUAGES_CHANGE_SYSTEM_LANGUAGE_BUTTON_DESCRIPTION}, + {"languagesPreferenceTitle", + IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PREFERENCE_TITLE}, + {"languagesPreferenceDescription", + IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PREFERENCE_DESCRIPTION}, + {"offerTranslationLabel", + IDS_OS_SETTINGS_LANGUAGES_OFFER_TRANSLATION_LABEL}, + {"offerTranslationSublabel", + IDS_OS_SETTINGS_LANGUAGES_OFFER_TRANSLATION_SUBLABEL}, + }; + AddLocalizedStringsBulk(html_source, kLocalizedStrings); + + html_source->AddString( + "languagesPreferenceDescription", + l10n_util::GetStringFUTF16( + IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PREFERENCE_DESCRIPTION, + base::ASCIIToUTF16(chrome::kLanguageSettingsLearnMoreUrl))); +} + } // namespace LanguagesSection::LanguagesSection(Profile* profile, @@ -207,9 +266,10 @@ : OsSettingsSection(profile, search_tag_registry) { SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate(); if (IsLanguageSettingsV2Enabled()) { - updater.AddSearchTags(GetUpdatedLanguagesSearchConcepts()); + updater.AddSearchTags(GetLanguagesPageSearchConceptsV2()); + updater.AddSearchTags(GetInputPageSearchConceptsV2()); } else { - updater.AddSearchTags(GetLanguagesSearchConcepts()); + updater.AddSearchTags(GetLanguagesSearchConceptsV1()); } if (IsAssistivePersonalInfoAllowed() || IsEmojiSuggestionAllowed()) { @@ -261,6 +321,7 @@ AddLocalizedStringsBulk(html_source, kLocalizedStrings); AddSmartInputsStrings(html_source, IsEmojiSuggestionAllowed()); AddInputMethodOptionsStrings(html_source); + AddLanguagesPageStringsV2(html_source); html_source->AddString( "languagesLearnMoreURL", @@ -306,6 +367,12 @@ IDS_OS_SETTINGS_LANGUAGES_LANGUAGES_PAGE_TITLE, mojom::Subpage::kLanguages, mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium, mojom::kLanguagesSubpagePath); + static constexpr mojom::Setting kLanguagesPageSettings[] = { + mojom::Setting::kChangeSystemLanguage, + mojom::Setting::kOfferTranslation, + }; + RegisterNestedSettingBulk(mojom::Subpage::kLanguages, kLanguagesPageSettings, + generator); // Input. generator->RegisterTopLevelSubpage( @@ -319,12 +386,21 @@ mojom::Subpage::kLanguagesAndInputDetails, mojom::SearchResultIcon::kGlobe, mojom::SearchResultDefaultRank::kMedium, mojom::kLanguagesAndInputDetailsSubpagePath); - static constexpr mojom::Setting kLanguagesAndInputDetailsSettings[] = { - mojom::Setting::kAddLanguage, - mojom::Setting::kShowInputOptionsInShelf, - }; - RegisterNestedSettingBulk(mojom::Subpage::kLanguagesAndInputDetails, - kLanguagesAndInputDetailsSettings, generator); + + // Shared settings between existing pages and the updated pages. + if (IsLanguageSettingsV2Enabled()) { + generator->RegisterNestedSetting(mojom::Setting::kAddLanguage, + mojom::Subpage::kLanguages); + generator->RegisterNestedSetting(mojom::Setting::kShowInputOptionsInShelf, + mojom::Subpage::kInput); + } else { + static constexpr mojom::Setting kLanguagesAndInputDetailsSettings[] = { + mojom::Setting::kAddLanguage, + mojom::Setting::kShowInputOptionsInShelf, + }; + RegisterNestedSettingBulk(mojom::Subpage::kLanguagesAndInputDetails, + kLanguagesAndInputDetailsSettings, generator); + } // Manage input methods. generator->RegisterNestedSubpage(
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc index a27bd8c..e625820a 100644 --- a/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_ui.cc
@@ -59,6 +59,7 @@ OsSettingsManager* manager = OsSettingsManagerFactory::GetForProfile(profile); manager->AddHandlers(web_ui); manager->AddLoadTimeData(html_source); + html_source->DisableTrustedTypesCSP(); // TODO(khorimoto): Move to DeviceSection::AddHandler() once |html_source| // parameter is removed.
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 47af301..38e912025 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -53,6 +53,7 @@ #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_payments_features.h" #include "components/browsing_data/core/features.h" +#include "components/cloud_devices/common/cloud_devices_urls.h" #include "components/dom_distiller/core/dom_distiller_features.h" #include "components/google/core/common/google_util.h" #include "components/omnibox/common/omnibox_features.h" @@ -1203,7 +1204,26 @@ }; AddLocalizedStringsBulk(html_source, kLocalizedStrings); - html_source->AddString("devicesUrl", chrome::kChromeUIDevicesURL); + html_source->AddString("cloudPrintersUrl", + cloud_devices::GetCloudPrintPrintersURL().spec()); + + const bool enterprise_managed = webui::IsEnterpriseManaged(); + html_source->AddLocalizedString( + "cloudPrintWarning", + enterprise_managed + ? IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_WARNING_ENTERPRISE + : IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_WARNING); + if (enterprise_managed) { + html_source->AddLocalizedString( + "cloudPrintFullWarning", + IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_WARNING_ENTERPRISE); + } else { + html_source->AddString( + "cloudPrintFullWarning", + l10n_util::GetStringFUTF16( + IDS_SETTINGS_PRINTING_GOOGLE_CLOUD_PRINT_NOT_SUPPORTED_FULL_WARNING, + base::ASCIIToUTF16(cloud_devices::kCloudPrintDeprecationHelpURL))); + } } void AddPrivacyStrings(content::WebUIDataSource* html_source,
diff --git a/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc b/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc index 6091f29..f0c5041 100644 --- a/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc +++ b/chrome/browser/ui/webui/signin/dice_web_signin_intercept_ui.cc
@@ -58,6 +58,7 @@ source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::ScriptSrc, "script-src chrome://resources chrome://test 'self';"); + source->DisableTrustedTypesCSP(); 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/vr/webxr_vr_transition_browser_test.cc b/chrome/browser/vr/webxr_vr_transition_browser_test.cc index e5b64957..2bc9362 100644 --- a/chrome/browser/vr/webxr_vr_transition_browser_test.cc +++ b/chrome/browser/vr/webxr_vr_transition_browser_test.cc
@@ -127,7 +127,7 @@ t->EndTest(); } -IN_PROC_BROWSER_TEST_F(WebXrVrOpenXrBrowserTest, TestSessionEnded) { +IN_PROC_BROWSER_TEST_F(WebXrVrOpenXrBrowserTest, DISABLED_TestSessionEnded) { TestWebXRSessionEndWhenEventTriggered( this, device_test::mojom::EventType::kSessionLost); }
diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn index 5bec0ee1..3f3fbfb 100644 --- a/chrome/browser/web_applications/components/BUILD.gn +++ b/chrome/browser/web_applications/components/BUILD.gn
@@ -4,6 +4,7 @@ source_set("components") { sources = [ + "app_icon_manager.cc", "app_icon_manager.h", "app_registrar.cc", "app_registrar.h",
diff --git a/chrome/browser/web_applications/components/app_icon_manager.cc b/chrome/browser/web_applications/components/app_icon_manager.cc new file mode 100644 index 0000000..2b0f13d2 --- /dev/null +++ b/chrome/browser/web_applications/components/app_icon_manager.cc
@@ -0,0 +1,87 @@ +// 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/web_applications/components/app_icon_manager.h" + +#include <map> +#include "chrome/common/web_application_info.h" +#include "third_party/skia/include/core/SkBitmap.h" + +namespace web_app { + +namespace { + +void WrapReadIconCallback(AppIconManager::ReadIconCallback callback, + IconPurpose ignored, + const SkBitmap& bitmap) { + std::move(callback).Run(bitmap); +} + +void WrapReadCompressedIconCallback( + AppIconManager::ReadCompressedIconCallback callback, + IconPurpose ignored, + std::vector<uint8_t> data) { + std::move(callback).Run(std::move(data)); +} + +} // namespace + +IconBitmaps::IconBitmaps() = default; + +IconBitmaps::~IconBitmaps() = default; + +IconBitmaps::IconBitmaps(const IconBitmaps&) = default; + +IconBitmaps::IconBitmaps(IconBitmaps&&) = default; + +void IconBitmaps::SetBitmapsForPurpose( + IconPurpose purpose, + std::map<SquareSizePx, SkBitmap> bitmaps) { + switch (purpose) { + case IconPurpose::ANY: + any = std::move(bitmaps); + return; + case IconPurpose::MONOCHROME: + // TODO (crbug.com/1114638): Monochrome support. + NOTREACHED(); + return; + case IconPurpose::MASKABLE: + maskable = std::move(bitmaps); + return; + } +} + +bool IconBitmaps::empty() { + // TODO (crbug.com/1114638): Check Monochrome if supported. + return any.empty() && maskable.empty(); +} + +void AppIconManager::ReadSmallestIconAny(const AppId& app_id, + SquareSizePx min_icon_size, + ReadIconCallback callback) const { + ReadIconWithPurposeCallback wrapped = + base::BindOnce(WrapReadIconCallback, std::move(callback)); + ReadSmallestIcon(app_id, {IconPurpose::ANY}, min_icon_size, + std::move(wrapped)); +} + +void AppIconManager::ReadSmallestCompressedIconAny( + const AppId& app_id, + SquareSizePx min_icon_size, + ReadCompressedIconCallback callback) const { + ReadCompressedIconWithPurposeCallback wrapped = + base::BindOnce(WrapReadCompressedIconCallback, std::move(callback)); + ReadSmallestCompressedIcon(app_id, {IconPurpose::ANY}, min_icon_size, + std::move(wrapped)); +} + +// static +void AppIconManager::WrapReadIconWithPurposeCallback( + ReadIconWithPurposeCallback callback, + IconPurpose purpose, + const SkBitmap& bitmap) { + std::move(callback).Run(purpose, bitmap); +} + +} // namespace web_app
diff --git a/chrome/browser/web_applications/components/app_icon_manager.h b/chrome/browser/web_applications/components/app_icon_manager.h index 76dbe84..ff65c92 100644 --- a/chrome/browser/web_applications/components/app_icon_manager.h +++ b/chrome/browser/web_applications/components/app_icon_manager.h
@@ -17,6 +17,21 @@ namespace web_app { +// Icon bitmaps for each IconPurpose. +struct IconBitmaps { + IconBitmaps(); + ~IconBitmaps(); + IconBitmaps(const IconBitmaps&); + IconBitmaps(IconBitmaps&&) noexcept; + void SetBitmapsForPurpose(IconPurpose purpose, + std::map<SquareSizePx, SkBitmap> bitmaps); + bool empty(); + + std::map<SquareSizePx, SkBitmap> any; + std::map<SquareSizePx, SkBitmap> maskable; + // TODO (crbug.com/1114638): Monochrome support. +}; + // Exclusively used from the UI thread. class AppIconManager { public: @@ -27,21 +42,23 @@ virtual void Shutdown() = 0; // Returns false if any icon in |icon_sizes_in_px| is missing from downloaded - // icons for a given app. |icon_sizes_in_px| must be sorted in ascending - // order. + // icons for a given app and |purpose|. virtual bool HasIcons( const AppId& app_id, + IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px) const = 0; - // Returns false if no downloaded icon matching |icon_size_in_px|. + // Returns whether there is a downloaded icon matching |icon_size_in_px| for + // any of the given |purposes|. virtual bool HasSmallestIcon(const AppId& app_id, - SquareSizePx icon_size_in_px) const = 0; + const std::vector<IconPurpose>& purposes, + SquareSizePx min_icon_size) const = 0; using ReadIconsCallback = base::OnceCallback<void(std::map<SquareSizePx, SkBitmap> icon_bitmaps)>; - - // Reads specified icon bitmaps for an app. Returns empty map in |callback| if - // IO error. |icon_sizes_in_px| must be sorted in ascending order. + // Reads specified icon bitmaps for an app and |purpose|. Returns empty map in + // |callback| if IO error. virtual void ReadIcons(const AppId& app_id, + IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px, ReadIconsCallback callback) const = 0; @@ -56,29 +73,57 @@ const AppId& app_id, ReadShortcutsMenuIconsCallback callback) const = 0; + // TODO (crbug.com/1102701): Callback with const ref instead of value. + using ReadIconBitmapsCallback = + base::OnceCallback<void(IconBitmaps icon_bitmaps)>; // Reads all icon bitmaps for an app. Returns empty |icon_bitmaps| in // |callback| if IO error. virtual void ReadAllIcons(const AppId& app_id, - ReadIconsCallback callback) const = 0; + ReadIconBitmapsCallback callback) const = 0; - // Reads smallest icon with size at least |icon_size_in_px|. Returns empty - // SkBitmap in |callback| if IO error. - using ReadIconCallback = base::OnceCallback<void(const SkBitmap&)>; + using ReadIconWithPurposeCallback = + base::OnceCallback<void(IconPurpose, const SkBitmap&)>; + // For each of |purposes|, in the given order, finds the smallest icon with + // size at least |icon_size_in_px|. Returns the first icon found, as a bitmap. + // Returns empty SkBitmap in |callback| if IO error. virtual void ReadSmallestIcon(const AppId& app_id, - SquareSizePx icon_size_in_px, - ReadIconCallback callback) const = 0; + const std::vector<IconPurpose>& purposes, + SquareSizePx min_icon_size, + ReadIconWithPurposeCallback callback) const = 0; - // Reads smallest icon, compressed as PNG with size at least - // |icon_size_in_px|. Returns empty |data| in |callback| if IO error. - using ReadCompressedIconCallback = - base::OnceCallback<void(std::vector<uint8_t> data)>; + using ReadIconCallback = base::OnceCallback<void(const SkBitmap&)>; + // Convenience method for |ReadSmallestIcon| with IconPurpose::ANY only. + void ReadSmallestIconAny(const AppId& app_id, + SquareSizePx min_icon_size, + ReadIconCallback callback) const; + + using ReadCompressedIconWithPurposeCallback = + base::OnceCallback<void(IconPurpose, std::vector<uint8_t> data)>; + // For each of |purposes|, in the given order, finds the smallest icon with + // size at least |icon_size_in_px|. Returns the first icon found, compressed + // as PNG. Returns empty |data| in |callback| if IO error. virtual void ReadSmallestCompressedIcon( const AppId& app_id, - SquareSizePx icon_size_in_px, - ReadCompressedIconCallback callback) const = 0; + const std::vector<IconPurpose>& purposes, + SquareSizePx min_icon_size, + ReadCompressedIconWithPurposeCallback callback) const = 0; + + using ReadCompressedIconCallback = + base::OnceCallback<void(std::vector<uint8_t> data)>; + // Convenience method for |ReadSmallestCompressedIcon| with IconPurpose::ANY + // only. + void ReadSmallestCompressedIconAny(const AppId& app_id, + SquareSizePx min_icon_size, + ReadCompressedIconCallback callback) const; virtual SkBitmap GetFavicon(const AppId& app_id) const = 0; + protected: + static void WrapReadIconWithPurposeCallback( + ReadIconWithPurposeCallback callback, + IconPurpose purpose, + const SkBitmap& bitmap); + private: DISALLOW_COPY_AND_ASSIGN(AppIconManager); };
diff --git a/chrome/browser/web_applications/components/app_registrar.h b/chrome/browser/web_applications/components/app_registrar.h index e6f36dae..d82c433 100644 --- a/chrome/browser/web_applications/components/app_registrar.h +++ b/chrome/browser/web_applications/components/app_registrar.h
@@ -109,16 +109,16 @@ const AppId& app_id) const = 0; // Represents which icon sizes we successfully downloaded from the IconInfos. - virtual std::vector<SquareSizePx> GetAppDownloadedIconSizes( + virtual std::vector<SquareSizePx> GetAppDownloadedIconSizesAny( const AppId& app_id) const = 0; // Returns the "shortcuts" field from the app manifest, use |AppIconManager| // to load shortcuts menu icons bitmaps data. - virtual std::vector<WebApplicationShortcutsMenuItemInfo> GetAppShortcutInfos( - const AppId& app_id) const = 0; + virtual std::vector<WebApplicationShortcutsMenuItemInfo> + GetAppShortcutsMenuItemInfos(const AppId& app_id) const = 0; // Represents which icon sizes we successfully downloaded from the - // ShortcutInfos. + // ShortcutsMenuItemInfos. virtual std::vector<std::vector<SquareSizePx>> GetAppDownloadedShortcutsMenuIconsSizes(const AppId& app_id) const = 0;
diff --git a/chrome/browser/web_applications/components/app_shortcut_manager.cc b/chrome/browser/web_applications/components/app_shortcut_manager.cc index 4e10461..b7fd06e 100644 --- a/chrome/browser/web_applications/components/app_shortcut_manager.cc +++ b/chrome/browser/web_applications/components/app_shortcut_manager.cc
@@ -177,7 +177,7 @@ RegisterShortcutsMenuCallback callback, ShortcutsMenuIconsBitmaps shortcuts_menu_icons_bitmaps) { std::vector<WebApplicationShortcutsMenuItemInfo> shortcuts_menu_item_infos = - registrar_->GetAppShortcutInfos(app_id); + registrar_->GetAppShortcutsMenuItemInfos(app_id); if (!shortcuts_menu_item_infos.empty()) { RegisterShortcutsMenuWithOs(app_id, shortcuts_menu_item_infos, shortcuts_menu_icons_bitmaps);
diff --git a/chrome/browser/web_applications/components/web_app_install_utils.cc b/chrome/browser/web_applications/components/web_app_install_utils.cc index e5132682..f9b063d 100644 --- a/chrome/browser/web_applications/components/web_app_install_utils.cc +++ b/chrome/browser/web_applications/components/web_app_install_utils.cc
@@ -25,8 +25,6 @@ namespace web_app { -using Purpose = blink::Manifest::ImageResource::Purpose; - namespace { // We restrict the number of icons to limit disk usage per installed PWA. This @@ -35,8 +33,8 @@ constexpr SquareSizePx kMaxIconSize = 1024; // Append non-empty square icons from |icons_map| onto the |square_icons| list. -void AddSquareIconsFromMap(const IconsMap& icons_map, - std::vector<SkBitmap>* square_icons) { +void AddSquareIconsFromMap(std::vector<SkBitmap>* square_icons, + const IconsMap& icons_map) { for (const auto& url_icon : icons_map) { for (const SkBitmap& icon : url_icon.second) { if (!icon.empty() && icon.width() == icon.height()) @@ -45,17 +43,17 @@ } } -// Append non-empty square icons from |icons_map| onto the -// |square_icons| list, if they are also in |icon_infos| with Purpose::ANY. +// Append non-empty square icons from |icons_map| onto the |square_icons| list, +// if they are also in |icon_infos|. void AddSquareIconsFromMapMatchingIconInfos( + std::vector<SkBitmap>* square_icons, const std::vector<WebApplicationIconInfo>& icon_infos, - const IconsMap& icons_map, - std::vector<SkBitmap>* square_icons) { + const IconsMap& icons_map) { for (const auto& url_icon : icons_map) { for (const SkBitmap& icon : url_icon.second) { if (!icon.empty() && icon.width() == icon.height()) { for (const auto& info : icon_infos) { - if (info.url == url_icon.first && info.purpose == Purpose::ANY) { + if (info.url == url_icon.first) { square_icons->push_back(icon); } } @@ -65,8 +63,9 @@ } // Append non-empty square icons from |bitmaps| onto the |square_icons| list. -void AddSquareIconsFromBitmaps(const std::map<SquareSizePx, SkBitmap>& bitmaps, - std::vector<SkBitmap>* square_icons) { +void AddSquareIconsFromBitmaps( + std::vector<SkBitmap>* square_icons, + const std::map<SquareSizePx, SkBitmap>& bitmaps) { for (const std::pair<const SquareSizePx, SkBitmap>& icon : bitmaps) { DCHECK_EQ(icon.first, icon.second.width()); DCHECK_EQ(icon.first, icon.second.height()); @@ -167,8 +166,8 @@ // should have added ANY if there was no purpose specified in the manifest). DCHECK(!icon.purpose.empty()); - for (Purpose purpose : icon.purpose) { - if (purpose != Purpose::ANY && purpose != Purpose::MASKABLE) + for (IconPurpose purpose : icon.purpose) { + if (purpose != IconPurpose::ANY && purpose != IconPurpose::MASKABLE) continue; WebApplicationIconInfo info; @@ -191,7 +190,7 @@ info.purpose = purpose; web_app_icons.push_back(std::move(info)); - if (purpose == Purpose::ANY) + if (purpose == IconPurpose::ANY) has_purpose_any = true; // Limit the number of icons we store on the user's machine. @@ -273,29 +272,54 @@ PopulateShortcutItemIcons(web_app_info, icons_map); } - // Ensure that all top-level icons that are in web_app_info are present, by - // generating icons for any sizes that have failed to download. This ensures - // that the created manifest for the web app does not contain links to icons - // that are not actually created and linked on disk. - std::vector<SkBitmap> square_icons; - if (icons_map) { - AddSquareIconsFromMapMatchingIconInfos(web_app_info->icon_infos, *icons_map, - &square_icons); - // Fall back to using all icons from |icons_map| if none match icon_infos. - if (square_icons.empty()) - AddSquareIconsFromMap(*icons_map, &square_icons); + std::vector<WebApplicationIconInfo> icon_infos_any; + std::vector<WebApplicationIconInfo> icon_infos_maskable; + for (WebApplicationIconInfo& icon_info : web_app_info->icon_infos) { + switch (icon_info.purpose) { + case IconPurpose::ANY: + icon_infos_any.push_back(icon_info); + break; + case IconPurpose::MASKABLE: + icon_infos_maskable.push_back(icon_info); + break; + case IconPurpose::MONOCHROME: + // Not used. + break; + } } - AddSquareIconsFromBitmaps(web_app_info->icon_bitmaps_any, &square_icons); + + std::vector<SkBitmap> square_icons_any; + std::vector<SkBitmap> square_icons_maskable; + if (icons_map) { + AddSquareIconsFromMapMatchingIconInfos(&square_icons_any, icon_infos_any, + *icons_map); + AddSquareIconsFromMapMatchingIconInfos(&square_icons_maskable, + icon_infos_maskable, *icons_map); + // Fall back to using all icons from |icons_map| if none match icon_infos. + if (square_icons_any.empty()) + AddSquareIconsFromMap(&square_icons_any, *icons_map); + } + AddSquareIconsFromBitmaps(&square_icons_any, web_app_info->icon_bitmaps_any); + + for (SkBitmap& bitmap : square_icons_maskable) { + // Retain any bitmaps provided as input to the installation. + if (web_app_info->icon_bitmaps_maskable.count(bitmap.width()) == 0) + web_app_info->icon_bitmaps_maskable[bitmap.width()] = std::move(bitmap); + } base::char16 icon_letter = web_app_info->title.empty() ? GenerateIconLetterFromUrl(web_app_info->app_url) : GenerateIconLetterFromAppName(web_app_info->title); web_app_info->generated_icon_color = SK_ColorTRANSPARENT; + // Ensure that all top-level icons that are in web_app_info with Purpose::ANY + // are present, by generating icons for any sizes that have failed to + // download. This ensures that the created manifest for the web app does not + // contain links to icons that are not actually created and linked on disk. // TODO(https://crbug.com/1029223): Don't resize before writing to disk, it's // not necessary and would simplify this code path to remove. SizeToBitmap size_to_icons = ResizeIconsAndGenerateMissing( - square_icons, SizesToGenerate(), icon_letter, + square_icons_any, SizesToGenerate(), icon_letter, &web_app_info->generated_icon_color, &web_app_info->is_generated_icon); for (auto& item : size_to_icons) {
diff --git a/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc b/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc index 3dc5a30..68eb4ce 100644 --- a/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc +++ b/chrome/browser/web_applications/components/web_app_install_utils_unittest.cc
@@ -196,12 +196,13 @@ UpdateWebAppInfoFromManifest(manifest, &web_app_info); EXPECT_EQ(3U, web_app_info.icon_infos.size()); - int maskable_count = 0; + std::map<IconPurpose, int> purpose_to_count; for (const auto& icon_info : web_app_info.icon_infos) { - if (icon_info.purpose == Purpose::MASKABLE) - maskable_count++; + purpose_to_count[icon_info.purpose]++; } - EXPECT_EQ(2, maskable_count); + EXPECT_EQ(1, purpose_to_count[IconPurpose::ANY]); + EXPECT_EQ(0, purpose_to_count[IconPurpose::MONOCHROME]); + EXPECT_EQ(2, purpose_to_count[IconPurpose::MASKABLE]); } // Tests that WebAppInfo is correctly updated when Manifest contains Shortcuts. @@ -513,7 +514,8 @@ } // Tests that when FilterAndResizeIconsGenerateMissing is called with maskable -// icons available, web_app_info.icon_bitmaps_any is correctly populated. +// icons available, web_app_info.icon_bitmaps_{any,maskable} are correctly +// populated. TEST(WebAppInstallUtils, FilterAndResizeIconsGenerateMissing_MaskableIcons) { // Construct |icons_map| to pass to FilterAndResizeIconsGenerateMissing(). IconsMap icons_map; @@ -540,10 +542,11 @@ FilterAndResizeIconsGenerateMissing(&web_app_info, &icons_map); EXPECT_EQ(SizesToGenerate().size(), web_app_info.icon_bitmaps_any.size()); - // Expect only icon at URL 1 to be used and resized. + // Expect only icon at URL 1 to be used and resized as. for (const auto& icon_bitmap : web_app_info.icon_bitmaps_any) { EXPECT_EQ(SK_ColorWHITE, icon_bitmap.second.getColor(0, 0)); } + EXPECT_EQ(2u, web_app_info.icon_bitmaps_maskable.size()); } // Tests that when FilterAndResizeIconsGenerateMissing is called with maskable
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.cc b/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.cc index ffc2466..67f82f91 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.cc
@@ -158,6 +158,14 @@ return results; } +void WrapCallbackAsPurposeAny( + BookmarkAppIconManager::ReadIconBitmapsCallback callback, + std::map<SquareSizePx, SkBitmap> icon_bitmaps) { + web_app::IconBitmaps result; + result.any = std::move(icon_bitmaps); + std::move(callback).Run(result); +} + } // anonymous namespace BookmarkAppIconManager::BookmarkAppIconManager(Profile* profile) @@ -171,10 +179,16 @@ bool BookmarkAppIconManager::HasIcons( const web_app::AppId& app_id, + IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px) const { const Extension* app = GetBookmarkApp(profile_, app_id); if (!app) return false; + if (icon_sizes_in_px.empty()) + return true; + // Legacy bookmark apps handle IconPurpose::ANY icons only. + if (purpose != IconPurpose::ANY) + return false; const ExtensionIconSet& icons = IconsInfo::GetIcons(app); @@ -190,10 +204,14 @@ bool BookmarkAppIconManager::HasSmallestIcon( const web_app::AppId& app_id, + const std::vector<IconPurpose>& purposes, SquareSizePx icon_size_in_px) const { const Extension* app = GetBookmarkApp(profile_, app_id); if (!app) return false; + // Legacy bookmark apps handle IconPurpose::ANY icons only. + if (!base::Contains(purposes, IconPurpose::ANY)) + return false; const ExtensionIconSet& icons = IconsInfo::GetIcons(app); @@ -205,18 +223,31 @@ void BookmarkAppIconManager::ReadIcons( const web_app::AppId& app_id, + IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px, ReadIconsCallback callback) const { - DCHECK(HasIcons(app_id, icon_sizes_in_px)); - ReadExtensionIcons(profile_, app_id, icon_sizes_in_px, std::move(callback)); + DCHECK(HasIcons(app_id, purpose, icon_sizes_in_px)); + // Legacy bookmark apps handle IconPurpose::ANY icons only. + if (purpose != IconPurpose::ANY) { + std::move(callback).Run(std::map<SquareSizePx, SkBitmap>()); + return; + } + const std::vector<SquareSizePx> icon_sizes_vector(icon_sizes_in_px.begin(), + icon_sizes_in_px.end()); + ReadExtensionIcons(profile_, app_id, icon_sizes_vector, std::move(callback)); } -void BookmarkAppIconManager::ReadAllIcons(const web_app::AppId& app_id, - ReadIconsCallback callback) const { +void BookmarkAppIconManager::ReadAllIcons( + const web_app::AppId& app_id, + ReadIconBitmapsCallback callback) const { const Extension* app = GetBookmarkApp(profile_, app_id); DCHECK(app); + + ReadIconsCallback wrapped_callback = + base::BindOnce(WrapCallbackAsPurposeAny, std::move(callback)); + ReadExtensionIcons(profile_, app_id, GetBookmarkAppDownloadedIconSizes(app), - std::move(callback)); + std::move(wrapped_callback)); } void BookmarkAppIconManager::ReadAllShortcutsMenuIcons( @@ -243,21 +274,26 @@ std::move(callback)); } -void BookmarkAppIconManager::ReadSmallestIcon(const web_app::AppId& app_id, - SquareSizePx icon_size_in_px, - ReadIconCallback callback) const { - DCHECK(HasSmallestIcon(app_id, icon_size_in_px)); +void BookmarkAppIconManager::ReadSmallestIcon( + const web_app::AppId& app_id, + const std::vector<IconPurpose>& purposes, + SquareSizePx icon_size_in_px, + ReadIconWithPurposeCallback callback) const { + DCHECK(HasSmallestIcon(app_id, purposes, icon_size_in_px)); + ReadIconCallback wrapped = base::BindOnce( + WrapReadIconWithPurposeCallback, std::move(callback), IconPurpose::ANY); ReadExtensionIcon(profile_, app_id, icon_size_in_px, - ExtensionIconSet::MATCH_BIGGER, std::move(callback)); + ExtensionIconSet::MATCH_BIGGER, std::move(wrapped)); } void BookmarkAppIconManager::ReadSmallestCompressedIcon( const web_app::AppId& app_id, + const std::vector<IconPurpose>& purposes, SquareSizePx icon_size_in_px, - ReadCompressedIconCallback callback) const { + ReadCompressedIconWithPurposeCallback callback) const { NOTIMPLEMENTED(); - DCHECK(HasSmallestIcon(app_id, icon_size_in_px)); - std::move(callback).Run(std::vector<uint8_t>()); + DCHECK(HasSmallestIcon(app_id, purposes, icon_size_in_px)); + std::move(callback).Run(IconPurpose::ANY, std::vector<uint8_t>()); } SkBitmap BookmarkAppIconManager::GetFavicon(
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.h b/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.h index 7a9a1d7..b6bc5ec8 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.h +++ b/chrome/browser/web_applications/extensions/bookmark_app_icon_manager.h
@@ -26,24 +26,29 @@ void Shutdown() override; bool HasIcons( const web_app::AppId& app_id, + IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px) const override; bool HasSmallestIcon(const web_app::AppId& app_id, + const std::vector<IconPurpose>& purposes, SquareSizePx icon_size_in_px) const override; void ReadIcons(const web_app::AppId& app_id, + IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px, ReadIconsCallback callback) const override; void ReadAllIcons(const web_app::AppId& app_id, - ReadIconsCallback callback) const override; + ReadIconBitmapsCallback callback) const override; void ReadAllShortcutsMenuIcons( const web_app::AppId& app_id, ReadShortcutsMenuIconsCallback callback) const override; void ReadSmallestIcon(const web_app::AppId& app_id, + const std::vector<IconPurpose>& purposes, SquareSizePx icon_size_in_px, - ReadIconCallback callback) const override; + ReadIconWithPurposeCallback callback) const override; void ReadSmallestCompressedIcon( const web_app::AppId& app_id, + const std::vector<IconPurpose>& purposes, SquareSizePx icon_size_in_px, - ReadCompressedIconCallback callback) const override; + ReadCompressedIconWithPurposeCallback callback) const override; SkBitmap GetFavicon(const web_app::AppId& app_id) const override; private:
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc b/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc index c472edfb..db5f962 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc +++ b/chrome/browser/web_applications/extensions/bookmark_app_registrar.cc
@@ -232,7 +232,7 @@ return result; } -std::vector<SquareSizePx> BookmarkAppRegistrar::GetAppDownloadedIconSizes( +std::vector<SquareSizePx> BookmarkAppRegistrar::GetAppDownloadedIconSizesAny( const web_app::AppId& app_id) const { const Extension* extension = GetBookmarkAppDchecked(app_id); return extension ? GetBookmarkAppDownloadedIconSizes(extension) @@ -240,7 +240,8 @@ } std::vector<WebApplicationShortcutsMenuItemInfo> -BookmarkAppRegistrar::GetAppShortcutInfos(const web_app::AppId& app_id) const { +BookmarkAppRegistrar::GetAppShortcutsMenuItemInfos( + const web_app::AppId& app_id) const { std::vector<WebApplicationShortcutsMenuItemInfo> result; const Extension* extension = GetBookmarkAppDchecked(app_id); if (!extension)
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_registrar.h b/chrome/browser/web_applications/extensions/bookmark_app_registrar.h index f6377784f..9d6f6df9 100644 --- a/chrome/browser/web_applications/extensions/bookmark_app_registrar.h +++ b/chrome/browser/web_applications/extensions/bookmark_app_registrar.h
@@ -57,9 +57,9 @@ base::Time GetAppInstallTime(const web_app::AppId& app_id) const override; std::vector<WebApplicationIconInfo> GetAppIconInfos( const web_app::AppId& app_id) const override; - std::vector<SquareSizePx> GetAppDownloadedIconSizes( + std::vector<SquareSizePx> GetAppDownloadedIconSizesAny( const web_app::AppId& app_id) const override; - std::vector<WebApplicationShortcutsMenuItemInfo> GetAppShortcutInfos( + std::vector<WebApplicationShortcutsMenuItemInfo> GetAppShortcutsMenuItemInfos( const web_app::AppId& app_id) const override; std::vector<std::vector<SquareSizePx>> GetAppDownloadedShortcutsMenuIconsSizes(
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc index 9707f63..08920df 100644 --- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc +++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -1045,7 +1045,7 @@ // Check that the installed icon is now blue. base::RunLoop run_loop; GetProvider().icon_manager().ReadIcons( - app_id, {192}, + app_id, IconPurpose::ANY, {192}, base::BindLambdaForTesting( [&run_loop](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { run_loop.Quit(); @@ -1108,7 +1108,7 @@ // Check that the installed icon is still black. base::RunLoop run_loop; GetProvider().icon_manager().ReadIcons( - app_id, {48, 192}, + app_id, IconPurpose::ANY, {48, 192}, base::BindLambdaForTesting( [&run_loop](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { run_loop.Quit(); @@ -1246,7 +1246,9 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - EXPECT_EQ(GetProvider().registrar().GetAppShortcutInfos(app_id).size(), 2u); + EXPECT_EQ( + GetProvider().registrar().GetAppShortcutsMenuItemInfos(app_id).size(), + 2u); } IN_PROC_BROWSER_TEST_P(ManifestUpdateManagerBrowserTestWithShortcutsMenu, @@ -1284,8 +1286,9 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - EXPECT_EQ(GetProvider().registrar().GetAppShortcutInfos(app_id)[0].name, - base::UTF8ToUTF16(kAnotherShortcutsItemName)); + EXPECT_EQ( + GetProvider().registrar().GetAppShortcutsMenuItemInfos(app_id)[0].name, + base::UTF8ToUTF16(kAnotherShortcutsItemName)); } IN_PROC_BROWSER_TEST_P(ManifestUpdateManagerBrowserTestWithShortcutsMenu, @@ -1361,8 +1364,9 @@ ManifestUpdateResult::kAppUpdated); histogram_tester_.ExpectBucketCount(kUpdateHistogramName, ManifestUpdateResult::kAppUpdated, 1); - EXPECT_EQ(GetProvider().registrar().GetAppShortcutInfos(app_id)[0].url, - http_server_.GetURL(kAnotherShortcutsItemUrl)); + EXPECT_EQ( + GetProvider().registrar().GetAppShortcutsMenuItemInfos(app_id)[0].url, + http_server_.GetURL(kAnotherShortcutsItemUrl)); } IN_PROC_BROWSER_TEST_P(ManifestUpdateManagerBrowserTestWithShortcutsMenu, @@ -1463,7 +1467,7 @@ ManifestUpdateResult::kAppUpdated, 1); EXPECT_EQ(GetProvider() .registrar() - .GetAppShortcutInfos(app_id)[0] + .GetAppShortcutsMenuItemInfos(app_id)[0] .shortcut_icon_infos[0] .url, http_server_.GetURL(kAnotherIconSrc)); @@ -1507,7 +1511,7 @@ ManifestUpdateResult::kAppUpdated, 1); EXPECT_EQ(GetProvider() .registrar() - .GetAppShortcutInfos(app_id)[0] + .GetAppShortcutsMenuItemInfos(app_id)[0] .shortcut_icon_infos[0] .square_size_px, kAnotherIconSize);
diff --git a/chrome/browser/web_applications/manifest_update_task.cc b/chrome/browser/web_applications/manifest_update_task.cc index 5ce9b4847..5dee3c88 100644 --- a/chrome/browser/web_applications/manifest_update_task.cc +++ b/chrome/browser/web_applications/manifest_update_task.cc
@@ -172,7 +172,7 @@ if (base::FeatureList::IsEnabled( features::kDesktopPWAsAppIconShortcutsMenu) && web_application_info_->shortcuts_menu_item_infos != - registrar_.GetAppShortcutInfos(app_id_)) { + registrar_.GetAppShortcutsMenuItemInfos(app_id_)) { return true; } @@ -222,9 +222,8 @@ std::move(icons_map))); } -void ManifestUpdateTask::OnAllIconsRead( - IconsMap downloaded_icons_map, - std::map<SquareSizePx, SkBitmap> disk_icon_bitmaps) { +void ManifestUpdateTask::OnAllIconsRead(IconsMap downloaded_icons_map, + IconBitmaps disk_icon_bitmaps) { DCHECK(stage_ == Stage::kPendingIconReadFromDisk); if (disk_icon_bitmaps.empty()) { @@ -254,12 +253,20 @@ } bool ManifestUpdateTask::IsUpdateNeededForIconContents( - const std::map<SquareSizePx, SkBitmap>& disk_icon_bitmaps) const { + const IconBitmaps& disk_icon_bitmaps) const { DCHECK(web_application_info_.has_value()); - const std::map<SquareSizePx, SkBitmap>& downloaded_icon_bitmaps = + const std::map<SquareSizePx, SkBitmap>& downloaded_icon_bitmaps_any = web_application_info_->icon_bitmaps_any; - if (HaveIconContentsChanged(disk_icon_bitmaps, downloaded_icon_bitmaps)) + if (HaveIconContentsChanged(disk_icon_bitmaps.any, + downloaded_icon_bitmaps_any)) { return true; + } + const std::map<SquareSizePx, SkBitmap>& downloaded_icon_bitmaps_maskable = + web_application_info_->icon_bitmaps_maskable; + if (HaveIconContentsChanged(disk_icon_bitmaps.maskable, + downloaded_icon_bitmaps_maskable)) { + return true; + } return false; }
diff --git a/chrome/browser/web_applications/manifest_update_task.h b/chrome/browser/web_applications/manifest_update_task.h index 35ba303..7dbe4b00 100644 --- a/chrome/browser/web_applications/manifest_update_task.h +++ b/chrome/browser/web_applications/manifest_update_task.h
@@ -10,6 +10,7 @@ #include "base/check_op.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" +#include "chrome/browser/web_applications/components/app_icon_manager.h" #include "chrome/browser/web_applications/components/web_app_icon_downloader.h" #include "chrome/browser/web_applications/components/web_app_id.h" #include "chrome/common/web_application_info.h" @@ -101,9 +102,9 @@ void LoadAndCheckIconContents(); void OnIconsDownloaded(bool success, IconsMap icons_map); void OnAllIconsRead(IconsMap downloaded_icons_map, - std::map<SquareSizePx, SkBitmap> disk_icon_bitmaps); + IconBitmaps disk_icon_bitmaps); bool IsUpdateNeededForIconContents( - const std::map<SquareSizePx, SkBitmap>& disk_icon_bitmaps) const; + const IconBitmaps& disk_icon_bitmaps) const; void OnAllShortcutsMenuIconsRead( ShortcutsMenuIconsBitmaps disk_shortcuts_menu_icons); bool IsUpdateNeededForShortcutsMenuIconsContents(
diff --git a/chrome/browser/web_applications/proto/web_app.proto b/chrome/browser/web_applications/proto/web_app.proto index 14a8b734..130228e13 100644 --- a/chrome/browser/web_applications/proto/web_app.proto +++ b/chrome/browser/web_applications/proto/web_app.proto
@@ -95,10 +95,15 @@ optional bool is_in_sync_install = 9; // A list of icon infos. repeated sync_pb.WebAppIconInfo icon_infos = 10; - // A list of icon sizes we successfully downloaded to store on disk. - repeated int32 downloaded_icon_sizes = 11; + + // A list of icon sizes we successfully downloaded to store on disk, for icons + // that are suitable for any purpose (ie. IconPurpose::ANY). See also: + // |downloaded_icon_sizes_purpose_maskable|. + repeated int32 downloaded_icon_sizes_purpose_any = 11; + // A list of file handlers. repeated WebAppFileHandlerProto file_handlers = 12; + // A list of additional search terms to use when searching for the app. repeated string additional_search_terms = 13; @@ -131,4 +136,9 @@ // A list of display modes specified in app manifest. repeated DisplayMode display_mode_override = 22; + + // A list of icon sizes we successfully downloaded to store on disk, for icons + // that are designed for masking (ie. IconPurpose::MASKABLE). See also: + // |downloaded_icon_sizes_purpose_any|. + repeated int32 downloaded_icon_sizes_purpose_maskable = 23; }
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc index af1f53c..72d784c 100644 --- a/chrome/browser/web_applications/system_web_app_manager.cc +++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -184,6 +184,7 @@ infos.at(SystemAppType::SAMPLE).enabled_origin_trials = OriginTrialsMap( {{GetOrigin("chrome://sample-system-web-app"), {"Frobulate"}}, {GetOrigin("chrome-untrusted://sample-system-web-app"), {"Frobulate"}}}); + infos.at(SystemAppType::SAMPLE).capture_navigations = true; #endif // !defined(OFFICIAL_BUILD) #endif // OS_CHROMEOS @@ -191,6 +192,11 @@ return infos; } +bool HasSystemWebAppScheme(const GURL& url) { + return url.SchemeIs(content::kChromeUIScheme) || + url.SchemeIs(content::kChromeUIUntrustedScheme); +} + ExternalInstallOptions CreateInstallOptionsForSystemApp( const SystemAppInfo& info, bool force_update, @@ -550,6 +556,29 @@ return it->second.show_in_search; } +base::Optional<SystemAppType> SystemWebAppManager::GetCapturingSystemAppForURL( + const GURL& url) const { + if (!HasSystemWebAppScheme(url)) + return base::nullopt; + + base::Optional<AppId> app_id = registrar_->FindAppWithUrlInScope(url); + if (!app_id.has_value()) + return base::nullopt; + + base::Optional<SystemAppType> type = GetSystemAppTypeForAppId(app_id.value()); + if (!type.has_value()) + return base::nullopt; + + const auto it = system_app_infos_.find(type); + if (it == system_app_infos_.end()) + return base::nullopt; + + if (!it->second.capture_navigations) + return base::nullopt; + + return type; +} + gfx::Size SystemWebAppManager::GetMinimumWindowSize(const AppId& app_id) const { auto app_type_it = app_id_to_app_type_.find(app_id); if (app_type_it == app_id_to_app_type_.end())
diff --git a/chrome/browser/web_applications/system_web_app_manager.h b/chrome/browser/web_applications/system_web_app_manager.h index c8f1b95..b01f59a5 100644 --- a/chrome/browser/web_applications/system_web_app_manager.h +++ b/chrome/browser/web_applications/system_web_app_manager.h
@@ -113,6 +113,11 @@ // If set to false, this app will be hidden from the Chrome OS search. bool show_in_search = true; + // If set to true, navigations (e.g. Omnibox URL, anchor link) to this app + // will open in the app's window instead of the navigation's context (e.g. + // browser tab). + bool capture_navigations = false; + WebApplicationInfoFactory app_info_factory; }; @@ -199,6 +204,10 @@ // Returns whether the app should be shown in search. bool ShouldShowInSearch(SystemAppType type) const; + // Returns the SystemAppType that should capture the navigation to |url|. + base::Optional<SystemAppType> GetCapturingSystemAppForURL( + const GURL& url) const; + // Returns the minimum window size for |app_id| or an empty size if the app // doesn't specify a minimum. gfx::Size GetMinimumWindowSize(const AppId& app_id) const;
diff --git a/chrome/browser/web_applications/test/test_app_registrar.cc b/chrome/browser/web_applications/test/test_app_registrar.cc index 7703903c..a460ec7 100644 --- a/chrome/browser/web_applications/test/test_app_registrar.cc +++ b/chrome/browser/web_applications/test/test_app_registrar.cc
@@ -153,14 +153,14 @@ return {}; } -std::vector<SquareSizePx> TestAppRegistrar::GetAppDownloadedIconSizes( +std::vector<SquareSizePx> TestAppRegistrar::GetAppDownloadedIconSizesAny( const AppId& app_id) const { NOTIMPLEMENTED(); return {}; } std::vector<WebApplicationShortcutsMenuItemInfo> -TestAppRegistrar::GetAppShortcutInfos(const AppId& app_id) const { +TestAppRegistrar::GetAppShortcutsMenuItemInfos(const AppId& app_id) const { NOTIMPLEMENTED(); return {}; }
diff --git a/chrome/browser/web_applications/test/test_app_registrar.h b/chrome/browser/web_applications/test/test_app_registrar.h index 8e0e5b0..be7bb03 100644 --- a/chrome/browser/web_applications/test/test_app_registrar.h +++ b/chrome/browser/web_applications/test/test_app_registrar.h
@@ -68,9 +68,9 @@ base::Time GetAppInstallTime(const web_app::AppId& app_id) const override; std::vector<WebApplicationIconInfo> GetAppIconInfos( const AppId& app_id) const override; - std::vector<SquareSizePx> GetAppDownloadedIconSizes( + std::vector<SquareSizePx> GetAppDownloadedIconSizesAny( const AppId& app_id) const override; - std::vector<WebApplicationShortcutsMenuItemInfo> GetAppShortcutInfos( + std::vector<WebApplicationShortcutsMenuItemInfo> GetAppShortcutsMenuItemInfos( const AppId& app_id) const override; std::vector<std::vector<SquareSizePx>> GetAppDownloadedShortcutsMenuIconsSizes(const AppId& app_id) const override;
diff --git a/chrome/browser/web_applications/test/test_system_web_app_installation.cc b/chrome/browser/web_applications/test/test_system_web_app_installation.cc index 1f1b1af..d6a60a9 100644 --- a/chrome/browser/web_applications/test/test_system_web_app_installation.cc +++ b/chrome/browser/web_applications/test/test_system_web_app_installation.cc
@@ -83,11 +83,10 @@ SystemAppInfo info) : type_(type) { if (GetWebUIType(info.install_url) == WebUIType::kChrome) { - web_ui_controller_factory_ = - std::make_unique<TestSystemWebAppWebUIControllerFactory>( - GetDataSourceNameFromSystemAppInstallUrl(info.install_url)); - content::WebUIControllerFactory::RegisterFactory( - web_ui_controller_factory_.get()); + auto factory = std::make_unique<TestSystemWebAppWebUIControllerFactory>( + GetDataSourceNameFromSystemAppInstallUrl(info.install_url)); + content::WebUIControllerFactory::RegisterFactory(factory.get()); + web_ui_controller_factories_.push_back(std::move(factory)); } test_web_app_provider_creator_ = std::make_unique<TestWebAppProviderCreator>( @@ -113,10 +112,8 @@ } TestSystemWebAppInstallation::~TestSystemWebAppInstallation() { - if (web_ui_controller_factory_.get()) { - content::WebUIControllerFactory::UnregisterFactoryForTesting( - web_ui_controller_factory_.get()); - } + for (auto& factory : web_ui_controller_factories_) + content::WebUIControllerFactory::UnregisterFactoryForTesting(factory.get()); } // static @@ -226,6 +223,28 @@ // static std::unique_ptr<TestSystemWebAppInstallation> +TestSystemWebAppInstallation::SetUpAppThatCapturesNavigation() { + SystemAppInfo app_info("Test", GURL("chrome://test-system-web-app/pwa.html")); + app_info.capture_navigations = true; + + auto* installation = new TestSystemWebAppInstallation(SystemAppType::HELP, + std::move(app_info)); + + // Add a helper system app to test capturing links from it. + const GURL kInitiatingAppUrl = GURL("chrome://initiating-app/pwa.html"); + installation->extra_apps_.insert_or_assign( + SystemAppType::SETTINGS, + SystemAppInfo("Initiating App", kInitiatingAppUrl)); + auto factory = std::make_unique<TestSystemWebAppWebUIControllerFactory>( + kInitiatingAppUrl.host()); + content::WebUIControllerFactory::RegisterFactory(factory.get()); + installation->web_ui_controller_factories_.push_back(std::move(factory)); + + return base::WrapUnique(installation); +} + +// static +std::unique_ptr<TestSystemWebAppInstallation> TestSystemWebAppInstallation::SetUpChromeUntrustedApp() { return base::WrapUnique(new TestSystemWebAppInstallation( SystemAppType::SETTINGS, @@ -236,6 +255,11 @@ std::unique_ptr<KeyedService> TestSystemWebAppInstallation::CreateWebAppProvider(SystemAppInfo info, Profile* profile) { + DCHECK(!extra_apps_.contains(type_.value())); + + base::flat_map<SystemAppType, SystemAppInfo> apps(extra_apps_); + apps.insert_or_assign(type_.value(), info); + profile_ = profile; if (GetWebUIType(info.install_url) == WebUIType::kChromeUntrusted) { web_app::AddTestURLDataSource( @@ -245,7 +269,7 @@ auto provider = std::make_unique<TestWebAppProvider>(profile); auto system_web_app_manager = std::make_unique<SystemWebAppManager>(profile); - system_web_app_manager->SetSystemAppsForTesting({{type_.value(), info}}); + system_web_app_manager->SetSystemAppsForTesting(apps); system_web_app_manager->SetUpdatePolicyForTesting(update_policy_); provider->SetSystemWebAppManager(std::move(system_web_app_manager)); provider->Start(); @@ -301,7 +325,7 @@ } void TestSystemWebAppInstallation::SetManifest(std::string manifest) { - web_ui_controller_factory_->set_manifest(std::move(manifest)); + web_ui_controller_factories_[0]->set_manifest(std::move(manifest)); } void TestSystemWebAppInstallation::RegisterAutoGrantedPermissions(
diff --git a/chrome/browser/web_applications/test/test_system_web_app_installation.h b/chrome/browser/web_applications/test/test_system_web_app_installation.h index b90ade2..3ec8629 100644 --- a/chrome/browser/web_applications/test/test_system_web_app_installation.h +++ b/chrome/browser/web_applications/test/test_system_web_app_installation.h
@@ -54,6 +54,11 @@ static std::unique_ptr<TestSystemWebAppInstallation> SetUpAppWithAdditionalSearchTerms(); + // This method additionally sets up a helper SystemAppType::SETTING system app + // for testing capturing links from a different SWA. + static std::unique_ptr<TestSystemWebAppInstallation> + SetUpAppThatCapturesNavigation(); + static std::unique_ptr<TestSystemWebAppInstallation> SetUpChromeUntrustedApp(); @@ -90,9 +95,10 @@ std::unique_ptr<TestWebAppProviderCreator> test_web_app_provider_creator_; // nullopt if SetUpWithoutApps() was used. const base::Optional<SystemAppType> type_; - std::unique_ptr<TestSystemWebAppWebUIControllerFactory> - web_ui_controller_factory_; + std::vector<std::unique_ptr<TestSystemWebAppWebUIControllerFactory>> + web_ui_controller_factories_; std::set<ContentSettingsType> auto_granted_permissions_; + base::flat_map<SystemAppType, SystemAppInfo> extra_apps_; }; } // namespace web_app
diff --git a/chrome/browser/web_applications/test/test_system_web_app_url_data_source.cc b/chrome/browser/web_applications/test/test_system_web_app_url_data_source.cc index 14151ee..f781bab 100644 --- a/chrome/browser/web_applications/test/test_system_web_app_url_data_source.cc +++ b/chrome/browser/web_applications/test/test_system_web_app_url_data_source.cc
@@ -28,6 +28,11 @@ </html> )"; +constexpr char kPage2Html[] = + R"( +<!DOCTYPE html><title>Page 2</title> + )"; + constexpr char kSwJs[] = "globalThis.addEventListener('fetch', event => {});"; } // namespace @@ -43,10 +48,12 @@ content::BrowserContext* browser_context) { content::WebUIDataSource* data_source = content::WebUIDataSource::Create(source_name); + data_source->DisableTrustedTypesCSP(); data_source->AddResourcePath("icon-256.png", IDR_PRODUCT_LOGO_256); data_source->SetRequestFilter( base::BindLambdaForTesting([](const std::string& path) { - return path == "manifest.json" || path == "pwa.html"; + return path == "manifest.json" || path == "pwa.html" || + path == "page2.html"; }), base::BindLambdaForTesting( [manifest_text](const std::string& id, @@ -59,6 +66,8 @@ ref_contents->data() = kPwaHtml; else if (id == "sw.js") ref_contents->data() = kSwJs; + else if (id == "page2.html") + ref_contents->data() = kPage2Html; else NOTREACHED();
diff --git a/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.cc b/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.cc index e033b32..202495c 100644 --- a/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.cc +++ b/chrome/browser/web_applications/test/test_system_web_app_web_ui_controller_factory.cc
@@ -40,6 +40,11 @@ TestSystemWebAppWebUIControllerFactory::CreateWebUIControllerForURL( content::WebUI* web_ui, const GURL& url) { + if (!url.SchemeIs(content::kChromeUIScheme) || + url.host_piece() != source_name_) { + return nullptr; + } + return std::make_unique<TestSystemWebAppWebUIController>(source_name_, &manifest_, web_ui); } @@ -47,7 +52,7 @@ content::WebUI::TypeID TestSystemWebAppWebUIControllerFactory::GetWebUIType( content::BrowserContext* browser_context, const GURL& url) { - if (url.SchemeIs(content::kChromeUIScheme)) + if (UseWebUIForURL(browser_context, url)) return reinterpret_cast<content::WebUI::TypeID>(1); return content::WebUI::kNoWebUI; @@ -56,11 +61,12 @@ bool TestSystemWebAppWebUIControllerFactory::UseWebUIForURL( content::BrowserContext* browser_context, const GURL& url) { - return url.SchemeIs(content::kChromeUIScheme); + return url.SchemeIs(content::kChromeUIScheme) && + url.host_piece() == source_name_; } bool TestSystemWebAppWebUIControllerFactory::UseWebUIBindingsForURL( content::BrowserContext* browser_context, const GURL& url) { - return url.SchemeIs(content::kChromeUIScheme); + return UseWebUIForURL(browser_context, url); }
diff --git a/chrome/browser/web_applications/test/web_app_icon_test_utils.cc b/chrome/browser/web_applications/test/web_app_icon_test_utils.cc index adf0c406..937efcd 100644 --- a/chrome/browser/web_applications/test/web_app_icon_test_utils.cc +++ b/chrome/browser/web_applications/test/web_app_icon_test_utils.cc
@@ -68,7 +68,7 @@ abs_error_b <= threshold && abs_error_a <= threshold; } -base::FilePath GetAppIconsDir(Profile* profile, const AppId& app_id) { +base::FilePath GetAppIconsAnyDir(Profile* profile, const AppId& app_id) { base::FilePath web_apps_root_directory = GetWebAppsRootDirectory(profile); base::FilePath app_dir = GetManifestResourcesDirectoryForApp(web_apps_root_directory, app_id); @@ -76,6 +76,14 @@ return icons_dir; } +base::FilePath GetAppIconsMaskableDir(Profile* profile, const AppId& app_id) { + base::FilePath web_apps_root_directory = GetWebAppsRootDirectory(profile); + base::FilePath app_dir = + GetManifestResourcesDirectoryForApp(web_apps_root_directory, app_id); + base::FilePath icons_dir = app_dir.AppendASCII("Icons Maskable"); + return icons_dir; +} + bool ReadBitmap(FileUtilsWrapper* utils, const base::FilePath& file_path, SkBitmap* bitmap) {
diff --git a/chrome/browser/web_applications/test/web_app_icon_test_utils.h b/chrome/browser/web_applications/test/web_app_icon_test_utils.h index b039611..2762dfb 100644 --- a/chrome/browser/web_applications/test/web_app_icon_test_utils.h +++ b/chrome/browser/web_applications/test/web_app_icon_test_utils.h
@@ -37,7 +37,9 @@ SkColor actual_color, int threshold); -base::FilePath GetAppIconsDir(Profile* profile, const AppId& app_id); +base::FilePath GetAppIconsAnyDir(Profile* profile, const AppId& app_id); + +base::FilePath GetAppIconsMaskableDir(Profile* profile, const AppId& app_id); bool ReadBitmap(FileUtilsWrapper* utils, const base::FilePath& file_path,
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc index d66559e..b5e1dd7 100644 --- a/chrome/browser/web_applications/web_app.cc +++ b/chrome/browser/web_applications/web_app.cc
@@ -43,6 +43,20 @@ WebApp& WebApp::operator=(WebApp&& web_app) = default; +const std::vector<SquareSizePx>& WebApp::downloaded_icon_sizes( + IconPurpose purpose) const { + switch (purpose) { + case IconPurpose::ANY: + return downloaded_icon_sizes_any_; + case IconPurpose::MONOCHROME: + // TODO (crbug.com/1114638): Download monochrome icons. + NOTREACHED(); + return downloaded_icon_sizes_monochrome_; + case IconPurpose::MASKABLE: + return downloaded_icon_sizes_maskable_; + } +} + void WebApp::AddSource(Source::Type source) { sources_[source] = true; } @@ -186,9 +200,21 @@ icon_infos_ = std::move(icon_infos); } -void WebApp::SetDownloadedIconSizes(std::vector<SquareSizePx> sizes) { +void WebApp::SetDownloadedIconSizes(IconPurpose purpose, + std::vector<SquareSizePx> sizes) { std::sort(sizes.begin(), sizes.end()); - downloaded_icon_sizes_ = std::move(sizes); + switch (purpose) { + case IconPurpose::ANY: + downloaded_icon_sizes_any_ = std::move(sizes); + break; + case IconPurpose::MONOCHROME: + // TODO (crbug.com/1114638): Add monochrome icons support. + NOTREACHED(); + break; + case IconPurpose::MASKABLE: + downloaded_icon_sizes_maskable_ = std::move(sizes); + break; + } } void WebApp::SetIsGeneratedIcon(bool is_generated_icon) { @@ -284,8 +310,10 @@ << " is_generated_icon: " << app.is_generated_icon_ << std::endl; for (const WebApplicationIconInfo& icon : app.icon_infos_) out << " icon_info: " << icon << std::endl; - for (SquareSizePx size : app.downloaded_icon_sizes_) - out << " icon_size_on_disk: " << size << std::endl; + for (SquareSizePx size : app.downloaded_icon_sizes_any_) + out << " downloaded_icon_sizes_any_: " << size << std::endl; + for (SquareSizePx size : app.downloaded_icon_sizes_maskable_) + out << " downloaded_icon_sizes_maskable_: " << size << std::endl; for (const apps::FileHandler& file_handler : app.file_handlers_) out << " file_handler: " << file_handler << std::endl; for (const std::string& additional_search_term : app.additional_search_terms_) @@ -319,7 +347,8 @@ return std::tie(app1.app_id_, app1.sources_, app1.name_, app1.launch_url_, app1.description_, app1.scope_, app1.theme_color_, app1.background_color_, app1.icon_infos_, - app1.downloaded_icon_sizes_, app1.is_generated_icon_, + app1.downloaded_icon_sizes_any_, + app1.downloaded_icon_sizes_maskable_, app1.is_generated_icon_, app1.display_mode_, app1.display_mode_override_, app1.user_display_mode_, app1.user_page_ordinal_, app1.user_launch_ordinal_, app1.chromeos_data_, @@ -330,7 +359,8 @@ std::tie(app2.app_id_, app2.sources_, app2.name_, app2.launch_url_, app2.description_, app2.scope_, app2.theme_color_, app2.background_color_, app2.icon_infos_, - app2.downloaded_icon_sizes_, app2.is_generated_icon_, + app2.downloaded_icon_sizes_any_, + app2.downloaded_icon_sizes_maskable_, app2.is_generated_icon_, app2.display_mode_, app2.display_mode_override_, app2.user_display_mode_, app2.user_page_ordinal_, app2.user_launch_ordinal_, app2.chromeos_data_,
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h index 88f88453..1392f124 100644 --- a/chrome/browser/web_applications/web_app.h +++ b/chrome/browser/web_applications/web_app.h
@@ -90,11 +90,12 @@ return icon_infos_; } - // Represents which icon sizes we successfully downloaded from the icon_infos. - // Icon sizes are sorted in ascending order. - const std::vector<SquareSizePx>& downloaded_icon_sizes() const { - return downloaded_icon_sizes_; - } + // Represents which icon sizes we successfully downloaded from the + // |icon_infos| for the given |purpose|. Icon sizes are sorted in ascending + // order. + // TODO(crbug.com/1102701): Convert to use flat_set to enforce size ordering. + const std::vector<SquareSizePx>& downloaded_icon_sizes( + IconPurpose purpose) const; // Represents whether the icons for the web app are generated by Chrome due to // no suitable icons being available. @@ -177,7 +178,8 @@ void SetIsInSyncInstall(bool is_in_sync_install); void SetIconInfos(std::vector<WebApplicationIconInfo> icon_infos); // Performs sorting of |sizes| vector. Must be called rarely. - void SetDownloadedIconSizes(std::vector<SquareSizePx> sizes); + void SetDownloadedIconSizes(IconPurpose purpose, + std::vector<SquareSizePx> sizes); void SetIsGeneratedIcon(bool is_generated_icon); void SetShortcutsMenuItemInfos( std::vector<WebApplicationShortcutsMenuItemInfo> @@ -223,7 +225,10 @@ bool is_locally_installed_ = true; bool is_in_sync_install_ = false; std::vector<WebApplicationIconInfo> icon_infos_; - std::vector<SquareSizePx> downloaded_icon_sizes_; + std::vector<SquareSizePx> downloaded_icon_sizes_any_; + // TODO (crbug.com/1114638): Monochrome icons are not currently downloaded. + std::vector<SquareSizePx> downloaded_icon_sizes_monochrome_; + std::vector<SquareSizePx> downloaded_icon_sizes_maskable_; bool is_generated_icon_ = false; std::vector<WebApplicationShortcutsMenuItemInfo> shortcuts_menu_item_infos_; std::vector<std::vector<SquareSizePx>> downloaded_shortcuts_menu_icons_sizes_;
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc index 1d6a3ea7..8ba5194 100644 --- a/chrome/browser/web_applications/web_app_database.cc +++ b/chrome/browser/web_applications/web_app_database.cc
@@ -156,8 +156,13 @@ for (const WebApplicationIconInfo& icon_info : web_app.icon_infos()) *(local_data->add_icon_infos()) = WebAppIconInfoToSyncProto(icon_info); - for (SquareSizePx size : web_app.downloaded_icon_sizes()) - local_data->add_downloaded_icon_sizes(size); + for (SquareSizePx size : web_app.downloaded_icon_sizes(IconPurpose::ANY)) { + local_data->add_downloaded_icon_sizes_purpose_any(size); + } + for (SquareSizePx size : + web_app.downloaded_icon_sizes(IconPurpose::MASKABLE)) { + local_data->add_downloaded_icon_sizes_purpose_maskable(size); + } local_data->set_is_generated_icon(web_app.is_generated_icon()); @@ -371,10 +376,16 @@ } web_app->SetIconInfos(std::move(parsed_icon_infos.value())); - std::vector<SquareSizePx> icon_sizes_on_disk; - for (int32_t size : local_data.downloaded_icon_sizes()) - icon_sizes_on_disk.push_back(size); - web_app->SetDownloadedIconSizes(std::move(icon_sizes_on_disk)); + std::vector<SquareSizePx> icon_sizes_any; + for (int32_t size : local_data.downloaded_icon_sizes_purpose_any()) + icon_sizes_any.push_back(size); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, std::move(icon_sizes_any)); + + std::vector<SquareSizePx> icon_sizes_maskable; + for (int32_t size : local_data.downloaded_icon_sizes_purpose_maskable()) + icon_sizes_maskable.push_back(size); + web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, + std::move(icon_sizes_maskable)); web_app->SetIsGeneratedIcon(local_data.is_generated_icon());
diff --git a/chrome/browser/web_applications/web_app_database_unittest.cc b/chrome/browser/web_applications/web_app_database_unittest.cc index e607a9b..cc9795b 100644 --- a/chrome/browser/web_applications/web_app_database_unittest.cc +++ b/chrome/browser/web_applications/web_app_database_unittest.cc
@@ -237,7 +237,10 @@ icon_infos[i] = icon; } app->SetIconInfos(icon_infos); - app->SetDownloadedIconSizes({size}); + if (random.next_bool()) + app->SetDownloadedIconSizes(IconPurpose::ANY, {size}); + if (random.next_bool()) + app->SetDownloadedIconSizes(IconPurpose::MASKABLE, {size}); app->SetIsGeneratedIcon(random.next_bool()); app->SetFileHandlers(CreateFileHandlers(random.next_uint())); @@ -523,7 +526,8 @@ EXPECT_FALSE(app->theme_color().has_value()); EXPECT_FALSE(app->background_color().has_value()); EXPECT_TRUE(app->icon_infos().empty()); - EXPECT_TRUE(app->downloaded_icon_sizes().empty()); + EXPECT_TRUE(app->downloaded_icon_sizes(IconPurpose::ANY).empty()); + EXPECT_TRUE(app->downloaded_icon_sizes(IconPurpose::MASKABLE).empty()); EXPECT_FALSE(app->is_generated_icon()); EXPECT_FALSE(app->is_in_sync_install()); EXPECT_TRUE(app->sync_fallback_data().name.empty()); @@ -577,7 +581,8 @@ EXPECT_TRUE(app_copy->last_launch_time().is_null()); EXPECT_TRUE(app_copy->install_time().is_null()); EXPECT_TRUE(app_copy->icon_infos().empty()); - EXPECT_TRUE(app_copy->downloaded_icon_sizes().empty()); + EXPECT_TRUE(app_copy->downloaded_icon_sizes(IconPurpose::ANY).empty()); + EXPECT_TRUE(app_copy->downloaded_icon_sizes(IconPurpose::MASKABLE).empty()); EXPECT_FALSE(app_copy->is_generated_icon()); EXPECT_FALSE(app_copy->is_in_sync_install()); EXPECT_TRUE(app_copy->sync_fallback_data().name.empty()); @@ -611,7 +616,7 @@ icons.push_back(std::move(icon)); } app->SetIconInfos(std::move(icons)); - app->SetDownloadedIconSizes(std::move(sizes)); + app->SetDownloadedIconSizes(IconPurpose::ANY, std::move(sizes)); app->SetIsGeneratedIcon(false); controller().RegisterApp(std::move(app));
diff --git a/chrome/browser/web_applications/web_app_icon_manager.cc b/chrome/browser/web_applications/web_app_icon_manager.cc index 9d29cd2..86c98c7 100644 --- a/chrome/browser/web_applications/web_app_icon_manager.cc +++ b/chrome/browser/web_applications/web_app_icon_manager.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/callback.h" +#include "base/containers/adapters.h" #include "base/files/scoped_temp_dir.h" #include "base/logging.h" #include "base/memory/ref_counted_memory.h" @@ -33,6 +34,16 @@ namespace { +struct IconId { + IconId(AppId app_id, IconPurpose purpose, SquareSizePx size) + : app_id(std::move(app_id)), purpose(purpose), size(size) {} + ~IconId() = default; + + AppId app_id; + IconPurpose purpose; + SquareSizePx size; +}; + // Returns false if directory doesn't exist or it is not writable. bool CreateDirectoryIfNotExists(FileUtilsWrapper* utils, const base::FilePath& path) { @@ -60,10 +71,24 @@ // This is a private implementation detail of WebAppIconManager, where and how // to store icon files. base::FilePath GetAppIconsDirectory( - const base::FilePath& app_manifest_resources_directory) { - constexpr base::FilePath::CharType kIconsDirectoryName[] = + const base::FilePath& app_manifest_resources_directory, + IconPurpose purpose) { + constexpr base::FilePath::CharType kIconsAnyDirectoryName[] = FILE_PATH_LITERAL("Icons"); - return app_manifest_resources_directory.Append(kIconsDirectoryName); + constexpr base::FilePath::CharType kIconsMonochromeDirectoryName[] = + FILE_PATH_LITERAL("Icons Monochrome"); + constexpr base::FilePath::CharType kIconsMaskableDirectoryName[] = + FILE_PATH_LITERAL("Icons Maskable"); + switch (purpose) { + case IconPurpose::ANY: + return app_manifest_resources_directory.Append(kIconsAnyDirectoryName); + case IconPurpose::MONOCHROME: + return app_manifest_resources_directory.Append( + kIconsMonochromeDirectoryName); + case IconPurpose::MASKABLE: + return app_manifest_resources_directory.Append( + kIconsMaskableDirectoryName); + } } // This is a private implementation detail of WebAppIconManager, where and how @@ -103,9 +128,8 @@ } bool WriteIcons(FileUtilsWrapper* utils, - const base::FilePath& app_dir, + const base::FilePath& icons_dir, const std::map<SquareSizePx, SkBitmap>& icon_bitmaps) { - const base::FilePath icons_dir = GetAppIconsDirectory(app_dir); if (!utils->CreateDirectory(icons_dir)) { LOG(ERROR) << "Could not create icons directory."; return false; @@ -155,7 +179,7 @@ bool WriteDataBlocking(const std::unique_ptr<FileUtilsWrapper>& utils, const base::FilePath& web_apps_directory, const AppId& app_id, - const std::map<SquareSizePx, SkBitmap>& icons) { + const IconBitmaps& icon_bitmaps) { // Create the temp directory under the web apps root. // This guarantees it is on the same file system as the WebApp's eventual // install target. @@ -172,8 +196,19 @@ return false; } - if (!WriteIcons(utils.get(), app_temp_dir.GetPath(), icons)) + if (!WriteIcons( + utils.get(), + GetAppIconsDirectory(app_temp_dir.GetPath(), IconPurpose::ANY), + icon_bitmaps.any)) { return false; + } + // TODO (crbug.com/1114638): Write Monochrome icons here. + if (!WriteIcons( + utils.get(), + GetAppIconsDirectory(app_temp_dir.GetPath(), IconPurpose::MASKABLE), + icon_bitmaps.maskable)) { + return false; + } base::FilePath manifest_resources_directory = GetManifestResourcesDirectory(web_apps_directory); @@ -269,13 +304,12 @@ } base::FilePath GetIconFileName(const base::FilePath& web_apps_directory, - const AppId& app_id, - int icon_size_px) { + const IconId& icon_id) { base::FilePath app_dir = - GetManifestResourcesDirectoryForApp(web_apps_directory, app_id); - base::FilePath icons_dir = GetAppIconsDirectory(app_dir); + GetManifestResourcesDirectoryForApp(web_apps_directory, icon_id.app_id); + base::FilePath icons_dir = GetAppIconsDirectory(app_dir, icon_id.purpose); - return icons_dir.AppendASCII(base::StringPrintf("%i.png", icon_size_px)); + return icons_dir.AppendASCII(base::StringPrintf("%i.png", icon_id.size)); } base::FilePath GetManifestResourcesShortcutsMenuIconFileName( @@ -299,10 +333,8 @@ // Returns empty SkBitmap if any errors occurred. SkBitmap ReadIconBlocking(const std::unique_ptr<FileUtilsWrapper>& utils, const base::FilePath& web_apps_directory, - const AppId& app_id, - int icon_size_px) { - base::FilePath icon_file = - GetIconFileName(web_apps_directory, app_id, icon_size_px); + const IconId& icon_id) { + base::FilePath icon_file = GetIconFileName(web_apps_directory, icon_id); auto icon_data = base::MakeRefCounted<base::RefCountedString>(); @@ -354,19 +386,17 @@ std::map<SquareSizePx, SkBitmap> ReadIconAndResizeBlocking( const std::unique_ptr<FileUtilsWrapper>& utils, const base::FilePath& web_apps_directory, - const AppId& app_id, - SquareSizePx source_icon_size_px, + const IconId& icon_id, SquareSizePx target_icon_size_px) { std::map<SquareSizePx, SkBitmap> result; - SkBitmap source = - ReadIconBlocking(utils, web_apps_directory, app_id, source_icon_size_px); + SkBitmap source = ReadIconBlocking(utils, web_apps_directory, icon_id); if (source.empty()) return result; SkBitmap target; - if (source_icon_size_px != target_icon_size_px) { + if (icon_id.size != target_icon_size_px) { target = skia::ImageOperations::Resize( source, skia::ImageOperations::RESIZE_BEST, target_icon_size_px, target_icon_size_px); @@ -383,12 +413,13 @@ const std::unique_ptr<FileUtilsWrapper>& utils, const base::FilePath& web_apps_directory, const AppId& app_id, + IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes) { std::map<SquareSizePx, SkBitmap> result; for (SquareSizePx icon_size_px : icon_sizes) { - SkBitmap bitmap = - ReadIconBlocking(utils, web_apps_directory, app_id, icon_size_px); + IconId icon_id(app_id, purpose, icon_size_px); + SkBitmap bitmap = ReadIconBlocking(utils, web_apps_directory, icon_id); if (!bitmap.empty()) result[icon_size_px] = bitmap; } @@ -396,6 +427,24 @@ return result; } +IconBitmaps ReadAllIconsBlocking( + const std::unique_ptr<FileUtilsWrapper>& utils, + const base::FilePath& web_apps_directory, + const AppId& app_id, + const std::map<IconPurpose, std::vector<SquareSizePx>>& + icon_purposes_to_sizes) { + IconBitmaps result; + + for (const auto& purpose_sizes : icon_purposes_to_sizes) { + std::map<SquareSizePx, SkBitmap> read_icons = + ReadIconsBlocking(utils, web_apps_directory, app_id, + purpose_sizes.first, purpose_sizes.second); + result.SetBitmapsForPurpose(purpose_sizes.first, std::move(read_icons)); + } + + return result; +} + // Performs blocking I/O. May be called on another thread. ShortcutsMenuIconsBitmaps ReadShortcutsMenuIconsBlocking( FileUtilsWrapper* utils, @@ -426,10 +475,8 @@ std::vector<uint8_t> ReadCompressedIconBlocking( const std::unique_ptr<FileUtilsWrapper>& utils, const base::FilePath& web_apps_directory, - const AppId& app_id, - SquareSizePx icon_size_px) { - base::FilePath icon_file = - GetIconFileName(web_apps_directory, app_id, icon_size_px); + const IconId& icon_id) { + base::FilePath icon_file = GetIconFileName(web_apps_directory, icon_id); std::string icon_data; @@ -442,6 +489,13 @@ return std::vector<uint8_t>(icon_data.begin(), icon_data.end()); } +void WrapReadCompressedIconWithPurposeCallback( + AppIconManager::ReadCompressedIconWithPurposeCallback callback, + IconPurpose purpose, + std::vector<uint8_t> data) { + std::move(callback).Run(purpose, std::move(data)); +} + constexpr base::TaskTraits kTaskTraits = { base::MayBlock(), base::TaskPriority::USER_VISIBLE, base::TaskShutdownBehavior::BLOCK_SHUTDOWN}; @@ -457,16 +511,15 @@ WebAppIconManager::~WebAppIconManager() = default; -void WebAppIconManager::WriteData( - AppId app_id, - std::map<SquareSizePx, SkBitmap> icons, - WriteDataCallback callback) { +void WebAppIconManager::WriteData(AppId app_id, + IconBitmaps icon_bitmaps, + WriteDataCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, kTaskTraits, base::BindOnce(WriteDataBlocking, utils_->Clone(), web_apps_directory_, - std::move(app_id), std::move(icons)), + std::move(app_id), std::move(icon_bitmaps)), std::move(callback)); } @@ -505,46 +558,58 @@ bool WebAppIconManager::HasIcons( const AppId& app_id, + IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px) const { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); const WebApp* web_app = registrar_.GetAppById(app_id); if (!web_app) return false; - return base::STLIncludes(web_app->downloaded_icon_sizes(), icon_sizes_in_px); + return base::STLIncludes(web_app->downloaded_icon_sizes(purpose), + icon_sizes_in_px); } -bool WebAppIconManager::HasSmallestIcon(const AppId& app_id, - SquareSizePx icon_size_in_px) const { - return FindDownloadedSizeInPxMatchBigger(app_id, icon_size_in_px).has_value(); -} - -void WebAppIconManager::ReadIcons( +bool WebAppIconManager::HasSmallestIcon( const AppId& app_id, - const std::vector<SquareSizePx>& icon_sizes_in_px, - ReadIconsCallback callback) const { + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size_in_px) const { + return FindDownloadedIconMatchBigger(app_id, purposes, min_size_in_px) + .has_value(); +} + +void WebAppIconManager::ReadIcons(const AppId& app_id, + IconPurpose purpose, + const std::vector<SquareSizePx>& icon_sizes, + ReadIconsCallback callback) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(HasIcons(app_id, icon_sizes_in_px)); + DCHECK(HasIcons(app_id, purpose, icon_sizes)); base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, kTaskTraits, base::BindOnce(ReadIconsBlocking, utils_->Clone(), web_apps_directory_, - app_id, icon_sizes_in_px), + app_id, purpose, icon_sizes), std::move(callback)); } void WebAppIconManager::ReadAllIcons(const AppId& app_id, - ReadIconsCallback callback) const { + ReadIconBitmapsCallback callback) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); const WebApp* web_app = registrar_.GetAppById(app_id); if (!web_app) { - std::move(callback).Run(std::map<SquareSizePx, SkBitmap>()); + std::move(callback).Run(IconBitmaps()); return; } + std::map<IconPurpose, std::vector<SquareSizePx>> icon_purposes_to_sizes; + icon_purposes_to_sizes[IconPurpose::ANY] = + web_app->downloaded_icon_sizes(IconPurpose::ANY); + icon_purposes_to_sizes[IconPurpose::MASKABLE] = + web_app->downloaded_icon_sizes(IconPurpose::MASKABLE); + base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, kTaskTraits, - base::BindOnce(ReadIconsBlocking, utils_->Clone(), web_apps_directory_, - app_id, web_app->downloaded_icon_sizes()), + base::BindOnce(ReadAllIconsBlocking, utils_->Clone(), web_apps_directory_, + app_id, std::move(icon_purposes_to_sizes)), std::move(callback)); } @@ -566,37 +631,47 @@ std::move(callback)); } -void WebAppIconManager::ReadSmallestIcon(const AppId& app_id, - SquareSizePx icon_size_in_px, - ReadIconCallback callback) const { +void WebAppIconManager::ReadSmallestIcon( + const AppId& app_id, + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size_in_px, + ReadIconWithPurposeCallback callback) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - base::Optional<SquareSizePx> best_size_in_px = - FindDownloadedSizeInPxMatchBigger(app_id, icon_size_in_px); - DCHECK(best_size_in_px.has_value()); + base::Optional<WebAppIconManager::SizeAndPurpose> best_icon = + FindDownloadedIconMatchBigger(app_id, purposes, min_size_in_px); + DCHECK(best_icon.has_value()); + IconId icon_id(app_id, best_icon->purpose, best_icon->size_px); + ReadIconCallback wrapped = base::BindOnce( + WrapReadIconWithPurposeCallback, std::move(callback), best_icon->purpose); base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, kTaskTraits, base::BindOnce(ReadIconBlocking, utils_->Clone(), web_apps_directory_, - app_id, best_size_in_px.value()), - std::move(callback)); + std::move(icon_id)), + std::move(wrapped)); } void WebAppIconManager::ReadSmallestCompressedIcon( const AppId& app_id, - SquareSizePx icon_size_in_px, - ReadCompressedIconCallback callback) const { + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size_in_px, + ReadCompressedIconWithPurposeCallback callback) const { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - base::Optional<SquareSizePx> best_size_in_px = - FindDownloadedSizeInPxMatchBigger(app_id, icon_size_in_px); - DCHECK(best_size_in_px.has_value()); + base::Optional<WebAppIconManager::SizeAndPurpose> best_icon = + FindDownloadedIconMatchBigger(app_id, purposes, min_size_in_px); + DCHECK(best_icon.has_value()); + IconId icon_id(app_id, best_icon->purpose, best_icon->size_px); + ReadCompressedIconCallback wrapped = + base::BindOnce(WrapReadCompressedIconWithPurposeCallback, + std::move(callback), best_icon->purpose); base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, kTaskTraits, base::BindOnce(ReadCompressedIconBlocking, utils_->Clone(), - web_apps_directory_, app_id, best_size_in_px.value()), - std::move(callback)); + web_apps_directory_, std::move(icon_id)), + std::move(wrapped)); } SkBitmap WebAppIconManager::GetFavicon(const web_app::AppId& app_id) const { @@ -614,84 +689,91 @@ registrar_observer_.RemoveAll(); } -bool WebAppIconManager::HasIconToResize(const AppId& app_id, - SquareSizePx desired_icon_size) const { - return FindDownloadedSizeInPxMatchBigger(app_id, desired_icon_size) - .has_value() || - FindDownloadedSizeInPxMatchSmaller(app_id, desired_icon_size) - .has_value(); -} - void WebAppIconManager::ReadIconAndResize(const AppId& app_id, + IconPurpose purpose, SquareSizePx desired_icon_size, ReadIconsCallback callback) const { - DCHECK(HasIconToResize(app_id, desired_icon_size)); - - base::Optional<SquareSizePx> best_downloaded_size = - FindDownloadedSizeInPxMatchBigger(app_id, desired_icon_size); - if (!best_downloaded_size) { - best_downloaded_size = - FindDownloadedSizeInPxMatchSmaller(app_id, desired_icon_size); + base::Optional<SizeAndPurpose> best_icon = + FindDownloadedIconMatchBigger(app_id, {purpose}, desired_icon_size); + if (!best_icon) { + best_icon = + FindDownloadedIconMatchSmaller(app_id, {purpose}, desired_icon_size); } - DCHECK(best_downloaded_size.has_value()); + if (!best_icon) { + std::move(callback).Run(std::map<SquareSizePx, SkBitmap>()); + return; + } + IconId icon_id(app_id, best_icon->purpose, best_icon->size_px); base::ThreadPool::PostTaskAndReplyWithResult( FROM_HERE, kTaskTraits, base::BindOnce(ReadIconAndResizeBlocking, utils_->Clone(), - web_apps_directory_, app_id, best_downloaded_size.value(), + web_apps_directory_, std::move(icon_id), desired_icon_size), std::move(callback)); } void WebAppIconManager::SetFaviconReadCallbackForTesting( FaviconReadCallback callback) { - favicon_read_callback_ = callback; + favicon_read_callback_ = std::move(callback); } -base::Optional<SquareSizePx> -WebAppIconManager::FindDownloadedSizeInPxMatchBigger( +base::Optional<WebAppIconManager::SizeAndPurpose> +WebAppIconManager::FindDownloadedIconMatchBigger( const AppId& app_id, + const std::vector<IconPurpose>& purposes, SquareSizePx desired_size) const { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); const WebApp* web_app = registrar_.GetAppById(app_id); if (!web_app) return base::nullopt; - DCHECK(base::STLIsSorted(web_app->downloaded_icon_sizes())); - for (auto it = web_app->downloaded_icon_sizes().begin(); - it != web_app->downloaded_icon_sizes().end(); ++it) { - if (*it >= desired_size) - return base::make_optional(*it); + // Must iterate through purposes in order given. + for (IconPurpose purpose : purposes) { + const std::vector<SquareSizePx>& sizes = + web_app->downloaded_icon_sizes(purpose); + DCHECK(base::STLIsSorted(sizes)); + for (SquareSizePx size : sizes) { + if (size >= desired_size) + return WebAppIconManager::SizeAndPurpose{size, purpose}; + } } return base::nullopt; } -base::Optional<SquareSizePx> -WebAppIconManager::FindDownloadedSizeInPxMatchSmaller( +base::Optional<WebAppIconManager::SizeAndPurpose> +WebAppIconManager::FindDownloadedIconMatchSmaller( const AppId& app_id, + const std::vector<IconPurpose>& purposes, SquareSizePx desired_size) const { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); const WebApp* web_app = registrar_.GetAppById(app_id); if (!web_app) return base::nullopt; - DCHECK(base::STLIsSorted(web_app->downloaded_icon_sizes())); - for (auto it = web_app->downloaded_icon_sizes().rbegin(); - it != web_app->downloaded_icon_sizes().rend(); ++it) { - if (*it <= desired_size) - return base::make_optional(*it); + // Must check purposes in the order given. + for (IconPurpose purpose : purposes) { + const std::vector<SquareSizePx>& sizes = + web_app->downloaded_icon_sizes(purpose); + DCHECK(base::STLIsSorted(sizes)); + for (SquareSizePx size : base::Reversed(sizes)) { + if (size <= desired_size) + return WebAppIconManager::SizeAndPurpose{size, purpose}; + } } return base::nullopt; } void WebAppIconManager::ReadFavicon(const AppId& app_id) { - if (!HasSmallestIcon(app_id, gfx::kFaviconSize)) + if (!HasSmallestIcon(app_id, {IconPurpose::ANY}, gfx::kFaviconSize)) return; - ReadSmallestIcon(app_id, gfx::kFaviconSize, - base::BindOnce(&WebAppIconManager::OnReadFavicon, - weak_ptr_factory_.GetWeakPtr(), app_id)); + ReadSmallestIconAny(app_id, gfx::kFaviconSize, + base::BindOnce(&WebAppIconManager::OnReadFavicon, + weak_ptr_factory_.GetWeakPtr(), app_id)); } void WebAppIconManager::OnReadFavicon(const AppId& app_id,
diff --git a/chrome/browser/web_applications/web_app_icon_manager.h b/chrome/browser/web_applications/web_app_icon_manager.h index 6f320976..d41824c 100644 --- a/chrome/browser/web_applications/web_app_icon_manager.h +++ b/chrome/browser/web_applications/web_app_icon_manager.h
@@ -38,11 +38,11 @@ std::unique_ptr<FileUtilsWrapper> utils); ~WebAppIconManager() override; - // Writes all data (icons) for an app. using WriteDataCallback = base::OnceCallback<void(bool success)>; + // Writes all data (icons) for an app. void WriteData(AppId app_id, - std::map<SquareSizePx, SkBitmap> icons, + IconBitmaps icon_bitmaps, WriteDataCallback callback); void WriteShortcutsMenuIconsData( AppId app_id, @@ -55,47 +55,58 @@ void Shutdown() override; bool HasIcons( const AppId& app_id, + IconPurpose purpose, const std::vector<SquareSizePx>& icon_sizes_in_px) const override; bool HasSmallestIcon(const AppId& app_id, - SquareSizePx icon_size_in_px) const override; + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size_in_px) const override; void ReadIcons(const AppId& app_id, - const std::vector<SquareSizePx>& icon_sizes_in_px, + IconPurpose purpose, + const std::vector<SquareSizePx>& icon_sizes, ReadIconsCallback callback) const override; void ReadAllIcons(const AppId& app_id, - ReadIconsCallback callback) const override; + ReadIconBitmapsCallback callback) const override; void ReadAllShortcutsMenuIcons( const AppId& app_id, ReadShortcutsMenuIconsCallback callback) const override; void ReadSmallestIcon(const AppId& app_id, - SquareSizePx icon_size_in_px, - ReadIconCallback callback) const override; + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size_in_px, + ReadIconWithPurposeCallback callback) const override; void ReadSmallestCompressedIcon( const AppId& app_id, - SquareSizePx icon_size_in_px, - ReadCompressedIconCallback callback) const override; + const std::vector<IconPurpose>& purposes, + SquareSizePx min_size_in_px, + ReadCompressedIconWithPurposeCallback callback) const override; SkBitmap GetFavicon(const web_app::AppId& app_id) const override; // AppRegistrarObserver: void OnWebAppInstalled(const AppId& app_id) override; void OnAppRegistrarDestroyed() override; - // If there is no icon at the downloaded sizes, we may resize what we can get. - bool HasIconToResize(const AppId& app_id, - SquareSizePx desired_icon_size) const; - // Looks for a larger icon first, a smaller icon second. (Resizing a large - // icon smaller is preferred to resizing a small icon larger) + // Calls back with an icon of the |desired_icon_size| and |purpose|, resizing + // an icon of a different size if necessary. If no icons were available, calls + // back with an empty map. Prefers resizing a large icon smaller over resizing + // a small icon larger. void ReadIconAndResize(const AppId& app_id, + IconPurpose purpose, SquareSizePx desired_icon_size, ReadIconsCallback callback) const; void SetFaviconReadCallbackForTesting(FaviconReadCallback callback); private: - base::Optional<SquareSizePx> FindDownloadedSizeInPxMatchBigger( + struct SizeAndPurpose { + SquareSizePx size_px = 0; + IconPurpose purpose = IconPurpose::ANY; + }; + base::Optional<WebAppIconManager::SizeAndPurpose> + FindDownloadedIconMatchBigger(const AppId& app_id, + const std::vector<IconPurpose>& purposes, + SquareSizePx desired_size) const; + base::Optional<SizeAndPurpose> FindDownloadedIconMatchSmaller( const AppId& app_id, - SquareSizePx desired_size) const; - base::Optional<SquareSizePx> FindDownloadedSizeInPxMatchSmaller( - const AppId& app_id, + const std::vector<IconPurpose>& purposes, SquareSizePx desired_size) const; void ReadFavicon(const AppId& app_id);
diff --git a/chrome/browser/web_applications/web_app_icon_manager_unittest.cc b/chrome/browser/web_applications/web_app_icon_manager_unittest.cc index b5fef773..b483598 100644 --- a/chrome/browser/web_applications/web_app_icon_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_icon_manager_unittest.cc
@@ -55,19 +55,28 @@ protected: void WriteIcons(const AppId& app_id, + const std::vector<IconPurpose>& purposes, const std::vector<int>& sizes_px, const std::vector<SkColor>& colors) { DCHECK_EQ(sizes_px.size(), colors.size()); + DCHECK(!purposes.empty()); - auto web_app_info = std::make_unique<WebApplicationInfo>(); - + IconBitmaps icon_bitmaps; for (size_t i = 0; i < sizes_px.size(); ++i) { std::string icon_name = base::StringPrintf("app-%d.ico", sizes_px[i]); - AddGeneratedIcon(&web_app_info->icon_bitmaps_any, sizes_px[i], colors[i]); + if (base::Contains(purposes, IconPurpose::ANY)) { + AddGeneratedIcon(&icon_bitmaps.any, sizes_px[i], colors[i]); + } + if (base::Contains(purposes, IconPurpose::MASKABLE)) { + AddGeneratedIcon(&icon_bitmaps.maskable, sizes_px[i], colors[i]); + } + if (base::Contains(purposes, IconPurpose::MONOCHROME)) + // TODO (crbug.com/1114638): Monochrome icon support. + NOTREACHED(); } base::RunLoop run_loop; - icon_manager_->WriteData(app_id, std::move(web_app_info->icon_bitmaps_any), + icon_manager_->WriteData(app_id, std::move(icon_bitmaps), base::BindLambdaForTesting([&](bool success) { EXPECT_TRUE(success); run_loop.Quit(); @@ -122,30 +131,41 @@ return downloaded_shortcuts_menu_icons_sizes; } - std::vector<uint8_t> ReadSmallestCompressedIcon(const AppId& app_id, - int icon_size_in_px) { - EXPECT_TRUE(icon_manager().HasSmallestIcon(app_id, icon_size_in_px)); + struct PurposeAndData { + IconPurpose purpose; + std::vector<uint8_t> data; + }; + PurposeAndData ReadSmallestCompressedIcon( + const AppId& app_id, + const std::vector<IconPurpose>& purposes, + int min_size_in_px) { + EXPECT_TRUE( + icon_manager().HasSmallestIcon(app_id, purposes, min_size_in_px)); - std::vector<uint8_t> result; + PurposeAndData result; base::RunLoop run_loop; icon_manager().ReadSmallestCompressedIcon( - app_id, icon_size_in_px, - base::BindLambdaForTesting([&](std::vector<uint8_t> data) { - result = std::move(data); - run_loop.Quit(); - })); + app_id, purposes, min_size_in_px, + base::BindLambdaForTesting( + [&](IconPurpose purpose, std::vector<uint8_t> data) { + result.purpose = purpose; + result.data = std::move(data); + run_loop.Quit(); + })); run_loop.Run(); return result; } - SkColor ReadIconAndResize(const AppId& app_id, int desired_icon_size) { + SkColor ReadIconAndResize(const AppId& app_id, + IconPurpose purpose, + int desired_icon_size) { base::RunLoop run_loop; SkColor icon_color = SK_ColorBLACK; icon_manager().ReadIconAndResize( - app_id, desired_icon_size, + app_id, purpose, desired_icon_size, base::BindLambdaForTesting( [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { EXPECT_EQ(1u, icon_bitmaps.size()); @@ -162,6 +182,10 @@ return icon_color; } + SkColor ReadIconAndResize(const AppId& app_id, int desired_icon_size) { + return ReadIconAndResize(app_id, IconPurpose::ANY, desired_icon_size); + } + std::unique_ptr<WebApp> CreateWebApp() { const GURL app_url = GURL("https://example.com/path"); const AppId app_id = GenerateAppIdFromURL(app_url); @@ -196,24 +220,126 @@ TestFileUtils* file_utils_ = nullptr; }; -TEST_F(WebAppIconManagerTest, WriteAndReadIcons) { +TEST_F(WebAppIconManagerTest, WriteAndReadIcons_AnyOnly) { auto web_app = CreateWebApp(); const AppId app_id = web_app->app_id(); const std::vector<int> sizes_px{icon_size::k256, icon_size::k512}; const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorYELLOW}; - WriteIcons(app_id, sizes_px, colors); + WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors); - web_app->SetDownloadedIconSizes(sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); controller().RegisterApp(std::move(web_app)); - EXPECT_TRUE(icon_manager().HasIcons(app_id, sizes_px)); + EXPECT_TRUE(icon_manager().HasIcons(app_id, IconPurpose::ANY, sizes_px)); { base::RunLoop run_loop; icon_manager().ReadIcons( - app_id, sizes_px, + app_id, IconPurpose::ANY, sizes_px, + base::BindLambdaForTesting( + [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { + EXPECT_EQ(2u, icon_bitmaps.size()); + + EXPECT_FALSE(icon_bitmaps[icon_size::k256].empty()); + EXPECT_EQ(SK_ColorGREEN, + icon_bitmaps[icon_size::k256].getColor(0, 0)); + + EXPECT_FALSE(icon_bitmaps[icon_size::k512].empty()); + EXPECT_EQ(SK_ColorYELLOW, + icon_bitmaps[icon_size::k512].getColor(0, 0)); + + run_loop.Quit(); + })); + + run_loop.Run(); + } + EXPECT_FALSE( + icon_manager().HasIcons(app_id, IconPurpose::MASKABLE, sizes_px)); +} + +TEST_F(WebAppIconManagerTest, WriteAndReadIcons_MaskableOnly) { + auto web_app = CreateWebApp(); + const AppId app_id = web_app->app_id(); + + const std::vector<int> sizes_px{icon_size::k256, icon_size::k512}; + const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorYELLOW}; + WriteIcons(app_id, {IconPurpose::MASKABLE}, sizes_px, colors); + + web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, sizes_px); + + controller().RegisterApp(std::move(web_app)); + + EXPECT_FALSE(icon_manager().HasIcons(app_id, IconPurpose::ANY, sizes_px)); + EXPECT_TRUE(icon_manager().HasIcons(app_id, IconPurpose::MASKABLE, sizes_px)); + { + base::RunLoop run_loop; + + icon_manager().ReadIcons( + app_id, IconPurpose::MASKABLE, sizes_px, + base::BindLambdaForTesting( + [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { + EXPECT_EQ(2u, icon_bitmaps.size()); + + EXPECT_FALSE(icon_bitmaps[icon_size::k256].empty()); + EXPECT_EQ(SK_ColorGREEN, + icon_bitmaps[icon_size::k256].getColor(0, 0)); + + EXPECT_FALSE(icon_bitmaps[icon_size::k512].empty()); + EXPECT_EQ(SK_ColorYELLOW, + icon_bitmaps[icon_size::k512].getColor(0, 0)); + + run_loop.Quit(); + })); + + run_loop.Run(); + } +} + +TEST_F(WebAppIconManagerTest, WriteAndReadIcons_AnyAndMaskable) { + auto web_app = CreateWebApp(); + const AppId app_id = web_app->app_id(); + + const std::vector<int> sizes_px{icon_size::k256, icon_size::k512}; + const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorYELLOW}; + WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px, + colors); + + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, sizes_px); + + controller().RegisterApp(std::move(web_app)); + + EXPECT_TRUE(icon_manager().HasIcons(app_id, IconPurpose::ANY, sizes_px)); + { + base::RunLoop run_loop; + + icon_manager().ReadIcons( + app_id, IconPurpose::ANY, sizes_px, + base::BindLambdaForTesting( + [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { + EXPECT_EQ(2u, icon_bitmaps.size()); + + EXPECT_FALSE(icon_bitmaps[icon_size::k256].empty()); + EXPECT_EQ(SK_ColorGREEN, + icon_bitmaps[icon_size::k256].getColor(0, 0)); + + EXPECT_FALSE(icon_bitmaps[icon_size::k512].empty()); + EXPECT_EQ(SK_ColorYELLOW, + icon_bitmaps[icon_size::k512].getColor(0, 0)); + + run_loop.Quit(); + })); + + run_loop.Run(); + } + EXPECT_TRUE(icon_manager().HasIcons(app_id, IconPurpose::MASKABLE, sizes_px)); + { + base::RunLoop run_loop; + + icon_manager().ReadIcons( + app_id, IconPurpose::MASKABLE, sizes_px, base::BindLambdaForTesting( [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { EXPECT_EQ(2u, icon_bitmaps.size()); @@ -241,9 +367,11 @@ { std::vector<int> sizes_px{icon_size::k32, icon_size::k64, icon_size::k48}; const std::vector<SkColor> colors{SK_ColorRED, SK_ColorRED, SK_ColorRED}; - WriteIcons(app_id, sizes_px, colors); + WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px, + colors); - web_app->SetDownloadedIconSizes(std::move(sizes_px)); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, std::move(sizes_px)); } controller().RegisterApp(std::move(web_app)); @@ -252,13 +380,15 @@ const std::vector<int> overwritten_sizes_px{icon_size::k48, icon_size::k64, icon_size::k96}; { - std::map<SquareSizePx, SkBitmap> icon_bitmaps; - for (int size_px : overwritten_sizes_px) - icon_bitmaps[size_px] = CreateSquareIcon(size_px, SK_ColorGREEN); + IconBitmaps icon_bitmaps; + for (int size_px : overwritten_sizes_px) { + icon_bitmaps.any[size_px] = CreateSquareIcon(size_px, SK_ColorGREEN); + icon_bitmaps.maskable[size_px] = CreateSquareIcon(size_px, SK_ColorBLUE); + } base::RunLoop run_loop; - // Overwrite red icons with green ones. + // Overwrite red icons with green and blue ones. icon_manager().WriteData(app_id, std::move(icon_bitmaps), base::BindLambdaForTesting([&](bool success) { EXPECT_TRUE(success); @@ -268,56 +398,118 @@ run_loop.Run(); ScopedRegistryUpdate update(&controller().sync_bridge()); - update->UpdateApp(app_id)->SetDownloadedIconSizes(overwritten_sizes_px); + update->UpdateApp(app_id)->SetDownloadedIconSizes(IconPurpose::ANY, + overwritten_sizes_px); + update->UpdateApp(app_id)->SetDownloadedIconSizes(IconPurpose::MASKABLE, + overwritten_sizes_px); } - // Check that all icons are now green. Check that all red icons were deleted - // on disk (including the k32 size). - base::FilePath icons_dir = GetAppIconsDir(profile(), app_id); + // Check that all IconPurpose::ANY icons are now green. Check that all red + // icons were deleted on disk (including the k32 size). + { + base::FilePath icons_dir = GetAppIconsAnyDir(profile(), app_id); + std::vector<int> sizes_on_disk_px; - std::vector<int> sizes_on_disk_px; + base::FileEnumerator enumerator_any(icons_dir, true, + base::FileEnumerator::FILES); + for (base::FilePath path = enumerator_any.Next(); !path.empty(); + path = enumerator_any.Next()) { + EXPECT_TRUE(path.MatchesExtension(FILE_PATH_LITERAL(".png"))); - base::FileEnumerator enumerator(icons_dir, true, base::FileEnumerator::FILES); - for (base::FilePath path = enumerator.Next(); !path.empty(); - path = enumerator.Next()) { - EXPECT_TRUE(path.MatchesExtension(FILE_PATH_LITERAL(".png"))); + SkBitmap bitmap; + EXPECT_TRUE(ReadBitmap(&file_utils(), path, &bitmap)); + EXPECT_FALSE(bitmap.empty()); + EXPECT_EQ(bitmap.width(), bitmap.height()); + EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 0)); - SkBitmap bitmap; - EXPECT_TRUE(ReadBitmap(&file_utils(), path, &bitmap)); - EXPECT_FALSE(bitmap.empty()); - EXPECT_EQ(bitmap.width(), bitmap.height()); - EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 0)); + sizes_on_disk_px.push_back(bitmap.width()); + } - sizes_on_disk_px.push_back(bitmap.width()); + std::sort(sizes_on_disk_px.begin(), sizes_on_disk_px.end()); + EXPECT_EQ(overwritten_sizes_px, sizes_on_disk_px); } - std::sort(sizes_on_disk_px.begin(), sizes_on_disk_px.end()); - EXPECT_EQ(overwritten_sizes_px, sizes_on_disk_px); + // Check that all IconPurpose::Maskable icons are now blue. Check that all red + // icons were deleted on disk (including the k32 size). + { + base::FilePath icons_dir = GetAppIconsMaskableDir(profile(), app_id); + std::vector<int> sizes_on_disk_px; + + base::FileEnumerator enumerator_maskable(icons_dir, true, + base::FileEnumerator::FILES); + for (base::FilePath path = enumerator_maskable.Next(); !path.empty(); + path = enumerator_maskable.Next()) { + EXPECT_TRUE(path.MatchesExtension(FILE_PATH_LITERAL(".png"))); + + SkBitmap bitmap; + EXPECT_TRUE(ReadBitmap(&file_utils(), path, &bitmap)); + EXPECT_FALSE(bitmap.empty()); + EXPECT_EQ(bitmap.width(), bitmap.height()); + EXPECT_EQ(SK_ColorBLUE, bitmap.getColor(0, 0)); + + sizes_on_disk_px.push_back(bitmap.width()); + } + + std::sort(sizes_on_disk_px.begin(), sizes_on_disk_px.end()); + EXPECT_EQ(overwritten_sizes_px, sizes_on_disk_px); + } } -TEST_F(WebAppIconManagerTest, ReadAllIcons) { +TEST_F(WebAppIconManagerTest, ReadAllIcons_AnyOnly) { auto web_app = CreateWebApp(); const AppId app_id = web_app->app_id(); const std::vector<int> sizes_px{icon_size::k256, icon_size::k512}; const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorYELLOW}; - WriteIcons(app_id, sizes_px, colors); + WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors); - web_app->SetDownloadedIconSizes(sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); controller().RegisterApp(std::move(web_app)); { base::RunLoop run_loop; icon_manager().ReadAllIcons( - app_id, - base::BindLambdaForTesting( - [&](std::map<SquareSizePx, SkBitmap> icons_map) { - EXPECT_EQ(2u, icons_map.size()); - EXPECT_EQ(colors[0], icons_map[sizes_px[0]].getColor(0, 0)); - EXPECT_EQ(colors[1], icons_map[sizes_px[1]].getColor(0, 0)); - run_loop.Quit(); - })); + app_id, base::BindLambdaForTesting([&](IconBitmaps icons_map) { + EXPECT_FALSE(icons_map.empty()); + EXPECT_EQ(2u, icons_map.any.size()); + EXPECT_EQ(colors[0], icons_map.any[sizes_px[0]].getColor(0, 0)); + EXPECT_EQ(colors[1], icons_map.any[sizes_px[1]].getColor(0, 0)); + EXPECT_EQ(0u, icons_map.maskable.size()); + run_loop.Quit(); + })); + + run_loop.Run(); + } +} + +TEST_F(WebAppIconManagerTest, ReadAllIcons_AnyAndMaskable) { + auto web_app = CreateWebApp(); + const AppId app_id = web_app->app_id(); + + const std::vector<int> sizes_px{icon_size::k256, icon_size::k512}; + const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorYELLOW}; + WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px, + colors); + + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, sizes_px); + + controller().RegisterApp(std::move(web_app)); + { + base::RunLoop run_loop; + + icon_manager().ReadAllIcons( + app_id, base::BindLambdaForTesting([&](IconBitmaps icons_map) { + EXPECT_FALSE(icons_map.empty()); + EXPECT_EQ(2u, icons_map.any.size()); + EXPECT_EQ(colors[0], icons_map.any[sizes_px[0]].getColor(0, 0)); + EXPECT_EQ(colors[1], icons_map.any[sizes_px[1]].getColor(0, 0)); + EXPECT_EQ(2u, icons_map.maskable.size()); + EXPECT_EQ(colors[0], icons_map.maskable[sizes_px[0]].getColor(0, 0)); + EXPECT_EQ(colors[1], icons_map.maskable[sizes_px[1]].getColor(0, 0)); + run_loop.Quit(); + })); run_loop.Run(); } @@ -406,20 +598,22 @@ const std::vector<SquareSizePx> icon_sizes_px{icon_size::k256}; // Set icon meta-info but don't write bitmap to disk. - web_app->SetDownloadedIconSizes(icon_sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, icon_sizes_px); controller().RegisterApp(std::move(web_app)); - EXPECT_FALSE(icon_manager().HasIcons(app_id, {icon_size::k96})); - EXPECT_TRUE(icon_manager().HasIcons(app_id, {icon_size::k256})); EXPECT_FALSE( - icon_manager().HasIcons(app_id, {icon_size::k96, icon_size::k256})); + icon_manager().HasIcons(app_id, IconPurpose::ANY, {icon_size::k96})); + EXPECT_TRUE( + icon_manager().HasIcons(app_id, IconPurpose::ANY, {icon_size::k256})); + EXPECT_FALSE(icon_manager().HasIcons(app_id, IconPurpose::ANY, + {icon_size::k96, icon_size::k256})); // Request existing icon size which doesn't exist on disk. base::RunLoop run_loop; icon_manager().ReadIcons( - app_id, icon_sizes_px, + app_id, IconPurpose::ANY, icon_sizes_px, base::BindLambdaForTesting( [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { EXPECT_TRUE(icon_bitmaps.empty()); @@ -436,21 +630,22 @@ const std::vector<int> sizes_px{10, 60, 50, 20, 30}; const std::vector<SkColor> colors{SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN, SK_ColorBLUE, SK_ColorMAGENTA}; - WriteIcons(app_id, sizes_px, colors); + WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors); - web_app->SetDownloadedIconSizes(sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); controller().RegisterApp(std::move(web_app)); - EXPECT_FALSE(icon_manager().HasIcons(app_id, {40})); + EXPECT_FALSE(icon_manager().HasIcons(app_id, IconPurpose::ANY, {40})); + EXPECT_FALSE(icon_manager().HasIcons(app_id, IconPurpose::MASKABLE, {20})); { base::RunLoop run_loop; - EXPECT_TRUE(icon_manager().HasIcons(app_id, {20})); + EXPECT_TRUE(icon_manager().HasIcons(app_id, IconPurpose::ANY, {20})); icon_manager().ReadIcons( - app_id, {20}, + app_id, IconPurpose::ANY, {20}, base::BindLambdaForTesting( [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { EXPECT_EQ(1u, icon_bitmaps.size()); @@ -470,19 +665,28 @@ const std::vector<int> sizes_px{10, 60, 50, 20, 30}; const std::vector<SkColor> colors{SK_ColorRED, SK_ColorYELLOW, SK_ColorGREEN, SK_ColorBLUE, SK_ColorMAGENTA}; - WriteIcons(app_id, sizes_px, colors); + WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors); - web_app->SetDownloadedIconSizes(sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); controller().RegisterApp(std::move(web_app)); - EXPECT_FALSE(icon_manager().HasSmallestIcon(app_id, 70)); + EXPECT_FALSE(icon_manager().HasSmallestIcon(app_id, {IconPurpose::ANY}, 70)); + EXPECT_FALSE(icon_manager().HasSmallestIcon( + app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, 70)); + EXPECT_FALSE( + icon_manager().HasSmallestIcon(app_id, {IconPurpose::MASKABLE}, 40)); + + EXPECT_TRUE(icon_manager().HasSmallestIcon( + app_id, {IconPurpose::MASKABLE, IconPurpose::ANY}, 40)); + EXPECT_TRUE(icon_manager().HasSmallestIcon( + app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, 20)); { base::RunLoop run_loop; - EXPECT_TRUE(icon_manager().HasSmallestIcon(app_id, 40)); - icon_manager().ReadSmallestIcon( + EXPECT_TRUE(icon_manager().HasSmallestIcon(app_id, {IconPurpose::ANY}, 40)); + icon_manager().ReadSmallestIconAny( app_id, 40, base::BindLambdaForTesting([&](const SkBitmap& bitmap) { EXPECT_FALSE(bitmap.empty()); EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 0)); @@ -495,8 +699,8 @@ { base::RunLoop run_loop; - EXPECT_TRUE(icon_manager().HasSmallestIcon(app_id, 20)); - icon_manager().ReadSmallestIcon( + EXPECT_TRUE(icon_manager().HasSmallestIcon(app_id, {IconPurpose::ANY}, 20)); + icon_manager().ReadSmallestIconAny( app_id, 20, base::BindLambdaForTesting([&](const SkBitmap& bitmap) { EXPECT_FALSE(bitmap.empty()); EXPECT_EQ(SK_ColorBLUE, bitmap.getColor(0, 0)); @@ -513,8 +717,10 @@ const std::vector<int> sizes_px{icon_size::k128}; const std::vector<SkColor> colors{SK_ColorMAGENTA}; - WriteIcons(app1_id, sizes_px, colors); - WriteIcons(app2_id, sizes_px, colors); + WriteIcons(app1_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px, + colors); + WriteIcons(app2_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px, + colors); const base::FilePath web_apps_root_directory = GetWebAppsRootDirectory(profile()); @@ -561,27 +767,103 @@ run_loop.Run(); } -TEST_F(WebAppIconManagerTest, ReadSmallestCompressedIcon_Success) { +TEST_F(WebAppIconManagerTest, ReadSmallestCompressedIcon_Success_AnyOnly) { auto web_app = CreateWebApp(); const AppId app_id = web_app->app_id(); const std::vector<int> sizes_px{icon_size::k128}; const std::vector<SkColor> colors{SK_ColorGREEN}; - WriteIcons(app_id, sizes_px, colors); + WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors); - web_app->SetDownloadedIconSizes(sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); controller().RegisterApp(std::move(web_app)); - std::vector<uint8_t> compressed_data = - ReadSmallestCompressedIcon(app_id, sizes_px[0]); - EXPECT_FALSE(compressed_data.empty()); + { + PurposeAndData result = + ReadSmallestCompressedIcon(app_id, {IconPurpose::ANY}, sizes_px[0]); + EXPECT_EQ(IconPurpose::ANY, result.purpose); + EXPECT_FALSE(result.data.empty()); + } + { + PurposeAndData result = ReadSmallestCompressedIcon( + app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px[0]); + EXPECT_EQ(IconPurpose::ANY, result.purpose); + EXPECT_FALSE(result.data.empty()); + } + { + PurposeAndData result = ReadSmallestCompressedIcon( + app_id, {IconPurpose::MASKABLE, IconPurpose::ANY}, sizes_px[0]); + EXPECT_EQ(IconPurpose::ANY, result.purpose); + EXPECT_FALSE(result.data.empty()); + } +} - auto* data_ptr = reinterpret_cast<const char*>(compressed_data.data()); +TEST_F(WebAppIconManagerTest, ReadSmallestCompressedIcon_Success) { + auto web_app = CreateWebApp(); + const AppId app_id = web_app->app_id(); - // Check that |compressed_data| starts with the 8-byte PNG magic string. - std::string png_magic_string{data_ptr, 8}; - EXPECT_EQ(png_magic_string, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"); + const std::vector<int> sizes_px{icon_size::k64, icon_size::k128}; + const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorGREEN}; + WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px, + colors); + + int size_smaller = icon_size::k64; + int size_larger = icon_size::k128; + // Lie about available icon sizes so any/maskable have different sizes. + web_app->SetDownloadedIconSizes(IconPurpose::ANY, {size_smaller}); + web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, {size_larger}); + + controller().RegisterApp(std::move(web_app)); + + { + PurposeAndData result = + ReadSmallestCompressedIcon(app_id, {IconPurpose::ANY}, size_smaller); + EXPECT_EQ(IconPurpose::ANY, result.purpose); + EXPECT_FALSE(result.data.empty()); + + auto* data_ptr = reinterpret_cast<const char*>(result.data.data()); + + // Check that |compressed_data| starts with the 8-byte PNG magic string. + std::string png_magic_string{data_ptr, 8}; + EXPECT_EQ(png_magic_string, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"); + } + + { + // Maskable returned when purpose specified. + PurposeAndData result = ReadSmallestCompressedIcon( + app_id, {IconPurpose::MASKABLE}, size_larger); + EXPECT_EQ(IconPurpose::MASKABLE, result.purpose); + EXPECT_FALSE(result.data.empty()); + } + { + // Maskable returned even though size doesn't exactly match. + PurposeAndData result = ReadSmallestCompressedIcon( + app_id, {IconPurpose::MASKABLE}, size_smaller); + EXPECT_EQ(IconPurpose::MASKABLE, result.purpose); + EXPECT_FALSE(result.data.empty()); + } + { + // Any returned because it is first in purposes. + PurposeAndData result = ReadSmallestCompressedIcon( + app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, size_smaller); + EXPECT_EQ(IconPurpose::ANY, result.purpose); + EXPECT_FALSE(result.data.empty()); + } + { + // Maskable returned because it is the only one of sufficient size. + PurposeAndData result = ReadSmallestCompressedIcon( + app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, size_larger); + EXPECT_EQ(IconPurpose::MASKABLE, result.purpose); + EXPECT_FALSE(result.data.empty()); + } + { + // Maskable returned because it is first in purposes. + PurposeAndData result = ReadSmallestCompressedIcon( + app_id, {IconPurpose::MASKABLE, IconPurpose::ANY}, size_smaller); + EXPECT_EQ(IconPurpose::MASKABLE, result.purpose); + EXPECT_FALSE(result.data.empty()); + } } TEST_F(WebAppIconManagerTest, ReadSmallestCompressedIcon_Failure) { @@ -589,16 +871,34 @@ const AppId app_id = web_app->app_id(); const std::vector<int> sizes_px{icon_size::k64}; - web_app->SetDownloadedIconSizes(sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, sizes_px); controller().RegisterApp(std::move(web_app)); - std::vector<uint8_t> compressed_data = - ReadSmallestCompressedIcon(app_id, sizes_px[0]); - EXPECT_TRUE(compressed_data.empty()); + { + PurposeAndData result = + ReadSmallestCompressedIcon(app_id, {IconPurpose::ANY}, sizes_px[0]); + EXPECT_TRUE(result.data.empty()); + } + { + PurposeAndData result = ReadSmallestCompressedIcon( + app_id, {IconPurpose::MASKABLE}, sizes_px[0]); + EXPECT_TRUE(result.data.empty()); + } + { + PurposeAndData result = ReadSmallestCompressedIcon( + app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px[0]); + EXPECT_TRUE(result.data.empty()); + } + { + PurposeAndData result = ReadSmallestCompressedIcon( + app_id, {IconPurpose::MASKABLE, IconPurpose::ANY}, sizes_px[0]); + EXPECT_TRUE(result.data.empty()); + } } -TEST_F(WebAppIconManagerTest, ReadIconAndResize_Success) { +TEST_F(WebAppIconManagerTest, ReadIconAndResize_Success_AnyOnly) { auto web_app = CreateWebApp(); const AppId app_id = web_app->app_id(); @@ -606,39 +906,26 @@ icon_size::k256, icon_size::k512}; const std::vector<SkColor> colors{SK_ColorBLUE, SK_ColorGREEN, SK_ColorYELLOW, SK_ColorRED}; - WriteIcons(app_id, sizes_px, colors); + WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors); - web_app->SetDownloadedIconSizes(sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); controller().RegisterApp(std::move(web_app)); - for (SquareSizePx size : sizes_px) - EXPECT_TRUE(icon_manager().HasIconToResize(app_id, size)); - - EXPECT_TRUE(icon_manager().HasIconToResize(app_id, icon_size::k128)); - EXPECT_TRUE(icon_manager().HasIconToResize(app_id, icon_size::k16)); - EXPECT_TRUE(icon_manager().HasIconToResize(app_id, 1024)); - for (size_t i = 0; i < sizes_px.size(); ++i) EXPECT_EQ(colors[i], ReadIconAndResize(app_id, sizes_px[i])); + // ReadIconAndResize should work for non-present icon sizes as long as an icon + // (with matching IconPurpose) is present. It should prefer shrinking over + // enlarging. EXPECT_EQ(SK_ColorYELLOW, ReadIconAndResize(app_id, icon_size::k128)); EXPECT_EQ(SK_ColorBLUE, ReadIconAndResize(app_id, icon_size::k16)); EXPECT_EQ(SK_ColorRED, ReadIconAndResize(app_id, 1024)); -} -TEST_F(WebAppIconManagerTest, ReadIconAndResize_Failure) { - auto web_app = CreateWebApp(); - const AppId app_id = web_app->app_id(); - - web_app->SetDownloadedIconSizes({icon_size::k32, icon_size::k64}); - - controller().RegisterApp(std::move(web_app)); - + // Maskable icons not found. base::RunLoop run_loop; - icon_manager().ReadIconAndResize( - app_id, icon_size::k128, + app_id, IconPurpose::MASKABLE, icon_size::k128, base::BindLambdaForTesting( [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { EXPECT_TRUE(icon_bitmaps.empty()); @@ -648,6 +935,82 @@ run_loop.Run(); } +TEST_F(WebAppIconManagerTest, ReadIconAndResize_Success_AnyAndMaskable) { + auto web_app = CreateWebApp(); + const AppId app_id = web_app->app_id(); + + const std::vector<int> sizes_px{icon_size::k32, icon_size::k64, + icon_size::k256, icon_size::k512}; + const std::vector<SkColor> colors{SK_ColorBLUE, SK_ColorGREEN, SK_ColorYELLOW, + SK_ColorRED}; + WriteIcons(app_id, {IconPurpose::ANY, IconPurpose::MASKABLE}, sizes_px, + colors); + + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, sizes_px); + + controller().RegisterApp(std::move(web_app)); + + for (size_t i = 0; i < sizes_px.size(); ++i) { + EXPECT_EQ(colors[i], + ReadIconAndResize(app_id, IconPurpose::ANY, sizes_px[i])); + } + for (size_t i = 0; i < sizes_px.size(); ++i) { + EXPECT_EQ(colors[i], + ReadIconAndResize(app_id, IconPurpose::MASKABLE, sizes_px[i])); + } + + // ReadIconAndResize should work for non-present icon sizes as long as an icon + // (with matching IconPurpose) is present. It should prefer shrinking over + // enlarging. + EXPECT_EQ(SK_ColorYELLOW, + ReadIconAndResize(app_id, IconPurpose::ANY, icon_size::k128)); + EXPECT_EQ(SK_ColorBLUE, + ReadIconAndResize(app_id, IconPurpose::ANY, icon_size::k16)); + EXPECT_EQ(SK_ColorRED, ReadIconAndResize(app_id, IconPurpose::ANY, 1024)); + EXPECT_EQ(SK_ColorYELLOW, + ReadIconAndResize(app_id, IconPurpose::MASKABLE, icon_size::k128)); + EXPECT_EQ(SK_ColorBLUE, + ReadIconAndResize(app_id, IconPurpose::MASKABLE, icon_size::k16)); + EXPECT_EQ(SK_ColorRED, + ReadIconAndResize(app_id, IconPurpose::MASKABLE, 1024)); +} + +TEST_F(WebAppIconManagerTest, ReadIconAndResize_Failure) { + auto web_app = CreateWebApp(); + const AppId app_id = web_app->app_id(); + + web_app->SetDownloadedIconSizes(IconPurpose::ANY, + {icon_size::k32, icon_size::k64}); + web_app->SetDownloadedIconSizes(IconPurpose::MASKABLE, + {icon_size::k32, icon_size::k64}); + + controller().RegisterApp(std::move(web_app)); + + { + base::RunLoop run_loop; + icon_manager().ReadIconAndResize( + app_id, IconPurpose::ANY, icon_size::k128, + base::BindLambdaForTesting( + [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { + EXPECT_TRUE(icon_bitmaps.empty()); + run_loop.Quit(); + })); + run_loop.Run(); + } + { + base::RunLoop run_loop; + icon_manager().ReadIconAndResize( + app_id, IconPurpose::MASKABLE, icon_size::k128, + base::BindLambdaForTesting( + [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { + EXPECT_TRUE(icon_bitmaps.empty()); + run_loop.Quit(); + })); + run_loop.Run(); + } +} + TEST_F(WebAppIconManagerTest, MatchSizes) { EXPECT_EQ(kWebAppIconSmall, extension_misc::EXTENSION_ICON_SMALL); } @@ -658,9 +1021,9 @@ const std::vector<int> sizes_px{gfx::kFaviconSize, icon_size::k48}; const std::vector<SkColor> colors{SK_ColorGREEN, SK_ColorRED}; - WriteIcons(app_id, sizes_px, colors); + WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors); - web_app->SetDownloadedIconSizes(sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); controller().RegisterApp(std::move(web_app)); @@ -689,9 +1052,9 @@ const std::vector<int> sizes_px{gfx::kFaviconSize, icon_size::k48}; const std::vector<SkColor> colors{SK_ColorBLUE, SK_ColorRED}; - WriteIcons(app_id, sizes_px, colors); + WriteIcons(app_id, {IconPurpose::ANY}, sizes_px, colors); - web_app->SetDownloadedIconSizes(sizes_px); + web_app->SetDownloadedIconSizes(IconPurpose::ANY, sizes_px); base::RunLoop run_loop; icon_manager().SetFaviconReadCallbackForTesting(
diff --git a/chrome/browser/web_applications/web_app_install_finalizer.cc b/chrome/browser/web_applications/web_app_install_finalizer.cc index a8189dc..fbde63b7 100644 --- a/chrome/browser/web_applications/web_app_install_finalizer.cc +++ b/chrome/browser/web_applications/web_app_install_finalizer.cc
@@ -450,7 +450,10 @@ web_app->SetIconInfos(web_app_info.icon_infos); web_app->SetDownloadedIconSizes( - GetSquareSizePxs(web_app_info.icon_bitmaps_any)); + IconPurpose::ANY, GetSquareSizePxs(web_app_info.icon_bitmaps_any)); + web_app->SetDownloadedIconSizes( + IconPurpose::MASKABLE, + GetSquareSizePxs(web_app_info.icon_bitmaps_maskable)); web_app->SetIsGeneratedIcon(web_app_info.is_generated_icon); web_app->SetShortcutsMenuItemInfos(web_app_info.shortcuts_menu_item_infos); @@ -462,8 +465,11 @@ SetWebAppProtocolHandlers(web_app_info.protocol_handlers, web_app.get()); AppId app_id = web_app->app_id(); + IconBitmaps icon_bitmaps; + icon_bitmaps.any = web_app_info.icon_bitmaps_any; + icon_bitmaps.maskable = web_app_info.icon_bitmaps_maskable; icon_manager_->WriteData( - std::move(app_id), web_app_info.icon_bitmaps_any, + std::move(app_id), std::move(icon_bitmaps), base::BindOnce(&WebAppInstallFinalizer::OnIconsDataWritten, weak_ptr_factory_.GetWeakPtr(), std::move(commit_callback), std::move(web_app),
diff --git a/chrome/browser/web_applications/web_app_install_manager_unittest.cc b/chrome/browser/web_applications/web_app_install_manager_unittest.cc index e2bf1bf42..afb1691 100644 --- a/chrome/browser/web_applications/web_app_install_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_manager_unittest.cc
@@ -79,10 +79,10 @@ for (const WebApplicationIconInfo& icon_info : app.icon_infos()) { blink::Manifest::ImageResource icon; icon.src = icon_info.url; - icon.purpose.push_back(blink::Manifest::ImageResource::Purpose::ANY); - icon.sizes.push_back( - gfx::Size(icon_info.square_size_px.value_or(kDefaultImageSize), - icon_info.square_size_px.value_or(kDefaultImageSize))); + icon.purpose.push_back(icon_info.purpose); + icon.sizes.emplace_back( + icon_info.square_size_px.value_or(kDefaultImageSize), + icon_info.square_size_px.value_or(kDefaultImageSize)); icons.push_back(std::move(icon)); } return icons; @@ -372,11 +372,12 @@ std::map<SquareSizePx, SkBitmap> ReadIcons( const AppId& app_id, + IconPurpose purpose, std::vector<SquareSizePx> sizes_px) { std::map<SquareSizePx, SkBitmap> result; base::RunLoop run_loop; icon_manager().ReadIcons( - app_id, sizes_px, + app_id, purpose, sizes_px, base::BindLambdaForTesting( [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { result = std::move(icon_bitmaps); @@ -715,7 +716,7 @@ sizes.push_back(size); } expected_app->SetIconInfos(std::move(icon_infos)); - expected_app->SetDownloadedIconSizes(std::move(sizes)); + expected_app->SetDownloadedIconSizes(IconPurpose::ANY, std::move(sizes)); { WebApp::SyncFallbackData sync_fallback_data; @@ -791,7 +792,7 @@ sizes.push_back(size); } expected_app->SetIconInfos(std::move(icon_infos)); - expected_app->SetDownloadedIconSizes(std::move(sizes)); + expected_app->SetDownloadedIconSizes(IconPurpose::ANY, std::move(sizes)); expected_app->SetIsGeneratedIcon(true); { @@ -1168,14 +1169,16 @@ const WebApp* web_app = registrar().GetAppById(app_id); EXPECT_EQ(2U, web_app->icon_infos().size()); - EXPECT_EQ(SizesToGenerate().size(), web_app->downloaded_icon_sizes().size()); + EXPECT_EQ(SizesToGenerate().size(), + web_app->downloaded_icon_sizes(IconPurpose::ANY).size()); + EXPECT_EQ(0u, web_app->downloaded_icon_sizes(IconPurpose::MASKABLE).size()); EXPECT_EQ(icon1_url, web_app->icon_infos().at(0).url); EXPECT_EQ(icon2_url, web_app->icon_infos().at(1).url); // Read icons from disk to check pixel contents. std::map<SquareSizePx, SkBitmap> icon_bitmaps = - ReadIcons(app_id, {icon_size::k128, icon_size::k256}); + ReadIcons(app_id, IconPurpose::ANY, {icon_size::k128, icon_size::k256}); EXPECT_EQ(2u, icon_bitmaps.size()); const auto& icon1 = icon_bitmaps[icon_size::k128]; @@ -1230,7 +1233,9 @@ const WebApp* web_app = registrar().GetAppById(app_id); EXPECT_EQ(2U, web_app->icon_infos().size()); - EXPECT_EQ(SizesToGenerate().size(), web_app->downloaded_icon_sizes().size()); + EXPECT_EQ(SizesToGenerate().size(), + web_app->downloaded_icon_sizes(IconPurpose::ANY).size()); + EXPECT_EQ(0u, web_app->downloaded_icon_sizes(IconPurpose::MASKABLE).size()); EXPECT_EQ(icon1_url, web_app->icon_infos().at(0).url); EXPECT_EQ(icon2_url, web_app->icon_infos().at(1).url); @@ -1238,7 +1243,7 @@ // Read icons from disk. All icons get the E letter drawn into a rounded // blue background. std::map<SquareSizePx, SkBitmap> icon_bitmaps = - ReadIcons(app_id, {icon_size::k128, icon_size::k256}); + ReadIcons(app_id, IconPurpose::ANY, {icon_size::k128, icon_size::k256}); EXPECT_EQ(2u, icon_bitmaps.size()); const auto& icon1 = icon_bitmaps[icon_size::k128]; @@ -1274,7 +1279,8 @@ const WebApp* web_app = registrar().GetAppById(app_id); std::map<SquareSizePx, SkBitmap> icon_bitmaps = - ReadIcons(app_id, web_app->downloaded_icon_sizes()); + ReadIcons(app_id, IconPurpose::ANY, + web_app->downloaded_icon_sizes(IconPurpose::ANY)); // Make sure that icons have been generated for all sub sizes. EXPECT_TRUE(ContainsOneIconOfEachSize(icon_bitmaps)); @@ -1313,7 +1319,8 @@ ASSERT_TRUE(web_app); std::map<SquareSizePx, SkBitmap> icon_bitmaps = - ReadIcons(expected_app_id, web_app->downloaded_icon_sizes()); + ReadIcons(expected_app_id, IconPurpose::ANY, + web_app->downloaded_icon_sizes(IconPurpose::ANY)); // Make sure that icons have been generated for all sub sizes. EXPECT_TRUE(ContainsOneIconOfEachSize(icon_bitmaps)); @@ -1338,7 +1345,8 @@ ASSERT_TRUE(web_app); std::map<SquareSizePx, SkBitmap> icon_bitmaps = - ReadIcons(expected_app_id, web_app->downloaded_icon_sizes()); + ReadIcons(expected_app_id, IconPurpose::ANY, + web_app->downloaded_icon_sizes(IconPurpose::ANY)); // Make sure that icons have been generated for all sub sizes. EXPECT_TRUE(ContainsOneIconOfEachSize(icon_bitmaps));
diff --git a/chrome/browser/web_applications/web_app_install_task.cc b/chrome/browser/web_applications/web_app_install_task.cc index 3cb821b..3a01752a 100644 --- a/chrome/browser/web_applications/web_app_install_task.cc +++ b/chrome/browser/web_applications/web_app_install_task.cc
@@ -97,6 +97,7 @@ WebAppUrlLoader* url_loader, LoadWebAppAndCheckManifestCallback callback) { DCHECK(url_loader); + CheckInstallPreconditions(); // Create a WebContents instead of reusing a shared one because we will pass // it back to be used for opening the web app. // TODO(loyso): Implement stealing of shared web_contents in upcoming @@ -233,6 +234,7 @@ const AppId& app_id, std::unique_ptr<WebApplicationInfo> web_application_info, InstallManager::OnceInstallCallback callback) { + CheckInstallPreconditions(); Observe(web_contents); install_callback_ = std::move(callback); background_installation_ = true; @@ -297,6 +299,9 @@ DCHECK(!web_contents()); CHECK(!install_callback_); CHECK(!retrieve_info_callback_); + + DCHECK(!initiated_); + initiated_ = true; } void WebAppInstallTask::RecordInstallEvent(
diff --git a/chrome/browser/web_applications/web_app_install_task.h b/chrome/browser/web_applications/web_app_install_task.h index 589b4cd5..8d1b3019 100644 --- a/chrome/browser/web_applications/web_app_install_task.h +++ b/chrome/browser/web_applications/web_app_install_task.h
@@ -42,6 +42,10 @@ class WebAppDataRetriever; class WebAppUrlLoader; +// Used to do a variety of tasks involving installing web applications. Only one +// of the public Load*, Update*, or Install* methods can be called on a single +// object. WebAppInstallManager is a queue of WebAppInstallTask jobs. Basically, +// WebAppInstallTask is an implementation detail of WebAppInstallManager. class WebAppInstallTask : content::WebContentsObserver { public: using RetrieveWebApplicationInfoWithIconsCallback = @@ -230,6 +234,10 @@ const AppId& app_id, const OsHooksResults os_hooks_results); + // Whether the install task has been 'initiated' by calling one of the public + // methods. + bool initiated_ = false; + // Whether we should just obtain WebApplicationInfo instead of the actual // installation. bool only_retrieve_web_application_info_ = false;
diff --git a/chrome/browser/web_applications/web_app_install_task_unittest.cc b/chrome/browser/web_applications/web_app_install_task_unittest.cc index 86a78bf..20d772e1 100644 --- a/chrome/browser/web_applications/web_app_install_task_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_task_unittest.cc
@@ -181,6 +181,15 @@ return base::NullableString16(base::UTF8ToUTF16(str), false); } + void ResetInstallTask() { + auto data_retriever = std::make_unique<TestDataRetriever>(); + data_retriever_ = static_cast<TestDataRetriever*>(data_retriever.get()); + + install_task_ = std::make_unique<WebAppInstallTask>( + profile(), os_integration_manager_.get(), install_finalizer_.get(), + std::move(data_retriever)); + } + void SetInstallFinalizerForTesting() { auto test_install_finalizer = std::make_unique<TestInstallFinalizer>(); test_install_finalizer_ = test_install_finalizer.get(); @@ -332,8 +341,9 @@ std::unique_ptr<InstallFinalizer> install_finalizer_; std::unique_ptr<TestOsIntegrationManager> os_integration_manager_; - // Owned by install_task_: + // Owned by icon_manager_: TestFileUtils* file_utils_ = nullptr; + // Owned by install_task_: TestDataRetriever* data_retriever_ = nullptr; #if defined(OS_CHROMEOS) @@ -444,6 +454,7 @@ const AppId installed_web_app = InstallWebAppFromManifestWithFallback(); EXPECT_EQ(app_id, installed_web_app); + ResetInstallTask(); // Force reinstall: CreateRendererAppInfo(url, "Renderer Name2", "Renderer Description2"); @@ -1035,6 +1046,7 @@ EXPECT_EQ(DisplayMode::kBrowser, registrar().GetAppById(app_id)->user_display_mode()); } + ResetInstallTask(); { CreateDataToRetrieve(GURL("https://example.org/"), /*open_as_window*/ true); @@ -1043,6 +1055,7 @@ EXPECT_EQ(DisplayMode::kStandalone, registrar().GetAppById(app_id)->user_display_mode()); } + ResetInstallTask(); { CreateDataToRetrieve(GURL("https://example.au/"), /*open_as_window*/ true); @@ -1051,6 +1064,7 @@ EXPECT_EQ(DisplayMode::kBrowser, registrar().GetAppById(app_id)->user_display_mode()); } + ResetInstallTask(); { CreateDataToRetrieve(GURL("https://example.app/"), /*open_as_window*/ false); @@ -1076,6 +1090,7 @@ EXPECT_EQ(app_id1, result.app_id); EXPECT_TRUE(registrar().GetAppById(app_id1)); } + ResetInstallTask(); { CreateDefaultDataToRetrieve(url2); install_task().ExpectAppId(app_id1); @@ -1099,6 +1114,7 @@ EXPECT_TRUE(result.app_id.empty()); EXPECT_FALSE(registrar().GetAppById(app_id)); } + ResetInstallTask(); { CreateDefaultDataToRetrieve(url); url_loader().SetNextLoadUrlResult( @@ -1109,6 +1125,7 @@ EXPECT_TRUE(result.app_id.empty()); EXPECT_FALSE(registrar().GetAppById(app_id)); } + ResetInstallTask(); { CreateDefaultDataToRetrieve(url); url_loader().SetNextLoadUrlResult(url, WebAppUrlLoader::Result::kUrlLoaded); @@ -1118,6 +1135,7 @@ EXPECT_EQ(app_id, result.app_id); EXPECT_TRUE(registrar().GetAppById(app_id)); } + ResetInstallTask(); { CreateDefaultDataToRetrieve(url); url_loader().SetNextLoadUrlResult(url, WebAppUrlLoader::Result::kUrlLoaded); @@ -1144,6 +1162,7 @@ LoadAndRetrieveWebApplicationInfoWithIcons(url); EXPECT_FALSE(result); } + ResetInstallTask(); { CreateDefaultDataToRetrieve(url); url_loader().SetNextLoadUrlResult( @@ -1153,6 +1172,7 @@ LoadAndRetrieveWebApplicationInfoWithIcons(url); EXPECT_FALSE(result); } + ResetInstallTask(); { CreateDefaultDataToRetrieve(start_url); CreateRendererAppInfo(url, name, description); @@ -1165,6 +1185,7 @@ EXPECT_TRUE(result->icon_infos.empty()); EXPECT_FALSE(result->icon_bitmaps_any.empty()); } + ResetInstallTask(); { // Verify the callback is always called. base::RunLoop run_loop; @@ -1474,6 +1495,7 @@ EXPECT_EQ(InstallResultCode::kSuccessNewInstall, result.code); EXPECT_EQ(app_id, result.app_id); } + ResetInstallTask(); // Update the installed app, adding a Shortcuts Menu in the process. { @@ -1499,6 +1521,7 @@ EXPECT_EQ(InstallResultCode::kSuccessNewInstall, result.code); EXPECT_EQ(app_id, result.app_id); } + ResetInstallTask(); // Update the installed app, Shortcuts Menu has changed. { @@ -1523,6 +1546,7 @@ EXPECT_EQ(InstallResultCode::kSuccessNewInstall, result.code); EXPECT_EQ(app_id, result.app_id); } + ResetInstallTask(); // Update the installed app. Only theme color changed, so Shortcuts Menu // should stay the same.
diff --git a/chrome/browser/web_applications/web_app_migration_manager.cc b/chrome/browser/web_applications/web_app_migration_manager.cc index ce1843d..35ec33e 100644 --- a/chrome/browser/web_applications/web_app_migration_manager.cc +++ b/chrome/browser/web_applications/web_app_migration_manager.cc
@@ -113,9 +113,8 @@ weak_ptr_factory_.GetWeakPtr(), app_id)); } -void WebAppMigrationManager::OnBookmarkAppIconsRead( - const AppId& app_id, - std::map<SquareSizePx, SkBitmap> icon_bitmaps) { +void WebAppMigrationManager::OnBookmarkAppIconsRead(const AppId& app_id, + IconBitmaps icon_bitmaps) { if (icon_bitmaps.empty()) { DLOG(ERROR) << "Read bookmark app icons failed."; MigrateNextBookmarkAppIcons(); @@ -236,12 +235,14 @@ bookmark_app_registrar_.IsLocallyInstalled(app_id)); web_app->SetIconInfos(bookmark_app_registrar_.GetAppIconInfos(app_id)); web_app->SetDownloadedIconSizes( - bookmark_app_registrar_.GetAppDownloadedIconSizes(app_id)); + IconPurpose::ANY, + bookmark_app_registrar_.GetAppDownloadedIconSizesAny(app_id)); + // Migrated bookmark apps will have no IconPurpose::MASKABLE icons downloaded. if (base::FeatureList::IsEnabled( features::kDesktopPWAsAppIconShortcutsMenu)) { web_app->SetShortcutsMenuItemInfos( - bookmark_app_registrar_.GetAppShortcutInfos(app_id)); + bookmark_app_registrar_.GetAppShortcutsMenuItemInfos(app_id)); web_app->SetDownloadedShortcutsMenuIconsSizes( bookmark_app_registrar_.GetAppDownloadedShortcutsMenuIconsSizes( app_id));
diff --git a/chrome/browser/web_applications/web_app_migration_manager.h b/chrome/browser/web_applications/web_app_migration_manager.h index 83ab8a86..2a7b4b7 100644 --- a/chrome/browser/web_applications/web_app_migration_manager.h +++ b/chrome/browser/web_applications/web_app_migration_manager.h
@@ -53,8 +53,7 @@ // Migrates next bookmark app in |bookmark_app_ids_| queue or starts // the registry migration if the queue is empty. void MigrateNextBookmarkAppIcons(); - void OnBookmarkAppIconsRead(const AppId& app_id, - std::map<SquareSizePx, SkBitmap> icon_bitmaps); + void OnBookmarkAppIconsRead(const AppId& app_id, IconBitmaps icon_bitmaps); void OnWebAppIconsWritten(const AppId& app_id, bool success); void OnBookmarkAppShortcutsMenuIconsRead( const AppId& app_id,
diff --git a/chrome/browser/web_applications/web_app_migration_manager_browsertest.cc b/chrome/browser/web_applications/web_app_migration_manager_browsertest.cc index 85d02603..1aab0c3 100644 --- a/chrome/browser/web_applications/web_app_migration_manager_browsertest.cc +++ b/chrome/browser/web_applications/web_app_migration_manager_browsertest.cc
@@ -234,11 +234,12 @@ const std::vector<SquareSizePx> icon_sizes_in_px = {32, 48, 64, 96, 128, 144, 192, 256, 512}; - EXPECT_EQ(icon_sizes_in_px, web_app->downloaded_icon_sizes()); + EXPECT_EQ(icon_sizes_in_px, web_app->downloaded_icon_sizes(IconPurpose::ANY)); base::RunLoop run_loop; provider().icon_manager().ReadIcons( - app_id, web_app->downloaded_icon_sizes(), + app_id, IconPurpose::ANY, + web_app->downloaded_icon_sizes(IconPurpose::ANY), base::BindLambdaForTesting( [&](std::map<SquareSizePx, SkBitmap> icon_bitmaps) { EXPECT_EQ(9u, icon_bitmaps.size()); @@ -414,7 +415,7 @@ EXPECT_TRUE(provider().registrar().IsInstalled(app_id)); std::vector<WebApplicationShortcutsMenuItemInfo> shortcuts_menu_item_infos = - provider().registrar().GetAppShortcutInfos(app_id); + provider().registrar().GetAppShortcutsMenuItemInfos(app_id); EXPECT_EQ(shortcuts_menu_item_infos.size(), 2u); EXPECT_EQ(shortcuts_menu_item_infos[0].name, base::UTF8ToUTF16("shortcut1")); EXPECT_EQ(shortcuts_menu_item_infos[0].shortcut_icon_infos.size(), 1u);
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc index 1fe8257..17a6475 100644 --- a/chrome/browser/web_applications/web_app_registrar.cc +++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/web_applications/web_app_registrar.h" -#include <memory> #include <utility> #include <vector> @@ -143,15 +142,15 @@ : std::vector<WebApplicationIconInfo>(); } -std::vector<SquareSizePx> WebAppRegistrar::GetAppDownloadedIconSizes( +std::vector<SquareSizePx> WebAppRegistrar::GetAppDownloadedIconSizesAny( const AppId& app_id) const { auto* web_app = GetAppById(app_id); - return web_app ? web_app->downloaded_icon_sizes() + return web_app ? web_app->downloaded_icon_sizes(IconPurpose::ANY) : std::vector<SquareSizePx>(); } std::vector<WebApplicationShortcutsMenuItemInfo> -WebAppRegistrar::GetAppShortcutInfos(const AppId& app_id) const { +WebAppRegistrar::GetAppShortcutsMenuItemInfos(const AppId& app_id) const { auto* web_app = GetAppById(app_id); return web_app ? web_app->shortcuts_menu_item_infos() : std::vector<WebApplicationShortcutsMenuItemInfo>();
diff --git a/chrome/browser/web_applications/web_app_registrar.h b/chrome/browser/web_applications/web_app_registrar.h index b7ee011..4374c6c 100644 --- a/chrome/browser/web_applications/web_app_registrar.h +++ b/chrome/browser/web_applications/web_app_registrar.h
@@ -57,9 +57,9 @@ base::Time GetAppInstallTime(const web_app::AppId& app_id) const override; std::vector<WebApplicationIconInfo> GetAppIconInfos( const AppId& app_id) const override; - std::vector<SquareSizePx> GetAppDownloadedIconSizes( + std::vector<SquareSizePx> GetAppDownloadedIconSizesAny( const AppId& app_id) const override; - std::vector<WebApplicationShortcutsMenuItemInfo> GetAppShortcutInfos( + std::vector<WebApplicationShortcutsMenuItemInfo> GetAppShortcutsMenuItemInfos( const AppId& app_id) const override; std::vector<std::vector<SquareSizePx>> GetAppDownloadedShortcutsMenuIconsSizes(const AppId& app_id) const override;
diff --git a/chrome/browser/web_applications/web_app_shortcut_manager.cc b/chrome/browser/web_applications/web_app_shortcut_manager.cc index 16ed3bbc..8004ff7 100644 --- a/chrome/browser/web_applications/web_app_shortcut_manager.cc +++ b/chrome/browser/web_applications/web_app_shortcut_manager.cc
@@ -51,10 +51,11 @@ // Build a common intersection between desired and downloaded icons. auto icon_sizes_in_px = base::STLSetIntersection<std::vector<SquareSizePx>>( - app->downloaded_icon_sizes(), GetDesiredIconSizesForShortcut()); + app->downloaded_icon_sizes(IconPurpose::ANY), + GetDesiredIconSizesForShortcut()); if (!icon_sizes_in_px.empty()) { - icon_manager_->ReadIcons(app_id, icon_sizes_in_px, + icon_manager_->ReadIcons(app_id, IconPurpose::ANY, icon_sizes_in_px, base::BindOnce(&WebAppShortcutManager::OnIconsRead, weak_ptr_factory_.GetWeakPtr(), app_id, std::move(callback))); @@ -65,25 +66,18 @@ // get. SquareSizePx desired_icon_size = GetDesiredIconSizesForShortcut().back(); - if (icon_manager_->HasIconToResize(app_id, desired_icon_size)) { - icon_manager_->ReadIconAndResize( - app_id, desired_icon_size, - base::BindOnce(&WebAppShortcutManager::OnIconsRead, - weak_ptr_factory_.GetWeakPtr(), app_id, - std::move(callback))); - } else { - // No icon found. Create shortcut info with the standard application icon - // anyway. - OnIconsRead(app_id, std::move(callback), - std::map<SquareSizePx, SkBitmap>()); - } + icon_manager_->ReadIconAndResize( + app_id, IconPurpose::ANY, desired_icon_size, + base::BindOnce(&WebAppShortcutManager::OnIconsRead, + weak_ptr_factory_.GetWeakPtr(), app_id, + std::move(callback))); } void WebAppShortcutManager::OnIconsRead( const AppId& app_id, GetShortcutInfoCallback callback, std::map<SquareSizePx, SkBitmap> icon_bitmaps) { - // |icon_bitmaps| can be empty here. + // |icon_bitmaps| can be empty here if no icon found. const WebApp* app = GetWebAppRegistrar().GetAppById(app_id); if (!app) { std::move(callback).Run(nullptr);
diff --git a/chrome/browser/xsurface/BUILD.gn b/chrome/browser/xsurface/BUILD.gn index 95ab11d0..8c7b197 100644 --- a/chrome/browser/xsurface/BUILD.gn +++ b/chrome/browser/xsurface/BUILD.gn
@@ -13,7 +13,6 @@ "android/java/src/org/chromium/chrome/browser/xsurface/ProcessScope.java", "android/java/src/org/chromium/chrome/browser/xsurface/ProcessScopeDependencyProvider.java", "android/java/src/org/chromium/chrome/browser/xsurface/SurfaceActionsHandler.java", - "android/java/src/org/chromium/chrome/browser/xsurface/SurfaceDependencyProvider.java", "android/java/src/org/chromium/chrome/browser/xsurface/SurfaceRenderer.java", "android/java/src/org/chromium/chrome/browser/xsurface/SurfaceScope.java", "android/java/src/org/chromium/chrome/browser/xsurface/SurfaceScopeDependencyProvider.java",
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/HybridListRenderer.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/HybridListRenderer.java index 125e231de..936b1f1 100644 --- a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/HybridListRenderer.java +++ b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/HybridListRenderer.java
@@ -24,6 +24,27 @@ } /** + * Notify the HybridListRender when the externally provided view surface (embedded in + * bind/update) is activated. This should include: + * + * - the user opening a new tab containing the (opened) surface. + * - the user switching to a tab containing the (opened) surface. + * - the user reactivating the previously deactivated surface. + */ + default void onSurfaceOpened() {} + + /** + * Notify the HybridListRender when the externally provided view surface (embedded in + * bind/update) is deactivated. This should include: + * + * - the user switching to another app. + * - the user browsing away to other content. + * - the user deactivates the surface. + * - the user switching to another tab. + */ + default void onSurfaceClosed() {} + + /** * Unbinds a previously attached recyclerview and contentmanager. * * Does nothing if nothing was previously bound.
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/ProcessScopeDependencyProvider.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/ProcessScopeDependencyProvider.java index 33d852e4..ffac701 100644 --- a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/ProcessScopeDependencyProvider.java +++ b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/ProcessScopeDependencyProvider.java
@@ -10,8 +10,6 @@ /** * Provides application-level dependencies for an external surface. - * - * Note: this will replace SurfaceDependencyProvider and so does not have any methods. */ public interface ProcessScopeDependencyProvider { /** @return the context associated with the application. */
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceDependencyProvider.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceDependencyProvider.java deleted file mode 100644 index afdd6cc..0000000 --- a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceDependencyProvider.java +++ /dev/null
@@ -1,13 +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. - -package org.chromium.chrome.browser.xsurface; - -/** - * Provides logging and context for an external surface. - * - * Note: this will replace SurfaceDependencyProvider and so does not have any methods. - */ -@Deprecated -public interface SurfaceDependencyProvider extends ProcessScopeDependencyProvider {}
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 1f40fc7..8c90f1ae 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1597233486-9b99859a3e8f91576b2a111cc083e1a4b72a89f4.profdata +chrome-mac-master-1597275686-7da657e756f53f89a89030a34195741313ee681f.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 263fd1dd..5d361aa3 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-master-1596815835-17de714c85521ed0db12b66b0c37f9edb8bc5aba.profdata +chrome-win32-master-1596045560-16c58258c8890a214570e6099d355ac47072ea3d.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index f2e11b82..07f16578 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1596801568-da9053c5545285a0551be6620dd66e88ca5fbe04.profdata +chrome-win64-master-1596045560-6c3207dc8f6ea5df1e0c422b4fa4d700088c0a24.profdata
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index 76204d1..916f11f 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -605,6 +605,7 @@ "//base", "//base/third_party/dynamic_annotations", "//build:branding_buildflags", + "//build:lacros_buildflags", "//components/bookmarks/common", "//components/nacl/common:switches", "//components/offline_pages/buildflags",
diff --git a/chrome/common/extensions/api/api_sources.gni b/chrome/common/extensions/api/api_sources.gni index de7ff0b03..e9be692 100644 --- a/chrome/common/extensions/api/api_sources.gni +++ b/chrome/common/extensions/api/api_sources.gni
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/chromeos/ui_mode.gni") import("//build/config/features.gni") import("//chrome/common/features.gni") @@ -76,6 +77,10 @@ schema_sources_ += [ "networking_cast_private.idl" ] } +if (is_chromeos || chromeos_is_browser_only) { + schema_sources_ += [ "enterprise_platform_keys.idl" ] +} + if (is_chromeos) { schema_sources_ += [ "certificate_provider.idl", @@ -84,7 +89,6 @@ "echo_private.json", "enterprise_device_attributes.idl", "enterprise_networking_attributes.idl", - "enterprise_platform_keys.idl", "enterprise_platform_keys_internal.idl", "enterprise_platform_keys_private.json", "file_browser_handler_internal.json",
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 5942167..d3f3ae7 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1390,8 +1390,7 @@ "native_printing.device_external_print_servers_allowlist"; // List of printers configured by policy. -const char kRecommendedNativePrinters[] = - "native_printing.recommended_printers"; +const char kRecommendedPrinters[] = "native_printing.recommended_printers"; // Enum designating the type of restrictions bulk printers are using. const char kRecommendedNativePrintersAccessMode[] =
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 2f9aae4..f2e3eb3 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -445,7 +445,7 @@ #if defined(OS_CHROMEOS) extern const char kExternalPrintServersAllowlist[]; extern const char kDeviceExternalPrintServersAllowlist[]; -extern const char kRecommendedNativePrinters[]; +extern const char kRecommendedPrinters[]; extern const char kRecommendedNativePrintersAccessMode[]; extern const char kRecommendedNativePrintersBlacklist[]; extern const char kRecommendedNativePrintersWhitelist[];
diff --git a/chrome/common/web_application_info.cc b/chrome/common/web_application_info.cc index a67de0d..3379a15 100644 --- a/chrome/common/web_application_info.cc +++ b/chrome/common/web_application_info.cc
@@ -80,6 +80,21 @@ icon_info2.purpose); } +std::ostream& operator<<(std::ostream& out, IconPurpose purpose) { + switch (purpose) { + case IconPurpose::ANY: + out << "any"; + break; + case IconPurpose::MONOCHROME: + out << "monochrome"; + break; + case IconPurpose::MASKABLE: + out << "maskable"; + break; + } + return out; +} + std::ostream& operator<<(std::ostream& out, const WebApplicationIconInfo& icon_info) { out << "url: " << icon_info.url << " square_size_px: "; @@ -87,18 +102,7 @@ out << *icon_info.square_size_px; else out << "none"; - out << " purpose: "; - switch (icon_info.purpose) { - case blink::Manifest::ImageResource::Purpose::ANY: - out << "any"; - break; - case blink::Manifest::ImageResource::Purpose::MONOCHROME: - out << "monochrome"; - break; - case blink::Manifest::ImageResource::Purpose::MASKABLE: - out << "maskable"; - break; - } + out << " purpose: " << icon_info.purpose; return out; }
diff --git a/chrome/common/web_application_info.h b/chrome/common/web_application_info.h index d148d450..b915ebe 100644 --- a/chrome/common/web_application_info.h +++ b/chrome/common/web_application_info.h
@@ -22,6 +22,7 @@ using SquareSizePx = int; using ShortcutsMenuIconsBitmaps = std::vector<std::map<SquareSizePx, SkBitmap>>; +using IconPurpose = blink::Manifest::ImageResource::Purpose; // TODO(https://crbug.com/1091473): Rename WebApplication* occurrences in this // file to WebApp*. @@ -36,8 +37,8 @@ GURL url; base::Optional<SquareSizePx> square_size_px; - blink::Manifest::ImageResource::Purpose purpose = - blink::Manifest::ImageResource::Purpose::ANY; + // TODO (crbug.com/1114638): Support Monochrome. + IconPurpose purpose = IconPurpose::ANY; }; // Structure used when creating app icon shortcuts menu and for downloading @@ -108,6 +109,7 @@ std::map<SquareSizePx, SkBitmap> icon_bitmaps_any; // Icon bitmaps designed for masking, keyed by their square size. + // See https://www.w3.org/TR/appmanifest/#dfn-maskable-purpose std::map<SquareSizePx, SkBitmap> icon_bitmaps_maskable; // Represents whether the icons for the web app are generated by Chrome due to
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 52ae00f..ff152a6 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -402,6 +402,7 @@ const char kPrivacySubPage[] = "privacy"; const char kResetSubPage[] = "reset"; const char kResetProfileSettingsSubPage[] = "resetProfileSettings"; +const char kSafetyCheckSubPage[] = "safetyCheck"; const char kSearchSubPage[] = "search"; const char kSearchEnginesSubPage[] = "searchEngines"; const char kSignOutSubPage[] = "signOut";
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index 1bddc3e..49d83b0b 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -356,6 +356,7 @@ extern const char kPrivacySubPage[]; extern const char kResetSubPage[]; extern const char kResetProfileSettingsSubPage[]; +extern const char kSafetyCheckSubPage[]; extern const char kSearchSubPage[]; extern const char kSearchEnginesSubPage[]; extern const char kSignOutSubPage[];
diff --git a/chrome/credential_provider/extension/BUILD.gn b/chrome/credential_provider/extension/BUILD.gn index 2939caa..e6b522bf 100644 --- a/chrome/credential_provider/extension/BUILD.gn +++ b/chrome/credential_provider/extension/BUILD.gn
@@ -43,10 +43,24 @@ configs += [ "//build/config/win:windowed" ] } +source_set("extension_lib") { + sources = [ + "service.cc", + "service.h", + ] + deps = [ + ":common", + "../gaiacp:common", + "//base:base", + ] + configs += [ "//build/config/win:windowed" ] +} + executable("gcpw_extension") { sources = [ "extension_main.cc" ] deps = [ ":common", + ":extension_lib", ":extension_resources", ":version", "../eventlog:gcp_eventlog_messages",
diff --git a/chrome/credential_provider/extension/extension_main.cc b/chrome/credential_provider/extension/extension_main.cc index df4f706..e7f6148 100644 --- a/chrome/credential_provider/extension/extension_main.cc +++ b/chrome/credential_provider/extension/extension_main.cc
@@ -9,8 +9,11 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "base/process/memory.h" +#include "base/task/thread_pool/thread_pool_instance.h" #include "base/win/process_startup_helper.h" #include "chrome/credential_provider/eventlog/gcp_eventlog_messages.h" +#include "chrome/credential_provider/extension/os_service_manager.h" +#include "chrome/credential_provider/extension/service.h" #include "chrome/credential_provider/gaiacp/logging.h" int APIENTRY wWinMain(HINSTANCE hInstance, @@ -48,7 +51,10 @@ // Set the event logging source and category for GCPW Extension. logging::SetEventSource("GCPW", GCPW_EXTENSION_CATEGORY, MSG_LOG_MESSAGE); - LOGFN(VERBOSE) << "GCPW Extension started running."; + // This initializes and starts ThreadPoolInstance with default params. + base::ThreadPoolInstance::CreateAndStartWithDefaultParams("gcpw_extension"); + + credential_provider::extension::Service::Get()->Run(); return 0; }
diff --git a/chrome/credential_provider/extension/service.cc b/chrome/credential_provider/extension/service.cc new file mode 100644 index 0000000..7128813 --- /dev/null +++ b/chrome/credential_provider/extension/service.cc
@@ -0,0 +1,123 @@ +// 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/credential_provider/extension/service.h" + +#include "base/logging.h" +#include "chrome/credential_provider/extension/os_service_manager.h" +#include "chrome/credential_provider/gaiacp/logging.h" + +namespace credential_provider { +namespace extension { + +// static +Service** Service::GetInstanceStorage() { + static Service* instance = new Service(); + + return &instance; +} + +// static +Service* Service::Get() { + return *GetInstanceStorage(); +} + +DWORD Service::Run() { + return (this->*run_routine_)(); +} + +Service::Service() + : run_routine_(&Service::RunAsService), + service_status_(), + service_status_handle_(nullptr), + stop_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED) { + service_status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + service_status_.dwCurrentState = SERVICE_STOPPED; + service_status_.dwControlsAccepted = + SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PRESHUTDOWN; +} + +Service::~Service() {} + +DWORD Service::RunAsService() { + LOGFN(INFO); + + DWORD error_code = + extension::OSServiceManager::Get()->StartServiceCtrlDispatcher( + &Service::ServiceMain); + + if (error_code != ERROR_SUCCESS) { + LOGFN(ERROR) + << "OSServiceManager::StartServiceCtrlDispatcher failed with win32=" + << error_code; + } + + return error_code; +} + +void Service::StartMain() { + DWORD error_code = extension::OSServiceManager::Get()->RegisterCtrlHandler( + &Service::ServiceControlHandler, &service_status_handle_); + if (error_code != ERROR_SUCCESS) { + LOGFN(ERROR) << "OSServiceManager::RegisterCtrlHandler failed win32=" + << error_code; + return; + } + + service_status_.dwCurrentState = SERVICE_RUNNING; + + error_code = extension::OSServiceManager::Get()->SetServiceStatus( + service_status_handle_, service_status_); + if (error_code != ERROR_SUCCESS) { + LOGFN(ERROR) << "OSServiceManager::SetServiceStatus failed win32=" + << error_code; + return; + } + + stop_event_.Wait(); + + service_status_.dwCurrentState = SERVICE_STOPPED; + service_status_.dwControlsAccepted = 0; + + error_code = extension::OSServiceManager::Get()->SetServiceStatus( + service_status_handle_, service_status_); + if (error_code != ERROR_SUCCESS) + LOGFN(ERROR) << "OSServiceManager::SetServiceStatus failed win32=" + << error_code; +} + +// static +VOID WINAPI Service::ServiceMain(DWORD argc /*unused*/, + WCHAR* argv[] /*unused*/) { + LOGFN(INFO); + + Service* self = Service::Get(); + + // Run the service. + self->StartMain(); +} + +// static +VOID WINAPI Service::ServiceControlHandler(DWORD control) { + LOGFN(INFO); + + Service* self = Service::Get(); + switch (control) { + case SERVICE_CONTROL_PRESHUTDOWN: + case SERVICE_CONTROL_STOP: + self->service_status_.dwCurrentState = SERVICE_STOP_PENDING; + + extension::OSServiceManager::Get()->SetServiceStatus( + self->service_status_handle_, self->service_status_); + self->stop_event_.Signal(); + + break; + default: + break; + } +} + +} // namespace extension +} // namespace credential_provider
diff --git a/chrome/credential_provider/extension/service.h b/chrome/credential_provider/extension/service.h new file mode 100644 index 0000000..6d0ecd7 --- /dev/null +++ b/chrome/credential_provider/extension/service.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_CREDENTIAL_PROVIDER_EXTENSION_SERVICE_H_ +#define CHROME_CREDENTIAL_PROVIDER_EXTENSION_SERVICE_H_ + +#include <windows.h> + +#include "base/macros.h" +#include "base/synchronization/waitable_event.h" + +namespace credential_provider { +namespace extension { + +// Bare implementation of the GCPW extension service. Takes care the handshake +// with the service control manager and the lifetime of the service. +class Service { + public: + // Gets the singleton instance of the service. + static Service* Get(); + + // Invoke the chosen action routine. By default service runs as a service, + // but the action routine can support running in console for testing purposes. + DWORD Run(); + + private: + Service(); + virtual ~Service(); + + // The action routine to be executed. + DWORD (Service::*run_routine_)(); + + // This function handshakes with the service control manager and starts + // the service. + DWORD RunAsService(); + + // Non-static function that is called as part of service main(ServiceMain). + // Performs registering control handler callback and managing the service + // states. + void StartMain(); + + // Service main call back which was provided earlier to service control + // manager as part of RunAsService call. + static VOID WINAPI ServiceMain(DWORD argc, WCHAR* argv[]); + + // The control handler of the service. Details about the control codes can be + // found here: + // https://docs.microsoft.com/en-us/windows/win32/services/service-control-handler-function + static void WINAPI ServiceControlHandler(DWORD control); + + // Returns the storage used for the instance pointer. + static Service** GetInstanceStorage(); + + // Status of the running service. Must be updated accordingly before calling + // SetServiceStatus API. + SERVICE_STATUS service_status_; + + // The service status handle which is used with SetServiceStatus API. + SERVICE_STATUS_HANDLE service_status_handle_; + + // Primitive that controls when to finish running service main. + base::WaitableEvent stop_event_; + + DISALLOW_COPY_AND_ASSIGN(Service); +}; + +} // namespace extension +} // namespace credential_provider + +#endif // CHROME_CREDENTIAL_PROVIDER_EXTENSION_SERVICE_H_
diff --git a/chrome/credential_provider/extension/service_unittests.cc b/chrome/credential_provider/extension/service_unittests.cc new file mode 100644 index 0000000..7d1741d1 --- /dev/null +++ b/chrome/credential_provider/extension/service_unittests.cc
@@ -0,0 +1,97 @@ +// 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 <windows.h> + +#include "base/files/file_path.h" +#include "base/threading/thread.h" +#include "chrome/credential_provider/extension/scoped_handle.h" +#include "chrome/credential_provider/extension/service.h" +#include "chrome/credential_provider/test/gcp_fakes.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace credential_provider { + +namespace testing { + +class GCPWServiceTest : public ::testing::Test { + public: + // Start the service as if SCM is starting it. Note that this will be started + // in a new thread which simulates the main thread when service process + // starts. + void StartServiceMainThread() { + main_thread->Start(); + main_thread->task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&GCPWServiceTest::RunService, base::Unretained(this))); + // Give some time so that service starts running and accpeting control + // requests. + ::Sleep(1000); + } + + void CheckServiceStatus(DWORD status) { + SERVICE_STATUS service_status; + fake_os_service_manager_.GetServiceStatus(&service_status); + ASSERT_EQ(service_status.dwCurrentState, status); + } + + void SendControlRequest(DWORD control_request) { + fake_os_service_manager_.SendControlRequestForTesting(control_request); + // Give some time for control to be processed by the service control + // handler. + ::Sleep(1000); + } + + FakeOSServiceManager* fake_os_service_manager() { + return &fake_os_service_manager_; + } + + protected: + void SetUp() override { + main_thread = std::make_unique<base::Thread>("ProcessMain Thread"); + } + + void TearDown() override { + SendControlRequest(SERVICE_CONTROL_STOP); + main_thread->Stop(); + } + + private: + void RunService() { + ASSERT_TRUE(credential_provider::extension::Service::Get()->Run() == + ERROR_SUCCESS); + } + + std::unique_ptr<base::Thread> main_thread; + FakeOSServiceManager fake_os_service_manager_; +}; + +TEST_F(GCPWServiceTest, StartSuccess) { + // Install service into SCM database. + credential_provider::extension::ScopedScHandle sc_handle; + ASSERT_TRUE(ERROR_SUCCESS == fake_os_service_manager()->InstallService( + base::FilePath(L"test"), &sc_handle)); + + StartServiceMainThread(); + CheckServiceStatus(SERVICE_RUNNING); + + SendControlRequest(SERVICE_CONTROL_STOP); + CheckServiceStatus(SERVICE_STOPPED); +} + +TEST_F(GCPWServiceTest, NoOpControlRequest) { + // Install service into SCM database. + credential_provider::extension::ScopedScHandle sc_handle; + ASSERT_TRUE(ERROR_SUCCESS == fake_os_service_manager()->InstallService( + base::FilePath(L"test"), &sc_handle)); + + StartServiceMainThread(); + CheckServiceStatus(SERVICE_RUNNING); + + SendControlRequest(SERVICE_CONTROL_PAUSE); + CheckServiceStatus(SERVICE_RUNNING); +} + +} // namespace testing +} // namespace credential_provider
diff --git a/chrome/credential_provider/test/BUILD.gn b/chrome/credential_provider/test/BUILD.gn index db54269f..e6a4e004 100644 --- a/chrome/credential_provider/test/BUILD.gn +++ b/chrome/credential_provider/test/BUILD.gn
@@ -7,6 +7,7 @@ test("gcp_unittests") { sources = [ + "../extension/service_unittests.cc", "../gaiacp/associated_user_validator_unittests.cc", "../gaiacp/device_policies_manager_unittests.cc", "../gaiacp/gaia_credential_base_unittests.cc", @@ -32,6 +33,7 @@ deps = [ "../extension:common", + "../extension:extension_lib", "../gaiacp:common", "../gaiacp:gaia_credential_provider_idl", "../gaiacp:gaiacp_lib",
diff --git a/chrome/credential_provider/test/gcp_fakes.cc b/chrome/credential_provider/test/gcp_fakes.cc index 67f3bb5..90476a5 100644 --- a/chrome/credential_provider/test/gcp_fakes.cc +++ b/chrome/credential_provider/test/gcp_fakes.cc
@@ -19,9 +19,11 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/waitable_event.h" +#include "base/threading/thread.h" #include "base/win/scoped_handle.h" #include "base/win/scoped_process_information.h" #include "chrome/credential_provider/common/gcp_strings.h" +#include "chrome/credential_provider/extension/extension_strings.h" #include "chrome/credential_provider/gaiacp/gcp_utils.h" #include "chrome/credential_provider/gaiacp/logging.h" #include "chrome/credential_provider/gaiacp/mdm_utils.h" @@ -1266,13 +1268,94 @@ *GetInstanceStorage() = os_service_manager_; } -DWORD FakeOSServiceManager::GetServiceStatus(SERVICE_STATUS* service_status) { - return ERROR_SERVICE_DOES_NOT_EXIST; +DWORD FakeOSServiceManager::StartServiceCtrlDispatcher( + LPSERVICE_MAIN_FUNCTION service_main) { + if (service_lookup_from_name_.find(extension::kGCPWExtensionServiceName) == + service_lookup_from_name_.end()) { + return ERROR_INVALID_DATA; + } + LOGFN(INFO); + // Windows calls the service main by creating a new thread. This is simulated + // in the test by creating a new thread. + base::Thread t("ServiceMain Thread"); + t.Start(); + t.task_runner()->PostTask(FROM_HERE, + base::BindOnce(service_main, 0, nullptr)); + + while (true) { + // Service looks for control requests so that it calls the service's control + // handler. + DWORD control_request = GetControlRequestForTesting(); + LOGFN(INFO) << "Received control: " << control_request; + + // This is a custom control to end the service process main when service is + // supposed to stop. + if (control_request == 100) + break; + + service_lookup_from_name_[extension::kGCPWExtensionServiceName] + .control_handler_cb_(control_request); + } + + return ERROR_SUCCESS; +} + +DWORD FakeOSServiceManager::RegisterCtrlHandler( + LPHANDLER_FUNCTION handler_proc, + SERVICE_STATUS_HANDLE* service_status_handle) { + if (service_lookup_from_name_.find(extension::kGCPWExtensionServiceName) == + service_lookup_from_name_.end()) { + return ERROR_SERVICE_DOES_NOT_EXIST; + } + + service_lookup_from_name_[extension::kGCPWExtensionServiceName] + .control_handler_cb_ = handler_proc; + // Set some random integer here. Not needed in the tests. + *service_status_handle = (SERVICE_STATUS_HANDLE)1; + + return ERROR_SUCCESS; +} + +DWORD FakeOSServiceManager::SetServiceStatus( + SERVICE_STATUS_HANDLE service_status_handle, + SERVICE_STATUS service) { + LOGFN(INFO) << "Service state: " << service.dwCurrentState; + if (service_lookup_from_name_.find(extension::kGCPWExtensionServiceName) == + service_lookup_from_name_.end()) { + return ERROR_SERVICE_DOES_NOT_EXIST; + } + service_lookup_from_name_[extension::kGCPWExtensionServiceName] + .service_status_ = service; + + if (service.dwCurrentState == SERVICE_STOPPED) + SendControlRequestForTesting(100); + return ERROR_SUCCESS; } DWORD FakeOSServiceManager::InstallService( const base::FilePath& service_binary_path, extension::ScopedScHandle* sc_handle) { + LOGFN(INFO); + + service_lookup_from_name_[extension::kGCPWExtensionServiceName] + .service_status_.dwCurrentState = SERVICE_STOPPED; + return ERROR_SUCCESS; +} + +DWORD FakeOSServiceManager::GetServiceStatus(SERVICE_STATUS* service_status) { + LOGFN(INFO); + if (service_lookup_from_name_.find(extension::kGCPWExtensionServiceName) == + service_lookup_from_name_.end()) { + return ERROR_SERVICE_DOES_NOT_EXIST; + } + *service_status = + service_lookup_from_name_[extension::kGCPWExtensionServiceName] + .service_status_; + return ERROR_SUCCESS; +} + +DWORD FakeOSServiceManager::DeleteService() { + service_lookup_from_name_.erase(extension::kGCPWExtensionServiceName); return ERROR_SUCCESS; }
diff --git a/chrome/credential_provider/test/gcp_fakes.h b/chrome/credential_provider/test/gcp_fakes.h index eba5478..6c0384d 100644 --- a/chrome/credential_provider/test/gcp_fakes.h +++ b/chrome/credential_provider/test/gcp_fakes.h
@@ -6,12 +6,15 @@ #define CHROME_CREDENTIAL_PROVIDER_TEST_GCP_FAKES_H_ #include <deque> +#include <list> #include <map> #include <memory> #include <string> +#include <thread> #include <vector> #include "base/strings/string16.h" +#include "base/synchronization/waitable_event.h" #include "base/test/test_reg_util_win.h" #include "base/win/scoped_handle.h" #include "chrome/credential_provider/extension/os_service_manager.h" @@ -660,8 +663,47 @@ DWORD InstallService(const base::FilePath& service_binary_path, extension::ScopedScHandle* sc_handle) override; + DWORD StartServiceCtrlDispatcher( + LPSERVICE_MAIN_FUNCTION service_main) override; + + DWORD RegisterCtrlHandler( + LPHANDLER_FUNCTION handler_proc, + SERVICE_STATUS_HANDLE* service_status_handle) override; + + DWORD SetServiceStatus(SERVICE_STATUS_HANDLE service_status_handle, + SERVICE_STATUS service) override; + + void SendControlRequestForTesting(DWORD control_request) { + std::unique_lock<std::mutex> lock(m); + queue.push_back(control_request); + cv.notify_one(); + } + + DWORD DeleteService() override; + private: + DWORD GetControlRequestForTesting() { + std::unique_lock<std::mutex> lock(m); + cv.wait(lock, [&]() { return !queue.empty(); }); + DWORD result = queue.front(); + queue.pop_front(); + return result; + } + + struct ServiceInfo { + LPHANDLER_FUNCTION control_handler_cb_; + SERVICE_STATUS service_status_; + }; + + // Primitives that are used to synchronize with the thread running service + // main and the thread testing the code. + std::list<DWORD> queue; + std::mutex m; + std::condition_variable cv; + + // Original instance of OSServiceManager. extension::OSServiceManager* os_service_manager_ = nullptr; + std::map<base::string16, ServiceInfo> service_lookup_from_name_; }; ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/renderer/lite_video/lite_video_url_loader_throttle.cc b/chrome/renderer/lite_video/lite_video_url_loader_throttle.cc index 4c795df2..acde3638 100644 --- a/chrome/renderer/lite_video/lite_video_url_loader_throttle.cc +++ b/chrome/renderer/lite_video/lite_video_url_loader_throttle.cc
@@ -36,10 +36,13 @@ // TODO(rajendrant): Also allow the throttle to be stopped when LiteMode gets // disabled or ECT worsens. This logic should probably be in the browser // process. - if (IsLiteVideoEnabled() && - GetLiteVideoHintAgent(render_frame_id)->HasLiteVideoHint()) { + if (!IsLiteVideoEnabled()) + return nullptr; + + auto* lite_video_hint_agent = GetLiteVideoHintAgent(render_frame_id); + if (lite_video_hint_agent && lite_video_hint_agent->HasLiteVideoHint()) return std::make_unique<LiteVideoURLLoaderThrottle>(render_frame_id); - } + return nullptr; }
diff --git a/chrome/services/machine_learning/BUILD.gn b/chrome/services/machine_learning/BUILD.gn index fefc19f..a0c7cde 100644 --- a/chrome/services/machine_learning/BUILD.gn +++ b/chrome/services/machine_learning/BUILD.gn
@@ -71,9 +71,16 @@ outputs = [ "$root_out_dir/test_data/simple_test.tflite" ] } - copy("tflite_lib") { - sources = [ "//third_party/tensorflow/libtensorflowlite_c.so" ] - outputs = [ "$root_out_dir/libtensorflowlite_c.so" ] + if (is_android) { + copy("tflite_lib") { + sources = [ "//third_party/tensorflow/libtensorflowlite_c_arm64.so" ] + outputs = [ "$root_out_dir/libtensorflowlite_c.so" ] + } + } else { + copy("tflite_lib") { + sources = [ "//third_party/tensorflow/libtensorflowlite_c.so" ] + outputs = [ "$root_out_dir/libtensorflowlite_c.so" ] + } } }
diff --git a/chrome/services/machine_learning/README.md b/chrome/services/machine_learning/README.md index ab06748..fa244d9 100644 --- a/chrome/services/machine_learning/README.md +++ b/chrome/services/machine_learning/README.md
@@ -19,15 +19,30 @@ ``` Build Tensorflow Lite library: - - clone https://github.com/tensorflow/tensorflow - - cd tensorflow - - bazel build tensorflow/lite/c:libtensorflowlite_c.so - - copy 'libtensorflowlite_c.so' file to chromium/src/third_party/tensorflow + + clone https://github.com/tensorflow/tensorflow + + cd tensorflow + + for x86 architecture: + + bazel build tensorflow/lite/c:libtensorflowlite_c.so + + for android: + + bazel build --config=android_arm64 tensorflow/lite/c:libtensorflowlite_c.so + + copy 'libtensorflowlite_c.so' file to chromium/src/third_party/tensorflow + + link the library to a soft link in system library directory under /lib/ Copy libraries: - - c_api.h and common.h [here](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/c) to into third_party/tensorflow/lite/c + + c_api.h and common.h [here](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/c) to into third_party/tensorflow/lite/c Build TFLite in chrome: - - Set flag build_with_tflite_lib=true - - Uncomment thirdparty library in [machine learning header file](./machine_learning_tflite_predictor.h). - \ No newline at end of file + + Set flag build_with_tflite_lib=true + + Uncomment thirdparty library in [machine learning header file](./machine_learning_tflite_predictor.h). + \ No newline at end of file
diff --git a/chrome/services/machine_learning/machine_learning_tflite_predictor.cc b/chrome/services/machine_learning/machine_learning_tflite_predictor.cc index 304ef47..ab9a6007 100644 --- a/chrome/services/machine_learning/machine_learning_tflite_predictor.cc +++ b/chrome/services/machine_learning/machine_learning_tflite_predictor.cc
@@ -8,8 +8,8 @@ namespace machine_learning { -TFLitePredictor::TFLitePredictor(std::string filename) - : model_file_name_(filename) {} +TFLitePredictor::TFLitePredictor(std::string filename, int32_t num_threads) + : model_file_name_(filename), num_threads_(num_threads) {} TFLitePredictor::~TFLitePredictor() = default; @@ -51,6 +51,8 @@ if (options_ == nullptr) return false; + TfLiteInterpreterOptionsSetNumThreads(options_.get(), num_threads_); + // We create the pointer using this approach since |TfLiteInterpreter| is a // structure without the delete operator. interpreter_ = std::unique_ptr<TfLiteInterpreter, @@ -81,7 +83,6 @@ return TfLiteInterpreterGetOutputTensorCount(interpreter_.get()); } -// TODO: change this to private TfLiteTensor* TFLitePredictor::GetInputTensor(int32_t index) const { if (interpreter_ == nullptr) return nullptr;
diff --git a/chrome/services/machine_learning/machine_learning_tflite_predictor.h b/chrome/services/machine_learning/machine_learning_tflite_predictor.h index c1abe98..7beae02 100644 --- a/chrome/services/machine_learning/machine_learning_tflite_predictor.h +++ b/chrome/services/machine_learning/machine_learning_tflite_predictor.h
@@ -19,12 +19,10 @@ namespace machine_learning { -// TFLite predictor class around TFLite C API for model evaluation. +// TFLite predictor class around TFLite C API for TFLite model evaluation. class TFLitePredictor { public: - // Creates a |TFLitePredictor| from a - // |char*| TFLite file. - explicit TFLitePredictor(std::string filename); + TFLitePredictor(std::string filename, int32_t num_threads); ~TFLitePredictor(); // Loads model, build the TFLite interpreter and allocates tensors. @@ -77,6 +75,9 @@ TfLiteStatus AllocateTensors(); std::string model_file_name_; + + // Number of threads used by |interpreter_| for evaluating |model_|. + int32_t num_threads_ = 1; std::unique_ptr<TfLiteModel, std::function<void(TfLiteModel*)>> model_; std::unique_ptr<TfLiteInterpreterOptions, std::function<void(TfLiteInterpreterOptions*)>>
diff --git a/chrome/services/machine_learning/machine_learning_tflite_predictor_unittest.cc b/chrome/services/machine_learning/machine_learning_tflite_predictor_unittest.cc index 4facf35..a2dcfb1 100644 --- a/chrome/services/machine_learning/machine_learning_tflite_predictor_unittest.cc +++ b/chrome/services/machine_learning/machine_learning_tflite_predictor_unittest.cc
@@ -17,6 +17,7 @@ class TFLitePredictorTest : public ::testing::Test { public: + const int32_t kTFLiteNumThreads = 4; const int32_t kInputTensorNum = 1; const int32_t kOutputTensorNum = 1; @@ -52,7 +53,7 @@ TEST_F(TFLitePredictorTest, TFLiteInitializationTest) { // Initialize the model std::string model_path = GetTFLiteTestPath(); - TFLitePredictor predictor(model_path); + TFLitePredictor predictor(model_path, kTFLiteNumThreads); TfLiteStatus status = predictor.Initialize(); EXPECT_EQ(status, kTfLiteOk); } @@ -60,7 +61,7 @@ TEST_F(TFLitePredictorTest, TFLiteTensorsCountTest) { // Initialize the model std::string model_path = GetTFLiteTestPath(); - TFLitePredictor predictor(model_path); + TFLitePredictor predictor(model_path, kTFLiteNumThreads); TfLiteStatus status = predictor.Initialize(); EXPECT_EQ(status, kTfLiteOk); @@ -71,7 +72,7 @@ TEST_F(TFLitePredictorTest, TFLiteTensorsTest) { // Initialize the model std::string model_path = GetTFLiteTestPath(); - TFLitePredictor predictor(model_path); + TFLitePredictor predictor(model_path, kTFLiteNumThreads); TfLiteStatus status = predictor.Initialize(); EXPECT_EQ(status, kTfLiteOk); @@ -98,7 +99,7 @@ // Initialize the model std::string model_path = GetTFLiteTestPath(); - TFLitePredictor predictor(model_path); + TFLitePredictor predictor(model_path, kTFLiteNumThreads); predictor.Initialize(); // Initialize model input tensor
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index e581ac6e8..036dda3 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -16,6 +16,7 @@ import("//chrome/browser/page_load_metrics/integration_tests/jsdeps.gni") import("//chrome/browser/page_load_metrics/integration_tests/sources.gni") import("//chrome/common/features.gni") +import("//chrome/services/machine_learning/features.gni") import("//chrome/test/base/js2gtest.gni") import("//chrome/test/include_js_tests.gni") import("//chromeos/assistant/assistant.gni") @@ -1190,6 +1191,7 @@ "../browser/secure_origin_allowlist_browsertest.cc", "../browser/serial/chrome_serial_browsertest.cc", "../browser/sessions/better_session_restore_browsertest.cc", + "../browser/sessions/closed_tab_cache_browsertest.cc", "../browser/sessions/session_restore_browsertest.cc", "../browser/sessions/session_restore_browsertest_chromeos.cc", "../browser/sessions/session_restore_observer_browsertest.cc", @@ -1485,6 +1487,9 @@ "../browser/speech/speech_recognizer_browsertest.cc", ] + if (build_with_tflite_lib) { + sources += [ "../browser/tflite_experiment/tflite_experiment_keyed_service_browsertest.cc" ] + } if (is_win) { data += [ "$root_out_dir/chrome_200_percent.pak" ] deps += [ "//chrome/app:chrome_dll_resources" ] @@ -1920,6 +1925,7 @@ "../browser/ui/views/extensions/extension_dialog_browsertest.cc", "../browser/ui/views/web_apps/pwa_confirmation_bubble_view_browsertest.cc", "../browser/ui/views/web_apps/web_app_confirmation_view_browsertest.cc", + "../browser/ui/web_applications/test/system_web_app_ui_browsertest.cc", "../browser/ui/web_applications/test/web_app_navigation_browsertest.cc", "../browser/ui/web_applications/test/web_app_navigation_browsertest.h", ] @@ -4790,6 +4796,7 @@ "../browser/extensions/api/identity/gaia_web_auth_flow_unittest.cc", "../browser/extensions/api/identity/identity_api_unittest.cc", "../browser/extensions/api/identity/identity_mint_queue_unittest.cc", + "../browser/extensions/api/identity/identity_token_cache_unittest.cc", "../browser/extensions/api/image_writer_private/destroy_partitions_operation_unittest.cc", "../browser/extensions/api/image_writer_private/image_writer_private_api_unittest.cc", "../browser/extensions/api/image_writer_private/operation_manager_unittest.cc", @@ -6258,10 +6265,6 @@ sources += [ "../browser/downgrade/user_data_snapshot_browsertest.cc" ] } - if (use_x11) { - configs += [ "//build/config/linux:xtst" ] - } - if (enable_extensions) { # TODO(rockot) bug 505926: The chrome_extensions_interactive_uitests # target should be deleted and this line removed. See the
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java index 5756bb0..073546f 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
@@ -421,7 +421,7 @@ ChromeTabUtils.waitForTabPageLoaded(tab, (String) null); - if (tab != null && NewTabPage.isNTPUrl(tab.getUrlString()) + if (tab != null && NewTabPage.isNTPUrl(ChromeTabUtils.getUrlStringOnUiThread(tab)) && !getActivity().isInOverviewMode()) { NewTabPageTestUtils.waitForNtpLoaded(tab); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java index 437c158..f418e10 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeTabUtils.java
@@ -40,6 +40,7 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestTouchUtils; import org.chromium.content_public.browser.test.util.TouchCommon; +import org.chromium.url.GURL; import java.util.List; import java.util.Locale; @@ -119,7 +120,8 @@ } private static boolean loadComplete(Tab tab, String url) { - return !tab.isLoading() && (url == null || TextUtils.equals(tab.getUrlString(), url)) + return !tab.isLoading() + && (url == null || TextUtils.equals(getUrlStringOnUiThread(tab), url)) && !tab.getWebContents().isLoadingToDifferentDocument(); } @@ -129,6 +131,18 @@ return res.get(); } + public static String getUrlStringOnUiThread(Tab tab) { + AtomicReference<String> res = new AtomicReference<>(); + TestThreadUtils.runOnUiThreadBlocking(() -> { res.set(tab.getUrlString()); }); + return res.get(); + } + + public static GURL getUrlOnUiThread(Tab tab) { + AtomicReference<GURL> res = new AtomicReference<>(); + TestThreadUtils.runOnUiThreadBlocking(() -> { res.set(tab.getUrl()); }); + return res.get(); + } + /** * Waits for the given tab to finish loading the given URL, or, if the given URL is * null, waits for the current page to load.
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ViewUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ViewUtils.java index aa46ac71..8f55033 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ViewUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ViewUtils.java
@@ -113,7 +113,7 @@ */ public static void waitForView( ViewGroup root, Matcher<View> viewMatcher, @ExpectedViewState int viewState) { - CriteriaHelper.pollUiThread(new ExpectedViewCriteria(viewMatcher, viewState, root)); + CriteriaHelper.pollUiThreadNested(new ExpectedViewCriteria(viewMatcher, viewState, root)); } /** @@ -133,7 +133,7 @@ Matcher<View> viewMatcher, @ExpectedViewState int viewState) { return (View view, NoMatchingViewException noMatchException) -> { if (noMatchException != null) throw noMatchException; - CriteriaHelper.pollUiThread( + CriteriaHelper.pollUiThreadNested( new ExpectedViewCriteria(viewMatcher, viewState, (ViewGroup) view)); }; } @@ -167,12 +167,13 @@ * @return An interaction on the matching view. */ public static ViewInteraction onViewWaiting(Matcher<View> viewMatcher) { - Espresso.onView(ViewMatchers.isRoot()) - .check((View view, NoMatchingViewException noMatchException) -> { - if (noMatchException != null) throw noMatchException; - CriteriaHelper.pollUiThread( - new ExpectedViewCriteria(viewMatcher, VIEW_VISIBLE, (ViewGroup) view)); - }); + CriteriaHelper.pollInstrumentationThread(() -> { + Espresso.onView(ViewMatchers.isRoot()) + .check((View view, NoMatchingViewException noMatchException) -> { + if (noMatchException != null) throw noMatchException; + new ExpectedViewCriteria(viewMatcher, VIEW_VISIBLE, (ViewGroup) view).run(); + }); + }); return Espresso.onView(viewMatcher); }
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index a080cd9..6f0fb3d 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -568,6 +568,7 @@ }, "NativePrinters": { + "note": "This policy is deprecated by 'Printers' policy. See http://crbug.com/1113362.", "os": ["chromeos"], "policy_pref_mapping_test": [ { @@ -592,7 +593,33 @@ ] }, + "Printers": { + "os": ["chromeos"], + "policy_pref_mapping_test": [ + { + "policies": { + "Printers": [ + { + "display_name": "Break Room", + "description": "The blue one", + "manufacturer": "PrtrMfgr", + "model": "MegaLazer", + "uri": "ipps://192.168.2.14", + "uuid": "aaaa-aaaa-eeee-eeee-1234", + "ppd_resource": { + "effective_manufacturer": "Printers, Ink", + "effective_model": "LaserMaster 2100" + } + } + ] + }, + "prefs": { "native_printing.recommended_printers": {} } + } + ] + }, + "NativePrintersBulkConfiguration": { + "note": "This policy is deprecated, see http://crbug.com/1113366.", "os": ["chromeos"], "policy_pref_mapping_test": [ { @@ -606,6 +633,20 @@ ] }, + "PrintersBulkConfiguration": { + "os": ["chromeos"], + "policy_pref_mapping_test": [ + { + "policies": { + "PrintersBulkConfiguration": { + "url": "https://example.com/policyfile", + "hash": "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" + } + } + } + ] + }, + "NativePrintersBulkAccessMode": { "os": ["chromeos"], "policy_pref_mapping_test": [
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 7f59eee..a799d59 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -190,6 +190,7 @@ data = [ "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cr_policy_network_behavior_mojo_tests.m.js", "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/cr_policy_network_indicator_mojo_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_components/chromeos/network_config_element_behavior_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_components/managed_footnote_test.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_button_tests.m.js", "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_container_shadow_behavior_test.m.js", @@ -250,6 +251,7 @@ "$root_gen_dir/chrome/test/data/webui/settings/chromeos/fake_bluetooth.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/fake_quick_unlock_private.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/input_method_options_page_test.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/input_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/localized_link_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/multidevice_feature_item_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/multidevice_feature_toggle_tests.m.js", @@ -258,9 +260,12 @@ "$root_gen_dir/chrome/test/data/webui/settings/chromeos/multidevice_subpage_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/nearby_share_subpage_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_languages_page_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_languages_page_v2_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_reset_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_people_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_privacy_page_test.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/smb_shares_page_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_files_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/parental_controls_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/people_page_account_manager_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/people_page_change_picture_test.m.js",
diff --git a/chrome/test/data/webui/cr_components/chromeos/BUILD.gn b/chrome/test/data/webui/cr_components/chromeos/BUILD.gn index b520d671..18b1686 100644 --- a/chrome/test/data/webui/cr_components/chromeos/BUILD.gn +++ b/chrome/test/data/webui/cr_components/chromeos/BUILD.gn
@@ -8,5 +8,6 @@ input_files = [ "cr_policy_network_behavior_mojo_tests.js", "cr_policy_network_indicator_mojo_tests.js", + "network_config_element_behavior_test.js", ] }
diff --git a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_browsertest.js b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_browsertest.js index b0ed1c2..8a834d20c 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_browsertest.js +++ b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_browsertest.js
@@ -38,6 +38,9 @@ '../../chromeos/fake_network_config_mojom.js', ] ], + ['NetworkConfigElementBehavior', 'network_config_element_behavior_test.js', + [] + ], ].forEach(test => registerTest(...test)); // clang-format on @@ -46,7 +49,7 @@ this[className] = class extends PolymerTest { /** @override */ get browsePreload() { - return `chrome://os-settings/test_loader.html?module=cr_components/chromeos/${module}`; + return `chrome://internet-config-dialog/test_loader.html?module=cr_components/chromeos/${module}`; } /** @override */ @@ -55,5 +58,5 @@ } }; - TEST_F(className, 'MAYBE_All', () => mocha.run()); + TEST_F(className, 'All', () => mocha.run()); }
diff --git a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js index 9afe21e6..29abffd 100644 --- a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js +++ b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js
@@ -11,6 +11,7 @@ // clang-format off [['CrPolicyNetworkBehaviorMojo', 'cr_policy_network_behavior_mojo_tests.m.js'], ['CrPolicyNetworkIndicatorMojo', 'cr_policy_network_indicator_mojo_tests.m.js'], + ['NetworkConfigElementBehavior', 'network_config_element_behavior_test.m.js'], ].forEach(test => registerTest(...test)); // clang-format on
diff --git a/chrome/test/data/webui/cr_components/chromeos/network_config_element_behavior_test.js b/chrome/test/data/webui/cr_components/chromeos/network_config_element_behavior_test.js new file mode 100644 index 0000000..480ebc68 --- /dev/null +++ b/chrome/test/data/webui/cr_components/chromeos/network_config_element_behavior_test.js
@@ -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. + +// clang-format off +// #import 'chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js'; +// #import 'chrome://resources/mojo/services/network/public/mojom/ip_address.mojom-lite.js'; +// #import 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-lite.js'; +// #import 'chrome://resources/mojo/mojo/public/mojom/base/time.mojom-lite.js'; +// #import 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-lite.js'; +// #import {NetworkConfigElementBehavior} from 'chrome://resources/cr_components/chromeos/network/network_config_element_behavior.m.js'; +// #import {OncMojo} from 'chrome://resources/cr_components/chromeos/network/onc_mojo.m.js'; +// #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {assertFalse, assertTrue} from '../../chai_assert.js'; +// clang-format on + +suite('CrComponentsNetworkConfigElementBehaviorTest', function() { + /** @type {!NetworkConfigElementBehavior} */ + let config; + + /** @polymerBehavior */ + const TestNetworkPolicyEnforcer = { + properties: { + /** True if the policy should be enforced. */ + enforced: { + type: Boolean, + value: false, + }, + }, + + /** @override */ + isNetworkPolicyEnforced(policy) { + // In tests, toggle |policy| and |enforced| to elicit different behaviors. + return !!policy && this.enforced; + }, + }; + + suiteSetup(function() { + Polymer({ + is: 'test-network-config-element', + + behaviors: [ + NetworkConfigElementBehavior, + TestNetworkPolicyEnforcer, + ], + + properties: { + showPolicyIndicator: { + type: Boolean, + value: false, + computed: 'getDisabled_(disabled, property)', + } + }, + }); + }); + + setup(function() { + config = document.createElement('test-network-config-element'); + document.body.appendChild(config); + Polymer.dom.flush(); + }); + + test('Policy indicator states', function() { + config.disabled = false; + config.enforced = false; + config.property = null; + assertFalse(config.showPolicyIndicator); + + config.disabled = false; + config.enforced = true; + config.property = null; + assertFalse(config.showPolicyIndicator); + + config.disabled = true; + config.enforced = false; + config.property = null; + assertTrue(config.showPolicyIndicator); + + config.disabled = true; + config.enforced = true; + config.property = null; + assertTrue(config.showPolicyIndicator); + + config.disabled = false; + config.enforced = false; + config.property = OncMojo.createManagedString('policy'); + assertFalse(config.showPolicyIndicator); + + config.disabled = false; + config.enforced = true; + config.property = OncMojo.createManagedString('policy'); + assertTrue(config.showPolicyIndicator); + + config.disabled = true; + config.enforced = false; + config.property = OncMojo.createManagedString('policy'); + assertTrue(config.showPolicyIndicator); + + config.disabled = true; + config.enforced = true; + config.property = OncMojo.createManagedString('policy'); + assertTrue(config.showPolicyIndicator); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 2e816f01..7bd75dd 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -40,6 +40,7 @@ "fake_settings_search_handler.js", "fake_user_action_recorder.js", "input_method_options_page_test.js", + "input_page_test.js", "localized_link_test.js", "multidevice_feature_item_tests.js", "multidevice_feature_toggle_tests.js", @@ -48,9 +49,12 @@ "multidevice_subpage_tests.js", "nearby_share_subpage_tests.js", "os_languages_page_tests.js", + "os_languages_page_v2_tests.js", "os_reset_page_test.js", "os_people_page_test.js", "os_privacy_page_test.js", + "smb_shares_page_tests.js", + "os_files_page_test.js", "parental_controls_page_test.js", "people_page_account_manager_test.js", "people_page_change_picture_test.js",
diff --git a/chrome/test/data/webui/settings/chromeos/input_page_test.js b/chrome/test/data/webui/settings/chromeos/input_page_test.js new file mode 100644 index 0000000..181bd89 --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/input_page_test.js
@@ -0,0 +1,54 @@ +// 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. + +// clang-format off +// #import {LanguagesMetricsProxy, LanguagesMetricsProxyImpl} from 'chrome://os-settings/chromeos/lazy_load.js'; +// #import {CrSettingsPrefs} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {TestLanguagesMetricsProxy} from './test_os_languages_metrics_proxy.m.js'; +// #import {assertFalse, assertTrue} from '../../chai_assert.js'; +// clang-format on + +suite('input page', () => { + /** @type {!SettingsInputPageElement} */ + let inputPage; + /** @type {!settings.LanguagesMetricsProxy} */ + let metricsProxy; + + setup(() => { + document.body.innerHTML = ''; + const prefElement = document.createElement('settings-prefs'); + document.body.appendChild(prefElement); + + return CrSettingsPrefs.initialized.then(() => { + // Sets up test metrics proxy. + metricsProxy = new settings.TestLanguagesMetricsProxy(); + settings.LanguagesMetricsProxyImpl.instance_ = metricsProxy; + + inputPage = document.createElement('os-settings-input-page'); + inputPage.prefs = prefElement.prefs; + document.body.appendChild(inputPage); + }); + }); + + suite('records metrics', () => { + test('when deactivating show ime menu', async () => { + inputPage.setPrefValue('settings.language.ime_menu_activated', true); + inputPage.$$('#showImeMenu').click(); + Polymer.dom.flush(); + + assertFalse( + await metricsProxy.whenCalled('recordToggleShowInputOptionsOnShelf')); + }); + + test('when activating show ime menu', async () => { + inputPage.setPrefValue('settings.language.ime_menu_activated', false); + inputPage.$$('#showImeMenu').click(); + Polymer.dom.flush(); + + assertTrue( + await metricsProxy.whenCalled('recordToggleShowInputOptionsOnShelf')); + }); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/os_files_page_test.js b/chrome/test/data/webui/settings/chromeos/os_files_page_test.js new file mode 100644 index 0000000..04a1f4c --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/os_files_page_test.js
@@ -0,0 +1,51 @@ +// 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. + +// clang-format off +// #import 'chrome://os-settings/chromeos/lazy_load.js'; + +// #import {Router, routes} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {flush} from'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; +// #import {assert} from 'chrome://resources/js/assert.m.js'; +// clang-format on + + +suite('FilesPageTests', function() { + /** @type {SettingsFilesPageElement} */ + let filesPage = null; + + setup(function() { + PolymerTest.clearBody(); + filesPage = document.createElement('os-settings-files-page'); + document.body.appendChild(filesPage); + Polymer.dom.flush(); + }); + + teardown(function() { + filesPage.remove(); + settings.Router.getInstance().resetRouteForTesting(); + }); + + test('Disconnect Google Drive account,pref disabled/enabled', async () => { + // The default state of the pref is disabled. + const disconnectGoogleDrive = + assert(filesPage.$$('#disconnectGoogleDriveAccount')); + assertFalse(disconnectGoogleDrive.checked); + + disconnectGoogleDrive.$$('cr-toggle').click(); + Polymer.dom.flush(); + assertTrue(disconnectGoogleDrive.checked); + }); + + test('Smb Shares, Navigates to SMB_SHARES route on click', async () => { + const smbShares = assert(filesPage.$$('#smbShares')); + + smbShares.click(); + Polymer.dom.flush(); + assertEquals( + settings.Router.getInstance().getCurrentRoute(), + settings.routes.SMB_SHARES); + }); +}); \ No newline at end of file
diff --git a/chrome/test/data/webui/settings/chromeos/os_languages_page_v2_tests.js b/chrome/test/data/webui/settings/chromeos/os_languages_page_v2_tests.js new file mode 100644 index 0000000..765c7f48 --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/os_languages_page_v2_tests.js
@@ -0,0 +1,238 @@ +// 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. + +// clang-format off +// #import {LanguagesBrowserProxyImpl, LanguagesMetricsProxyImpl, LanguagesPageInteraction} from 'chrome://os-settings/chromeos/lazy_load.js'; +// #import {CrSettingsPrefs, Router} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {assert} from 'chrome://resources/js/assert.m.js'; +// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {getFakeLanguagePrefs} from '../fake_language_settings_private.m.js' +// #import {FakeSettingsPrivate} from '../fake_settings_private.m.js'; +// #import {TestLanguagesBrowserProxy} from './test_os_languages_browser_proxy.m.js'; +// #import {TestLanguagesMetricsProxy} from './test_os_languages_metrics_proxy.m.js'; +// #import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; +// #import {fakeDataBind} from '../../test_util.m.js'; +// clang-format on + +suite('languages page', () => { + /** @type {!LanguageHelper} */ + let languageHelper; + /** @type {!SettingsLanguagesPageElement} */ + let languagesPage; + /** @type {!HTMLElement} */ + let languagesList; + /** @type {!CrActionMenuElement} */ + let actionMenu; + /** @type {!settings.LanguagesBrowserProxy} */ + let browserProxy; + /** @type {!settings.LanguagesMetricsProxy} */ + let metricsProxy; + + // Enabled language pref name for the platform. + const languagesPref = 'settings.language.preferred_languages'; + + // Initial value of enabled languages pref used in tests. + const initialLanguages = 'en-US,sw'; + + suiteSetup(() => { + CrSettingsPrefs.deferInitialization = true; + loadTimeData.overrideValues({imeOptionsInSettings: true}); + }); + + setup(async () => { + document.body.innerHTML = ''; + + const settingsPrefs = document.createElement('settings-prefs'); + const settingsPrivate = + new settings.FakeSettingsPrivate(settings.getFakeLanguagePrefs()); + settingsPrefs.initialize(settingsPrivate); + document.body.appendChild(settingsPrefs); + await CrSettingsPrefs.initialized; + // Sets up test browser proxy. + browserProxy = new settings.TestLanguagesBrowserProxy(); + settings.LanguagesBrowserProxyImpl.instance_ = browserProxy; + + // Sets up test metrics proxy. + metricsProxy = new settings.TestLanguagesMetricsProxy(); + settings.LanguagesMetricsProxyImpl.instance_ = metricsProxy; + + // Sets up fake languageSettingsPrivate API. + const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate(); + languageSettingsPrivate.setSettingsPrefs(settingsPrefs); + + // Instantiates the data model with data bindings for prefs. + const settingsLanguages = document.createElement('settings-languages'); + settingsLanguages.prefs = settingsPrefs.prefs; + test_util.fakeDataBind(settingsPrefs, settingsLanguages, 'prefs'); + document.body.appendChild(settingsLanguages); + + // Creates page with data bindings for prefs and data model. + languagesPage = document.createElement('os-settings-languages-page-v2'); + languagesPage.prefs = settingsPrefs.prefs; + test_util.fakeDataBind(settingsPrefs, languagesPage, 'prefs'); + languagesPage.languages = settingsLanguages.languages; + test_util.fakeDataBind(settingsLanguages, languagesPage, 'languages'); + languagesPage.languageHelper = settingsLanguages.languageHelper; + test_util.fakeDataBind(settingsLanguages, languagesPage, 'language-helper'); + document.body.appendChild(languagesPage); + + languagesList = languagesPage.$.languagesList; + actionMenu = languagesPage.$.menu.get(); + + languageHelper = languagesPage.languageHelper; + await languageHelper.whenReady(); + }); + + suite('language menu', () => { + /* + * Finds, asserts and returns the menu item for the given i18n key. + * @param {string} i18nKey Name of the i18n string for the item's text. + * @return {!HTMLElement} Menu item. + */ + function getMenuItem(i18nKey) { + const i18nString = assert(loadTimeData.getString(i18nKey)); + const menuItems = actionMenu.querySelectorAll('.dropdown-item'); + const menuItem = Array.from(menuItems).find( + item => item.textContent.trim() === i18nString); + return assert(menuItem, `Menu item "${i18nKey}" not found`); + } + + /* + * Checks the visibility of each expected menu item button. + * param {!Object<boolean>} Dictionary from i18n keys to expected + * visibility of those menu items. + */ + function assertMenuItemButtonsVisible(buttonVisibility) { + assertTrue(actionMenu.open); + for (const buttonKey of Object.keys(buttonVisibility)) { + const buttonItem = getMenuItem(buttonKey); + assertEquals( + !buttonVisibility[buttonKey], buttonItem.hidden, + `Menu item "${buttonKey}" hidden`); + } + } + + test('removes language when starting with 3 languages', () => { + // Enables a language which we can then disable. + languageHelper.enableLanguage('no'); + + // Populates the dom-repeat. + Polymer.dom.flush(); + + // Finds the new language item. + const items = languagesList.querySelectorAll('.list-item'); + const domRepeat = assert(languagesList.querySelector('dom-repeat')); + const item = Array.from(items).find(function(el) { + return domRepeat.itemForElement(el) && + domRepeat.itemForElement(el).language.code === 'no'; + }); + + // Opens the menu and selects Remove. + item.querySelector('cr-icon-button').click(); + + assertTrue(actionMenu.open); + const removeMenuItem = getMenuItem('removeLanguage'); + assertFalse(removeMenuItem.disabled); + assertFalse(removeMenuItem.hidden); + removeMenuItem.click(); + assertFalse(actionMenu.open); + + assertEquals( + initialLanguages, languageHelper.getPref(languagesPref).value); + }); + + test('removes language when starting with 2 languages', () => { + const items = languagesList.querySelectorAll('.list-item'); + const domRepeat = assert(languagesList.querySelector('dom-repeat')); + const item = Array.from(items).find(function(el) { + return domRepeat.itemForElement(el) && + domRepeat.itemForElement(el).language.code === 'sw'; + }); + + // Opens the menu and selects Remove. + item.querySelector('cr-icon-button').click(); + + assertTrue(actionMenu.open); + const removeMenuItem = getMenuItem('removeLanguage'); + assertFalse(removeMenuItem.disabled); + assertFalse(removeMenuItem.hidden); + removeMenuItem.click(); + assertFalse(actionMenu.open); + + assertEquals('en-US', languageHelper.getPref(languagesPref).value); + }); + + test('has move up/down buttons', () => { + // Adds several languages. + for (const language of ['en-CA', 'en-US', 'tk', 'no']) { + languageHelper.enableLanguage(language); + } + + Polymer.dom.flush(); + + const menuButtons = languagesList.querySelectorAll( + '.list-item cr-icon-button.icon-more-vert'); + + // First language should not have "Move up" or "Move to top". + menuButtons[0].click(); + assertMenuItemButtonsVisible({ + moveToTop: false, + moveUp: false, + moveDown: true, + }); + actionMenu.close(); + + // Second language should not have "Move up". + menuButtons[1].click(); + assertMenuItemButtonsVisible({ + moveToTop: true, + moveUp: false, + moveDown: true, + }); + actionMenu.close(); + + // Middle languages should have all buttons. + menuButtons[2].click(); + assertMenuItemButtonsVisible({ + moveToTop: true, + moveUp: true, + moveDown: true, + }); + actionMenu.close(); + + // Last language should not have "Move down". + menuButtons[menuButtons.length - 1].click(); + assertMenuItemButtonsVisible({ + moveToTop: true, + moveUp: true, + moveDown: false, + }); + actionMenu.close(); + }); + }); + + suite('records metrics', () => { + test('when adding languages', async () => { + languagesPage.$$('#addLanguages').click(); + Polymer.dom.flush(); + await metricsProxy.whenCalled('recordAddLanguages'); + }); + + test('when disabling translate.enable toggle', async () => { + languagesPage.setPrefValue('translate.enabled', true); + languagesPage.$$('#offerTranslation').click(); + Polymer.dom.flush(); + + assertFalse(await metricsProxy.whenCalled('recordToggleTranslate')); + }); + + test('when enabling translate.enable toggle', async () => { + languagesPage.setPrefValue('translate.enabled', false); + languagesPage.$$('#offerTranslation').click(); + Polymer.dom.flush(); + + assertTrue(await metricsProxy.whenCalled('recordToggleTranslate')); + }); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index c6e2e4a4..4a383885 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -1239,6 +1239,24 @@ mocha.run(); }); +// Tests for the Files section. +// eslint-disable-next-line no-var +var OSSettingsFilesPageTest = class extends OSSettingsBrowserTest { + /** @override */ + get browsePreload() { + return super.browsePreload + 'chromeos/os_files_page/os_files_page.html'; + } + + /** @override */ + get extraLibraries() { + return super.extraLibraries.concat(['os_files_page_test.js']); + } +}; + +TEST_F('OSSettingsFilesPageTest', 'AllJsTests', () => { + mocha.run(); +}); + // eslint-disable-next-line no-var var OSSettingsParentalControlsPageTest = class extends OSSettingsBrowserTest { /** @override */ @@ -1406,6 +1424,34 @@ }); // eslint-disable-next-line no-var +var OSSettingsLanguagesPageV2Test = class extends OSSettingsBrowserTest { + /** @override */ + get browsePreload() { + return super.browsePreload + + 'chromeos/os_languages_page/os_languages_page_v2.html'; + } + + /** @override */ + get extraLibraries() { + return super.extraLibraries.concat([ + BROWSER_SETTINGS_PATH + '../fake_chrome_event.js', + BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', + BROWSER_SETTINGS_PATH + 'fake_input_method_private.js', + BROWSER_SETTINGS_PATH + 'fake_language_settings_private.js', + BROWSER_SETTINGS_PATH + 'fake_settings_private.js', + BROWSER_SETTINGS_PATH + '../test_util.js', + 'os_languages_page_v2_tests.js', + 'test_os_languages_browser_proxy.js', + 'test_os_languages_metrics_proxy.js', + ]); + } +}; + +TEST_F('OSSettingsLanguagesPageV2Test', 'AllJsTests', () => { + mocha.run(); +}); + +// eslint-disable-next-line no-var var OSSettingsSmartInputsPageTest = class extends OSSettingsBrowserTest { /** @override */ get browsePreload() { @@ -1447,6 +1493,27 @@ mocha.run(); }); +// eslint-disable-next-line no-var +var OSSettingsInputPageTest = class extends OSSettingsBrowserTest { + /** @override */ + get browsePreload() { + return super.browsePreload + 'chromeos/os_language_page/input_page.html'; + } + + /** @override */ + get extraLibraries() { + return super.extraLibraries.concat([ + BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', + 'input_page_test.js', + 'test_os_languages_metrics_proxy.js', + ]); + } +}; + +TEST_F('OSSettingsInputPageTest', 'AllJsTests', () => { + mocha.run(); +}); + // Tests for the Reset section. // eslint-disable-next-line no-var var OSSettingsResetPageTest = class extends OSSettingsBrowserTest {
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index 5d556073..36d30a3 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -41,6 +41,7 @@ ['BluetoothPage', 'bluetooth_page_tests.m.js'], ['DateTimePage', 'date_time_page_tests.m.js'], ['InputMethodOptionPage', 'input_method_options_page_test.m.js'], + ['InputPage', 'input_page_test.m.js'], ['LocalizedLink', 'localized_link_test.m.js'], ['MultideviceFeatureItem', 'multidevice_feature_item_tests.m.js'], ['MultideviceFeatureToggle', 'multidevice_feature_toggle_tests.m.js'], @@ -48,6 +49,7 @@ ['MultideviceSmartLockSubPage', 'multidevice_smartlock_subpage_test.m.js'], ['MultideviceSubPage', 'multidevice_subpage_tests.m.js'], ['OsLanguagesPage', 'os_languages_page_tests.m.js'], + ['OsLanguagesPageV2', 'os_languages_page_v2_tests.m.js'], ['NearbyShareSubPage', 'nearby_share_subpage_tests.m.js'], ['ParentalControlsPage', 'parental_controls_page_test.m.js'], ['PeoplePage', 'os_people_page_test.m.js'], @@ -56,6 +58,8 @@ ['PeoplePageKerberosAccounts', 'people_page_kerberos_accounts_test.m.js'], ['PersonalizationPage', 'personalization_page_test.m.js'], ['PrivacyPage', 'os_privacy_page_test.m.js'], + ['SmbPage', 'smb_shares_page_tests.m.js'], + ['FilesPage', 'os_files_page_test.m.js'], ['ResetPage', 'os_reset_page_test.m.js'], ['SmartInputsPage', 'smart_inputs_page_test.m.js'], ['TimezoneSelector', 'timezone_selector_test.m.js'],
diff --git a/chrome/test/data/webui/settings/chromeos/smb_shares_page_tests.js b/chrome/test/data/webui/settings/chromeos/smb_shares_page_tests.js index fef64e1f..7f8e6de 100644 --- a/chrome/test/data/webui/settings/chromeos/smb_shares_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/smb_shares_page_tests.js
@@ -2,6 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// clang-format off +// #import 'chrome://os-settings/chromeos/lazy_load.js'; +// #import {TestBrowserProxy} from '../../test_browser_proxy.m.js'; +// #import {SmbMountResult, SmbBrowserProxyImpl} from 'chrome://os-settings/chromeos/lazy_load.js'; +// #import {assertEquals, assertFalse, assertNotEquals, assertTrue} from '../../chai_assert.js'; +// #import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {flushTasks} from 'chrome://test/test_util.m.js'; +// clang-format on + /** @implements {smb_shares.SmbBrowserProxy} */ class TestSmbBrowserProxy extends TestBrowserProxy { constructor() {
diff --git a/chrome/test/data/webui/settings/chromeos/test_os_languages_metrics_proxy.js b/chrome/test/data/webui/settings/chromeos/test_os_languages_metrics_proxy.js index 7929bc5b..74c48c16 100644 --- a/chrome/test/data/webui/settings/chromeos/test_os_languages_metrics_proxy.js +++ b/chrome/test/data/webui/settings/chromeos/test_os_languages_metrics_proxy.js
@@ -19,6 +19,7 @@ 'recordAddLanguages', 'recordManageInputMethods', 'recordToggleShowInputOptionsOnShelf', + 'recordToggleTranslate', ]); } @@ -41,6 +42,11 @@ recordToggleShowInputOptionsOnShelf(value) { this.methodCalled('recordToggleShowInputOptionsOnShelf', value); } + + /** @override */ + recordToggleTranslate(value) { + this.methodCalled('recordToggleTranslate', value); + } } // #cr_define_end return {
diff --git a/chrome/third_party/mock4js/README.chromium b/chrome/third_party/mock4js/README.chromium index fdf4eeb..4fedefa 100644 --- a/chrome/third_party/mock4js/README.chromium +++ b/chrome/third_party/mock4js/README.chromium
@@ -11,3 +11,4 @@ Local Modifications: * Replace a fail() call with throwing Mock4JSException. +* Changed `new Function()` call in order to avoid Trusted Types violation.
diff --git a/chrome/third_party/mock4js/mock4js.js b/chrome/third_party/mock4js/mock4js.js index 5cd02d5..fa62caf 100644 --- a/chrome/third_party/mock4js/mock4js.js +++ b/chrome/third_party/mock4js/mock4js.js
@@ -506,13 +506,15 @@ this._expectedInvocations = []; // setup proxy - var IntermediateClass = new Function(); + // TODO(crbug.com/1087743): Support Function constructor in Trusted Types + var IntermediateClass = (function(){}); IntermediateClass.prototype = mockedType.prototype; - var ChildClass = new Function(); + // TODO(crbug.com/1087743): Support Function constructor in Trusted Types + var ChildClass = (function(){}); ChildClass.prototype = new IntermediateClass(); this._proxy = new ChildClass(); this._proxy.mock = this; - + for(property in mockedType.prototype) { if(this._isPublicMethod(mockedType.prototype, property)) { var publicMethodName = property;
diff --git a/chromeos/BUILD.gn b/chromeos/BUILD.gn index dab95391..3ef6d63 100644 --- a/chromeos/BUILD.gn +++ b/chromeos/BUILD.gn
@@ -287,6 +287,9 @@ tast_test("chrome_all_tast_tests") { # To disable a specific test, add it the following list and cite a bug. tast_disabled_tests = [ + # crbug.com/1115622 + "ui.ChromeLoginGAIA", + # crbug.com/1097630 "security.OpenFDs",
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 840b9d3..a82be5d7 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -13399.0.0 \ No newline at end of file +13402.0.0 \ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/resources/src/js/state.js b/chromeos/components/camera_app_ui/resources/src/js/state.js index bd1281399..4f51dca 100644 --- a/chromeos/components/camera_app_ui/resources/src/js/state.js +++ b/chromeos/components/camera_app_ui/resources/src/js/state.js
@@ -24,6 +24,7 @@ GRID_GOLDEN: 'golden', GRID: 'grid', HAS_BACK_CAMERA: 'has-back-camera', + HAS_EXTERNAL_SCREEN: 'has-external-screen', HAS_FRONT_CAMERA: 'has-front-camera', MAX_WND: 'max-wnd', MIC: 'mic',
diff --git a/chromeos/components/camera_app_ui/resources/src/js/views/camera.js b/chromeos/components/camera_app_ui/resources/src/js/views/camera.js index 6003232..ae00443 100644 --- a/chromeos/components/camera_app_ui/resources/src/js/views/camera.js +++ b/chromeos/components/camera_app_ui/resources/src/js/views/camera.js
@@ -3,7 +3,7 @@ // found in the LICENSE file. import {browserProxy} from '../browser_proxy/browser_proxy.js'; -import {assert, assertInstanceof} from '../chrome_util.js'; +import {assert, assertInstanceof, promisify} from '../chrome_util.js'; import { PhotoConstraintsPreferrer, // eslint-disable-line no-unused-vars VideoConstraintsPreferrer, // eslint-disable-line no-unused-vars @@ -257,10 +257,6 @@ this.start(); } }); - - state.addObserver(state.State.SCREEN_OFF_AUTO, () => this.start()); - - this.configuring_ = null; } /** @@ -280,6 +276,34 @@ }; const screenState = await helper.initScreenStateMonitor(setScreenOffAuto); setScreenOffAuto(screenState); + + const updateExternalScreen = async () => { + const allInfo = await promisify(chrome.system.display.getInfo)( + {singleUnified: false}); + const hasExternalScreen = allInfo.some(({isInternal}) => !isInternal); + state.set(state.State.HAS_EXTERNAL_SCREEN, hasExternalScreen); + }; + await updateExternalScreen(); + chrome.system.display.onDisplayChanged.addListener(updateExternalScreen); + + const checkScreenOff = () => { + if (this.screenOff_) { + this.start(); + } + }; + + state.addObserver(state.State.SCREEN_OFF_AUTO, checkScreenOff); + state.addObserver(state.State.HAS_EXTERNAL_SCREEN, checkScreenOff); + } + + /** + * @return {boolean} If the App window is invisible to user with respect to + * screen off state. + * @private + */ + get screenOff_() { + return state.get(state.State.SCREEN_OFF_AUTO) && + !state.get(state.State.HAS_EXTERNAL_SCREEN); } /** @@ -305,8 +329,8 @@ */ isSuspended() { return this.locked_ || browserProxy.isMinimized() || - state.get(state.State.SUSPEND) || - state.get(state.State.SCREEN_OFF_AUTO) || this.isTabletBackground_(); + state.get(state.State.SUSPEND) || this.screenOff_ || + this.isTabletBackground_(); } /**
diff --git a/chromeos/components/camera_app_ui/resources/src/manifest.json b/chromeos/components/camera_app_ui/resources/src/manifest.json index 8d2f7a32..7797acc 100644 --- a/chromeos/components/camera_app_ui/resources/src/manifest.json +++ b/chromeos/components/camera_app_ui/resources/src/manifest.json
@@ -15,6 +15,7 @@ "videoCapture", "audioCapture", "storage", + "system.display", "unlimitedStorage", "chromeosInfoPrivate", "metricsPrivate",
diff --git a/chromeos/components/help_app_ui/help_app_untrusted_ui.cc b/chromeos/components/help_app_ui/help_app_untrusted_ui.cc index c3d2df7f..ab0c779 100644 --- a/chromeos/components/help_app_ui/help_app_untrusted_ui.cc +++ b/chromeos/components/help_app_ui/help_app_untrusted_ui.cc
@@ -26,6 +26,7 @@ source->SetDefaultResource(IDR_HELP_APP_APP_HTML); source->AddResourcePath("app_bin.js", IDR_HELP_APP_APP_BIN_JS); source->AddResourcePath("load_time_data.js", IDR_WEBUI_JS_LOAD_TIME_DATA); + source->DisableTrustedTypesCSP(); // Add all resources from chromeos_media_app_bundle.pak. for (size_t i = 0; i < kChromeosHelpAppBundleResourcesSize; i++) {
diff --git a/chromeos/components/media_app_ui/media_app_guest_ui.cc b/chromeos/components/media_app_ui/media_app_guest_ui.cc index e66ce85..af89a82 100644 --- a/chromeos/components/media_app_ui/media_app_guest_ui.cc +++ b/chromeos/components/media_app_ui/media_app_guest_ui.cc
@@ -60,6 +60,8 @@ // Allow styles to include inline styling needed for Polymer elements. source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::StyleSrc, "style-src 'unsafe-inline';"); + // TODO(crbug.com/1098685): Trusted Type remaining WebUI. + source->DisableTrustedTypesCSP(); return source; }
diff --git a/chromeos/components/media_app_ui/resources/js/launch.js b/chromeos/components/media_app_ui/resources/js/launch.js index b351e15..edd83bb 100644 --- a/chromeos/components/media_app_ui/resources/js/launch.js +++ b/chromeos/components/media_app_ui/resources/js/launch.js
@@ -57,8 +57,16 @@ */ const tokenMap = new Map(); -/** A pipe through which we can send messages to the guest frame. */ -const guestMessagePipe = new MessagePipe('chrome-untrusted://media-app'); +/** + * A pipe through which we can send messages to the guest frame. + * Use an undefined `target` to find the <iframe> automatically. + * Do not rethrow errors, since handlers installed here are expected to + * throw exceptions that are handled on the other side of the pipe. And + * nothing `awaits` async callHandlerForMessageType_(), so they will always + * be reported as `unhandledrejection` and trigger a crash report. + */ +const guestMessagePipe = + new MessagePipe('chrome-untrusted://media-app', undefined, false); /** * Promise that resolves once the iframe is ready to receive messages. This is
diff --git a/chromeos/components/phonehub/BUILD.gn b/chromeos/components/phonehub/BUILD.gn index 308be82..fd11876 100644 --- a/chromeos/components/phonehub/BUILD.gn +++ b/chromeos/components/phonehub/BUILD.gn
@@ -14,6 +14,8 @@ "feature_status_provider.h", "feature_status_provider_impl.cc", "feature_status_provider_impl.h", + "phone_hub_manager.cc", + "phone_hub_manager.h", ] deps = [ @@ -22,6 +24,7 @@ "//chromeos/components/multidevice/logging", "//chromeos/services/device_sync/public/cpp", "//chromeos/services/multidevice_setup/public/cpp", + "//components/keyed_service/core", "//device/bluetooth", ] }
diff --git a/chromeos/components/phonehub/DEPS b/chromeos/components/phonehub/DEPS index 8145cd9..ff54a29 100644 --- a/chromeos/components/phonehub/DEPS +++ b/chromeos/components/phonehub/DEPS
@@ -2,5 +2,6 @@ "+chromeos/components/multidevice", "+chromeos/services/device_sync/public/cpp", "+chromeos/services/multidevice_setup/public/cpp", + "+components/keyed_service/core/keyed_service.h", "+device/bluetooth", ]
diff --git a/chromeos/components/phonehub/feature_status.cc b/chromeos/components/phonehub/feature_status.cc index d4917f1..6267b65 100644 --- a/chromeos/components/phonehub/feature_status.cc +++ b/chromeos/components/phonehub/feature_status.cc
@@ -18,9 +18,6 @@ case FeatureStatus::kPhoneSelectedAndPendingSetup: stream << "[Phone selected and pending setup]"; break; - case FeatureStatus::kProhibitedByPolicy: - stream << "[Prohibited by policy]"; - break; case FeatureStatus::kDisabled: stream << "[Disabled]"; break;
diff --git a/chromeos/components/phonehub/feature_status.h b/chromeos/components/phonehub/feature_status.h index c37917b..e2a6855 100644 --- a/chromeos/components/phonehub/feature_status.h +++ b/chromeos/components/phonehub/feature_status.h
@@ -10,7 +10,10 @@ namespace chromeos { namespace phonehub { -// Enum representing potential status values for the Phone Hub feature. +// Enum representing potential status values for the Phone Hub feature. Note +// that there is no value representing "prohibited" - when the feature is +// prohibited by enterprise policy, we don't instantiate Phone Hub-related logic +// at all. enum class FeatureStatus { // The user's devices are not eligible for the feature. This means that either // the Chrome OS device or the user's phone (or both) have not enrolled with @@ -26,26 +29,23 @@ // server and with the phone itself. kPhoneSelectedAndPendingSetup = 2, - // An enterprise policy has prohibited this feature from running. - kProhibitedByPolicy = 3, - // The feature is disabled, but the user could enable it via settings. - kDisabled = 4, + kDisabled = 3, // The feature is enabled, but it is currently unavailable because Bluetooth // is disabled (the feature cannot run without Bluetooth). - kUnavailableBluetoothOff = 5, + kUnavailableBluetoothOff = 4, // The feature is enabled, but currently there is no active connection to // the phone. - kEnabledButDisconnected = 6, + kEnabledButDisconnected = 5, // The feature is enabled, and there is an active attempt to connect to the // phone. - kEnabledAndConnecting = 7, + kEnabledAndConnecting = 6, // The feature is enabled, and there is an active connection with the phone. - kEnabledAndConnected = 8 + kEnabledAndConnected = 7 }; std::ostream& operator<<(std::ostream& stream, FeatureStatus status); @@ -53,4 +53,4 @@ } // namespace phonehub } // namespace chromeos -#endif // CHROMEOS_CO MPONENTS_PHONEHUB_FEATURE_STATUS_H_ +#endif // CHROMEOS_COMPONENTS_PHONEHUB_FEATURE_STATUS_H_
diff --git a/chromeos/components/phonehub/feature_status_provider_impl.cc b/chromeos/components/phonehub/feature_status_provider_impl.cc index fea23f5..69451910 100644 --- a/chromeos/components/phonehub/feature_status_provider_impl.cc +++ b/chromeos/components/phonehub/feature_status_provider_impl.cc
@@ -28,7 +28,16 @@ bool IsEligibleForFeature( const base::Optional<multidevice::RemoteDeviceRef>& local_device, - const RemoteDeviceRefList& remote_devices) { + const RemoteDeviceRefList& remote_devices, + FeatureState feature_state) { + // If the feature is prohibited by policy, we don't initialize Phone Hub + // classes at all. But, there is an edge case where a user session starts up + // normally, then an administrator prohibits the policy during the user + // session. If this occurs, we consider the session ineligible for using Phone + // Hub. + if (feature_state == FeatureState::kProhibitedByPolicy) + return false; + // If the local device has not yet been enrolled, no phone can serve as its // Phone Hub host. if (!local_device) @@ -65,7 +74,7 @@ continue; return true; - }; + } // If none of the devices return true above, there are no phones capable of // Phone Hub connections on the account. @@ -185,8 +194,12 @@ } FeatureStatus FeatureStatusProviderImpl::ComputeStatus() { + FeatureState feature_state = + multidevice_setup_client_->GetFeatureState(Feature::kPhoneHub); + if (!IsEligibleForFeature(device_sync_client_->GetLocalDeviceMetadata(), - device_sync_client_->GetSyncedDevices())) { + device_sync_client_->GetSyncedDevices(), + feature_state)) { return FeatureStatus::kNotEligibleForFeature; } @@ -195,15 +208,9 @@ if (host_status == HostStatus::kEligibleHostExistsButNoHostSet) return FeatureStatus::kEligiblePhoneButNotSetUp; - FeatureState feature_state = - multidevice_setup_client_->GetFeatureState(Feature::kPhoneHub); - if (IsPhonePendingSetup(host_status, feature_state)) return FeatureStatus::kPhoneSelectedAndPendingSetup; - if (feature_state == FeatureState::kProhibitedByPolicy) - return FeatureStatus::kProhibitedByPolicy; - if (IsFeatureDisabledByUser(feature_state)) return FeatureStatus::kDisabled;
diff --git a/chromeos/components/phonehub/feature_status_provider_impl_unittest.cc b/chromeos/components/phonehub/feature_status_provider_impl_unittest.cc index 1aab330..b45be18 100644 --- a/chromeos/components/phonehub/feature_status_provider_impl_unittest.cc +++ b/chromeos/components/phonehub/feature_status_provider_impl_unittest.cc
@@ -259,13 +259,13 @@ // Set all properties to true so that there is an eligible phone. Since // |fake_multidevice_setup_client_| defaults to kProhibitedByPolicy, the - // status should change to this default. + // status should still be kNotEligibleForFeature. SetSyncedDevices(CreateLocalDevice(/*supports_phone_hub_client=*/true, /*has_bluetooth_address=*/true), CreatePhoneDevice(/*supports_better_together_host=*/true, /*supports_phone_hub_host=*/true, /*has_bluetooth_address=*/true)); - EXPECT_EQ(FeatureStatus::kProhibitedByPolicy, GetStatus()); + EXPECT_EQ(FeatureStatus::kNotEligibleForFeature, GetStatus()); } TEST_F(FeatureStatusProviderImplTest, EligiblePhoneButNotSetUp) { @@ -292,14 +292,6 @@ EXPECT_EQ(FeatureStatus::kPhoneSelectedAndPendingSetup, GetStatus()); } -TEST_F(FeatureStatusProviderImplTest, ProhibitedByPolicy) { - SetEligibleSyncedDevices(); - - SetMultiDeviceState(HostStatus::kHostVerified, - FeatureState::kProhibitedByPolicy); - EXPECT_EQ(FeatureStatus::kProhibitedByPolicy, GetStatus()); -} - TEST_F(FeatureStatusProviderImplTest, Disabled) { SetEligibleSyncedDevices(); @@ -346,23 +338,18 @@ EXPECT_EQ(FeatureStatus::kPhoneSelectedAndPendingSetup, GetStatus()); EXPECT_EQ(2u, GetNumObserverCalls()); - SetMultiDeviceState(HostStatus::kHostVerified, - FeatureState::kProhibitedByPolicy); - EXPECT_EQ(FeatureStatus::kProhibitedByPolicy, GetStatus()); - EXPECT_EQ(3u, GetNumObserverCalls()); - SetMultiDeviceState(HostStatus::kHostVerified, FeatureState::kDisabledByUser); EXPECT_EQ(FeatureStatus::kDisabled, GetStatus()); - EXPECT_EQ(4u, GetNumObserverCalls()); + EXPECT_EQ(3u, GetNumObserverCalls()); SetAdapterPoweredState(false); SetMultiDeviceState(HostStatus::kHostVerified, FeatureState::kEnabledByUser); EXPECT_EQ(FeatureStatus::kUnavailableBluetoothOff, GetStatus()); - EXPECT_EQ(5u, GetNumObserverCalls()); + EXPECT_EQ(4u, GetNumObserverCalls()); SetAdapterPoweredState(true); EXPECT_EQ(FeatureStatus::kEnabledButDisconnected, GetStatus()); - EXPECT_EQ(6u, GetNumObserverCalls()); + EXPECT_EQ(5u, GetNumObserverCalls()); } } // namespace phonehub
diff --git a/chromeos/components/phonehub/phone_hub_manager.cc b/chromeos/components/phonehub/phone_hub_manager.cc new file mode 100644 index 0000000..fd791618 --- /dev/null +++ b/chromeos/components/phonehub/phone_hub_manager.cc
@@ -0,0 +1,42 @@ +// 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 "chromeos/components/phonehub/phone_hub_manager.h" + +#include "base/callback.h" +#include "base/no_destructor.h" +#include "chromeos/components/phonehub/feature_status_provider_impl.h" + +namespace chromeos { +namespace phonehub { +namespace { +PhoneHubManager* g_instance = nullptr; +} // namespace + +// static +PhoneHubManager* PhoneHubManager::Get() { + return g_instance; +} + +PhoneHubManager::PhoneHubManager( + device_sync::DeviceSyncClient* device_sync_client, + multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client) + : feature_status_provider_(std::make_unique<FeatureStatusProviderImpl>( + device_sync_client, + multidevice_setup_client)) { + DCHECK(!g_instance); + g_instance = this; +} + +PhoneHubManager::~PhoneHubManager() = default; + +void PhoneHubManager::Shutdown() { + DCHECK(g_instance); + g_instance = nullptr; + + feature_status_provider_.reset(); +} + +} // namespace phonehub +} // namespace chromeos
diff --git a/chromeos/components/phonehub/phone_hub_manager.h b/chromeos/components/phonehub/phone_hub_manager.h new file mode 100644 index 0000000..bb77c97a --- /dev/null +++ b/chromeos/components/phonehub/phone_hub_manager.h
@@ -0,0 +1,60 @@ +// 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 CHROMEOS_COMPONENTS_PHONEHUB_PHONE_HUB_MANAGER_H_ +#define CHROMEOS_COMPONENTS_PHONEHUB_PHONE_HUB_MANAGER_H_ + +#include <memory> + +#include "base/callback_forward.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace chromeos { + +namespace device_sync { +class DeviceSyncClient; +} // namespace device_sync + +namespace multidevice_setup { +class MultiDeviceSetupClient; +} // namespace multidevice_setup + +namespace phonehub { + +class FeatureStatusProvider; + +// Implements the core logic of the Phone Hub feature and exposes interfaces via +// its public API. Implemented as a KeyedService which is keyed by the primary +// Profile; since there is only one primary Profile, the class is intended to be +// a singleton. +class PhoneHubManager : public KeyedService { + public: + // Returns a pointer to the singleton once it has been instantiated. Returns + // null if the primary profile has not yet been initialized or has already + // shut down, if the kPhoneHub flag is disabled, or if the feature is + // prohibited by policy. + static PhoneHubManager* Get(); + + PhoneHubManager( + device_sync::DeviceSyncClient* device_sync_client, + multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client); + PhoneHubManager(const PhoneHubManager&) = delete; + PhoneHubManager& operator=(const PhoneHubManager&) = delete; + ~PhoneHubManager() override; + + FeatureStatusProvider* feature_status_provider() { + return feature_status_provider_.get(); + } + + private: + // KeyedService: + void Shutdown() override; + + std::unique_ptr<FeatureStatusProvider> feature_status_provider_; +}; + +} // namespace phonehub +} // namespace chromeos + +#endif // CHROMEOS_COMPONENTS_PHONEHUB_PHONE_HUB_MANAGER_H_
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 15ae950..35f7362 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -215,7 +215,11 @@ // Enables new ZIP archive handling in Files App. // https://crbug.com/912236 -const base::Feature kFilesZipNoNaCl{"FilesZipNoNaCl", +const base::Feature kFilesZipMount{"FilesZipMount", + base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kFilesZipPack{"FilesZipPack", + base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kFilesZipUnpack{"FilesZipUnpack", base::FEATURE_DISABLED_BY_DEFAULT}; // Enables the use of Mojo by Chrome-process code to communicate with Power
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index 1ea21d36..a9fc225 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -97,7 +97,9 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kFilesSWA; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kFilesTransferDetails; -COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kFilesZipNoNaCl; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kFilesZipMount; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kFilesZipPack; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kFilesZipUnpack; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kMojoDBusRelay; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kClipboardHistory;
diff --git a/chromeos/crosapi/cpp/BUILD.gn b/chromeos/crosapi/cpp/BUILD.gn index 6275567d..08943efe 100644 --- a/chromeos/crosapi/cpp/BUILD.gn +++ b/chromeos/crosapi/cpp/BUILD.gn
@@ -10,8 +10,8 @@ component("cpp") { output_name = "crosapi_public_cpp" sources = [ - "window_snapshot.cc", - "window_snapshot.h", + "bitmap.cc", + "bitmap.h", ] configs += [ ":crosapi_implementation" ] deps = [ "//base" ]
diff --git a/chromeos/crosapi/cpp/window_snapshot.cc b/chromeos/crosapi/cpp/bitmap.cc similarity index 60% rename from chromeos/crosapi/cpp/window_snapshot.cc rename to chromeos/crosapi/cpp/bitmap.cc index 947ed42..edd512e 100644 --- a/chromeos/crosapi/cpp/window_snapshot.cc +++ b/chromeos/crosapi/cpp/bitmap.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chromeos/crosapi/cpp/window_snapshot.h" +#include "chromeos/crosapi/cpp/bitmap.h" namespace crosapi { -WindowSnapshot::WindowSnapshot() = default; -WindowSnapshot::~WindowSnapshot() = default; +Bitmap::Bitmap() = default; +Bitmap::~Bitmap() = default; } // namespace crosapi
diff --git a/chromeos/crosapi/cpp/bitmap.h b/chromeos/crosapi/cpp/bitmap.h new file mode 100644 index 0000000..7891b86 --- /dev/null +++ b/chromeos/crosapi/cpp/bitmap.h
@@ -0,0 +1,28 @@ +// 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 CHROMEOS_CROSAPI_CPP_BITMAP_H_ +#define CHROMEOS_CROSAPI_CPP_BITMAP_H_ + +#include <stdint.h> + +#include <vector> + +#include "base/component_export.h" + +namespace crosapi { + +// A 4-byte RGBA bitmap representation. Its size must be exactly equal to +// width * height * 4. +struct COMPONENT_EXPORT(CROSAPI) Bitmap { + Bitmap(); + ~Bitmap(); + uint32_t width = 0; + uint32_t height = 0; + std::vector<uint8_t> pixels; +}; + +} // namespace crosapi + +#endif // CHROMEOS_CROSAPI_CPP_BITMAP_H_
diff --git a/chromeos/crosapi/cpp/window_snapshot.h b/chromeos/crosapi/cpp/window_snapshot.h deleted file mode 100644 index 7c93230..0000000 --- a/chromeos/crosapi/cpp/window_snapshot.h +++ /dev/null
@@ -1,28 +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 CHROMEOS_CROSAPI_CPP_WINDOW_SNAPSHOT_H_ -#define CHROMEOS_CROSAPI_CPP_WINDOW_SNAPSHOT_H_ - -#include <stdint.h> - -#include <vector> - -#include "base/component_export.h" - -namespace crosapi { - -// bitmap is a 4-byte RGBA bitmap representation of the window. Its size must -// be exactly equal to width * height * 4. -struct COMPONENT_EXPORT(CROSAPI) WindowSnapshot { - WindowSnapshot(); - ~WindowSnapshot(); - uint32_t width = 0; - uint32_t height = 0; - std::vector<uint8_t> bitmap; -}; - -} // namespace crosapi - -#endif // CHROMEOS_CROSAPI_CPP_WINDOW_SNAPSHOT_H_
diff --git a/chromeos/crosapi/mojom/BUILD.gn b/chromeos/crosapi/mojom/BUILD.gn index 9701a5e0..0988d0d 100644 --- a/chromeos/crosapi/mojom/BUILD.gn +++ b/chromeos/crosapi/mojom/BUILD.gn
@@ -6,6 +6,8 @@ mojom("mojom") { sources = [ + "attestation.mojom", + "bitmap.mojom", "crosapi.mojom", "screen_manager.mojom", "select_file.mojom", @@ -15,12 +17,11 @@ { types = [ { - mojom = "crosapi.mojom.WindowSnapshot" - cpp = "crosapi::WindowSnapshot" + mojom = "crosapi.mojom.Bitmap" + cpp = "crosapi::Bitmap" }, ] - traits_headers = - [ "//chromeos/crosapi/mojom/window_snapshot_mojom_traits.h" ] + traits_headers = [ "//chromeos/crosapi/mojom/bitmap_mojom_traits.h" ] traits_public_deps = [ ":mojom_traits", "//chromeos/crosapi/cpp", @@ -38,8 +39,8 @@ output_name = "crosapi_mojom_traits" sources = [ - "window_snapshot_mojom_traits.cc", - "window_snapshot_mojom_traits.h", + "bitmap_mojom_traits.cc", + "bitmap_mojom_traits.h", ] defines = [ "IS_CROSAPI_MOJOM_TRAITS_IMPL" ]
diff --git a/chromeos/crosapi/mojom/attestation.mojom b/chromeos/crosapi/mojom/attestation.mojom new file mode 100644 index 0000000..eb8b1fd --- /dev/null +++ b/chromeos/crosapi/mojom/attestation.mojom
@@ -0,0 +1,31 @@ +// 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 crosapi.mojom; + +[Extensible] +enum ChallengeKeyType { + // The challenge is attested by keys belonging to the current user. + kUser = 0, + + // The challenge is attested by keys belonging to the device. + kDevice = 1, +}; + +union ChallengeKeyResult { + // Implies failure. + string error_message; + + // Implies success. + string challenge_response; +}; + +// This interface is implemented by ash-chrome. It provides lacros-chrome a +// mechanism to use the system keystore to attest challenges. +interface Attestation { + // Requests that the OS keystore attest a challenge. + ChallengeKey@0(string challenge, ChallengeKeyType type) => + (ChallengeKeyResult result); +}; +
diff --git a/chromeos/crosapi/mojom/bitmap.mojom b/chromeos/crosapi/mojom/bitmap.mojom new file mode 100644 index 0000000..134666ea --- /dev/null +++ b/chromeos/crosapi/mojom/bitmap.mojom
@@ -0,0 +1,13 @@ +// 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 crosapi.mojom; + +// Each pixel is represented by 4 bytes [RGBA]. +// TODO(https://crbug.com/1094460): Use a more performant transport mechanism. +struct Bitmap { + uint32 width; + uint32 height; + array<uint8> pixels; +};
diff --git a/chromeos/crosapi/mojom/bitmap_mojom_traits.cc b/chromeos/crosapi/mojom/bitmap_mojom_traits.cc new file mode 100644 index 0000000..be03040 --- /dev/null +++ b/chromeos/crosapi/mojom/bitmap_mojom_traits.cc
@@ -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. + +#include "chromeos/crosapi/mojom/bitmap_mojom_traits.h" + +#include "base/numerics/checked_math.h" + +namespace mojo { + +// static +bool StructTraits<crosapi::mojom::BitmapDataView, crosapi::Bitmap>::Read( + crosapi::mojom::BitmapDataView data, + crosapi::Bitmap* out) { + out->width = data.width(); + out->height = data.height(); + + ArrayDataView<uint8_t> pixels; + data.GetPixelsDataView(&pixels); + + uint32_t size; + size = base::CheckMul(out->width, out->height).ValueOrDie(); + size = base::CheckMul(size, 4).ValueOrDie(); + + if (pixels.size() != base::checked_cast<size_t>(size)) + return false; + + const uint8_t* base = pixels.data(); + out->pixels.assign(base, base + pixels.size()); + return true; +} + +} // namespace mojo
diff --git a/chromeos/crosapi/mojom/bitmap_mojom_traits.h b/chromeos/crosapi/mojom/bitmap_mojom_traits.h new file mode 100644 index 0000000..b3f5263c --- /dev/null +++ b/chromeos/crosapi/mojom/bitmap_mojom_traits.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 CHROMEOS_CROSAPI_MOJOM_BITMAP_MOJOM_TRAITS_H_ +#define CHROMEOS_CROSAPI_MOJOM_BITMAP_MOJOM_TRAITS_H_ + +#include "base/component_export.h" +#include "chromeos/crosapi/cpp/bitmap.h" +#include "chromeos/crosapi/mojom/bitmap.mojom-shared.h" +#include "mojo/public/cpp/bindings/struct_traits.h" + +namespace mojo { + +template <> +struct COMPONENT_EXPORT(CROSAPI_MOJOM_TRAITS) + StructTraits<crosapi::mojom::BitmapDataView, crosapi::Bitmap> { + static uint32_t width(const crosapi::Bitmap& bitmap) { return bitmap.width; } + static uint32_t height(const crosapi::Bitmap& bitmap) { + return bitmap.height; + } + static const std::vector<uint8_t>& pixels(const crosapi::Bitmap& bitmap) { + return bitmap.pixels; + } + static bool Read(crosapi::mojom::BitmapDataView, crosapi::Bitmap* out); +}; + +} // namespace mojo + +#endif // CHROMEOS_CROSAPI_MOJOM_BITMAP_MOJOM_TRAITS_H_
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom index 73bbfcf2..858994df 100644 --- a/chromeos/crosapi/mojom/crosapi.mojom +++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -4,12 +4,16 @@ module crosapi.mojom; +import "chromeos/crosapi/mojom/attestation.mojom"; import "chromeos/crosapi/mojom/screen_manager.mojom"; import "chromeos/crosapi/mojom/select_file.mojom"; // AshChromeService defines the APIs that live in ash-chrome and are // accessed from lacros-chrome. interface AshChromeService { + // Binds the Attestation interface for challenging keys. + BindAttestation@2(pending_receiver<Attestation> receiver); + // Binds the ScreenManager interface for interacting with windows, screens and // displays. BindScreenManager@1(pending_receiver<ScreenManager> receiver);
diff --git a/chromeos/crosapi/mojom/screen_manager.mojom b/chromeos/crosapi/mojom/screen_manager.mojom index d49dadb5..4e1b2d8 100644 --- a/chromeos/crosapi/mojom/screen_manager.mojom +++ b/chromeos/crosapi/mojom/screen_manager.mojom
@@ -4,6 +4,8 @@ module crosapi.mojom; +import "chromeos/crosapi/mojom/bitmap.mojom"; + // A unique identifier and title for a window. struct WindowDetails { // Guaranteed to be unique and never reused. @@ -13,14 +15,6 @@ string title; }; -// A bitmap representation of the current contents of a window or screen. Each -// pixel is represented by 4 bytes [RGBA]. -struct WindowSnapshot { - uint32 width; - uint32 height; - array<uint8> bitmap; -}; - // This interface is implemented by ash-chrome. It allows lacros-chrome to query // information about existing windows, screens, and displays. // @@ -45,7 +39,7 @@ // The media screen capture implementation assumes that every platform // provides a synchronous method to take a snapshot of the screen. [Sync] - TakeScreenSnapshot@0() => (WindowSnapshot snapshot); + TakeScreenSnapshot@0() => (Bitmap snapshot); // Synchronously returns a list of visible, focusable windows. This method // needs to be synchronous to support cross-platform code that relies on the @@ -56,6 +50,5 @@ // Take a screenshot of a window with an id from ListWindows. If |success| // is false, then the window no longer exists. [Sync] - TakeWindowSnapshot@2(uint64 id) => (bool success, WindowSnapshot snapshot); + TakeWindowSnapshot@2(uint64 id) => (bool success, Bitmap snapshot); }; -
diff --git a/chromeos/crosapi/mojom/window_snapshot_mojom_traits.cc b/chromeos/crosapi/mojom/window_snapshot_mojom_traits.cc deleted file mode 100644 index 59c4d2a..0000000 --- a/chromeos/crosapi/mojom/window_snapshot_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 "chromeos/crosapi/mojom/window_snapshot_mojom_traits.h" - -#include "base/numerics/checked_math.h" - -namespace mojo { - -// static -bool StructTraits< - crosapi::mojom::WindowSnapshotDataView, - crosapi::WindowSnapshot>::Read(crosapi::mojom::WindowSnapshotDataView data, - crosapi::WindowSnapshot* out) { - out->width = data.width(); - out->height = data.height(); - - ArrayDataView<uint8_t> bitmap; - data.GetBitmapDataView(&bitmap); - - uint32_t size; - size = base::CheckMul(out->width, out->height).ValueOrDie(); - size = base::CheckMul(size, 4).ValueOrDie(); - - if (bitmap.size() != base::checked_cast<size_t>(size)) - return false; - - const uint8_t* base = bitmap.data(); - out->bitmap.assign(base, base + bitmap.size()); - return true; -} - -} // namespace mojo
diff --git a/chromeos/crosapi/mojom/window_snapshot_mojom_traits.h b/chromeos/crosapi/mojom/window_snapshot_mojom_traits.h deleted file mode 100644 index 9a3d449b..0000000 --- a/chromeos/crosapi/mojom/window_snapshot_mojom_traits.h +++ /dev/null
@@ -1,35 +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 CHROMEOS_CROSAPI_MOJOM_WINDOW_SNAPSHOT_MOJOM_TRAITS_H_ -#define CHROMEOS_CROSAPI_MOJOM_WINDOW_SNAPSHOT_MOJOM_TRAITS_H_ - -#include "base/component_export.h" -#include "chromeos/crosapi/cpp/window_snapshot.h" -#include "chromeos/crosapi/mojom/screen_manager.mojom-shared.h" -#include "mojo/public/cpp/bindings/struct_traits.h" - -namespace mojo { - -template <> -struct COMPONENT_EXPORT(CROSAPI_MOJOM_TRAITS) - StructTraits<crosapi::mojom::WindowSnapshotDataView, - crosapi::WindowSnapshot> { - static uint32_t width(const crosapi::WindowSnapshot& snapshot) { - return snapshot.width; - } - static uint32_t height(const crosapi::WindowSnapshot& snapshot) { - return snapshot.height; - } - static const std::vector<uint8_t>& bitmap( - const crosapi::WindowSnapshot& snapshot) { - return snapshot.bitmap; - } - static bool Read(crosapi::mojom::WindowSnapshotDataView, - crosapi::WindowSnapshot* out); -}; - -} // namespace mojo - -#endif // CHROMEOS_CROSAPI_MOJOM_WINDOW_SNAPSHOT_MOJOM_TRAITS_H_
diff --git a/chromeos/lacros/lacros_chrome_service_impl.cc b/chromeos/lacros/lacros_chrome_service_impl.cc index e0f9857..0554474a 100644 --- a/chromeos/lacros/lacros_chrome_service_impl.cc +++ b/chromeos/lacros/lacros_chrome_service_impl.cc
@@ -89,6 +89,12 @@ ash_chrome_service_->BindScreenManager(std::move(pending_receiver)); } + void BindAttestationReceiver( + mojo::PendingReceiver<crosapi::mojom::Attestation> pending_receiver) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + ash_chrome_service_->BindAttestation(std::move(pending_receiver)); + } + base::WeakPtr<LacrosChromeServiceNeverBlockingState> GetWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -158,6 +164,15 @@ &LacrosChromeServiceNeverBlockingState::BindSelectFileReceiver, weak_sequenced_state_, std::move(select_file_pending_receiver))); + mojo::PendingReceiver<crosapi::mojom::Attestation> + attestation_pending_receiver = + attestation_remote_.BindNewPipeAndPassReceiver(); + never_blocking_sequence_->PostTask( + FROM_HERE, + base::BindOnce( + &LacrosChromeServiceNeverBlockingState::BindAttestationReceiver, + weak_sequenced_state_, std::move(attestation_pending_receiver))); + DCHECK(!g_instance); g_instance = this; }
diff --git a/chromeos/lacros/lacros_chrome_service_impl.h b/chromeos/lacros/lacros_chrome_service_impl.h index b639e7a..0d0e0ac 100644 --- a/chromeos/lacros/lacros_chrome_service_impl.h +++ b/chromeos/lacros/lacros_chrome_service_impl.h
@@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/sequenced_task_runner.h" +#include "chromeos/crosapi/mojom/attestation.mojom.h" #include "chromeos/crosapi/mojom/crosapi.mojom.h" #include "chromeos/crosapi/mojom/screen_manager.mojom.h" #include "chromeos/crosapi/mojom/select_file.mojom.h" @@ -70,6 +71,13 @@ return select_file_remote_; } + // This must be called on the affine sequence. It exposes a remote that can + // be used to perform attestation on challenges. + mojo::Remote<crosapi::mojom::Attestation>& attestation_remote() { + DCHECK_CALLED_ON_VALID_SEQUENCE(affine_sequence_checker_); + return attestation_remote_; + } + // This may be called on any thread. void BindScreenManagerReceiver( mojo::PendingReceiver<crosapi::mojom::ScreenManager> pending_receiver); @@ -91,6 +99,11 @@ // constructor and it is immediately available for use. mojo::Remote<crosapi::mojom::SelectFile> select_file_remote_; + // This member allows lacros-chrome to use the Attestation interface. This + // member is affine to the affine sequence. It is initialized in the + // constructor and it is immediately available for use. + mojo::Remote<crosapi::mojom::Attestation> attestation_remote_; + // This member is instantiated on the affine sequence alongside the // constructor. All subsequent invocations of this member, including // destruction, happen on the |never_blocking_sequence_|.
diff --git a/components/arc/OWNERS b/components/arc/OWNERS index d2b9a64..30b8279 100644 --- a/components/arc/OWNERS +++ b/components/arc/OWNERS
@@ -1,6 +1,6 @@ hidehiko@chromium.org +jhorwich@chromium.org +yhanada@chromium.org yusukes@chromium.org -# backup reviewer -elijahtaylor@chromium.org # COMPONENT: Platform>Apps>ARC
diff --git a/components/background_task_scheduler/internal/BUILD.gn b/components/background_task_scheduler/internal/BUILD.gn index 68ee6999..1ce3ec4b 100644 --- a/components/background_task_scheduler/internal/BUILD.gn +++ b/components/background_task_scheduler/internal/BUILD.gn
@@ -36,7 +36,7 @@ "//components/background_task_scheduler:public_java", "//content/public/android:content_java", "//third_party/android_deps:androidx_annotation_annotation_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", + "//third_party/android_deps:protobuf_lite_runtime_java", ] }
diff --git a/components/browser_ui/client_certificate/android/java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequest.java b/components/browser_ui/client_certificate/android/java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequest.java index 800cf88..7778c53 100644 --- a/components/browser_ui/client_certificate/android/java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequest.java +++ b/components/browser_ui/client_certificate/android/java/src/org/chromium/components/browser_ui/client_certificate/SSLClientCertificateRequest.java
@@ -12,12 +12,12 @@ import android.security.KeyChain; import android.security.KeyChainAliasCallback; import android.security.KeyChainException; -import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; import org.chromium.base.ContextUtils; +import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; @@ -46,7 +46,7 @@ */ @JNINamespace("browser_ui") public class SSLClientCertificateRequest { - static final String TAG = "SSLClientCertificateRequest"; + static final String TAG = "SSLClientCertRequest"; /** * Implementation for anynchronous task of handling the certificate request. This @@ -146,6 +146,7 @@ private static class KeyChainCertSelectionCallback implements KeyChainAliasCallback { private final long mNativePtr; private final Context mContext; + private boolean mAliasCalled; KeyChainCertSelectionCallback(Context context, long nativePtr) { mContext = context; @@ -154,6 +155,12 @@ @Override public void alias(final String alias) { + if (mAliasCalled) { + Log.w(TAG, "KeyChainCertSelectionCallback called more than once ('" + alias + "')"); + return; + } + mAliasCalled = true; + // This is called by KeyChainActivity in a background thread. Post task to // handle the certificate selection on the UI thread. PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> {
diff --git a/components/cloud_devices/common/cloud_devices_urls.cc b/components/cloud_devices/common/cloud_devices_urls.cc index b08cc6f0..6d06774 100644 --- a/components/cloud_devices/common/cloud_devices_urls.cc +++ b/components/cloud_devices/common/cloud_devices_urls.cc
@@ -16,6 +16,13 @@ const char kCloudPrintAuthScope[] = "https://www.googleapis.com/auth/cloudprint"; +const char kCloudPrintDeprecationHelpURL[] = +#if defined(OS_CHROMEOS) + "https://www.google.com/chromebook/?p=cloudprint"; +#else + "https://www.google.com/chrome/?p=cloudprint"; +#endif + const char kCloudPrintLearnMoreURL[] = "https://www.google.com/support/cloudprint"; @@ -58,15 +65,6 @@ return url.ReplaceComponents(replacements); } -GURL GetCloudPrintSigninURL() { - GURL url(GaiaUrls::GetInstance()->service_login_url()); - url = net::AppendQueryParameter(url, "service", "cloudprint"); - url = net::AppendQueryParameter(url, "sarp", "1"); - std::string continue_str = GetCloudPrintURL().spec(); - url = net::AppendQueryParameter(url, "continue", continue_str); - return url; -} - GURL GetCloudPrintAddAccountURL() { GURL url(GaiaUrls::GetInstance()->add_account_url()); url = net::AppendQueryParameter(url, "service", "cloudprint"); @@ -76,14 +74,6 @@ return url; } -bool IsCloudPrintURL(const GURL& url) { - const GURL& cloud_print_url = GetCloudPrintURL(); - return url.host_piece() == cloud_print_url.host_piece() && - url.scheme_piece() == cloud_print_url.scheme_piece() && - base::StartsWith(url.path(), cloud_print_url.path(), - base::CompareCase::SENSITIVE); -} - GURL GetCloudPrintEnableURL(const std::string& proxy_id) { GURL url = GetCloudPrintRelativeURL("enable_chrome_connector/enable.html"); url = net::AppendQueryParameter(url, "proxy", proxy_id); @@ -105,4 +95,27 @@ return GetCloudPrintURL().ReplaceComponents(replacements); } +GURL GetCloudPrintPrintersURL() { + GURL::Replacements replacements; + replacements.SetRefStr("printers"); + return GetCloudPrintURL().ReplaceComponents(replacements); +} + +GURL GetCloudPrintSigninURL() { + GURL url(GaiaUrls::GetInstance()->service_login_url()); + url = net::AppendQueryParameter(url, "service", "cloudprint"); + url = net::AppendQueryParameter(url, "sarp", "1"); + std::string continue_str = GetCloudPrintURL().spec(); + url = net::AppendQueryParameter(url, "continue", continue_str); + return url; +} + +bool IsCloudPrintURL(const GURL& url) { + const GURL& cloud_print_url = GetCloudPrintURL(); + return url.host_piece() == cloud_print_url.host_piece() && + url.scheme_piece() == cloud_print_url.scheme_piece() && + base::StartsWith(url.path(), cloud_print_url.path(), + base::CompareCase::SENSITIVE); +} + } // namespace cloud_devices
diff --git a/components/cloud_devices/common/cloud_devices_urls.h b/components/cloud_devices/common/cloud_devices_urls.h index 6cb761ac..d1818fe 100644 --- a/components/cloud_devices/common/cloud_devices_urls.h +++ b/components/cloud_devices/common/cloud_devices_urls.h
@@ -12,16 +12,18 @@ namespace cloud_devices { extern const char kCloudPrintAuthScope[]; +extern const char kCloudPrintDeprecationHelpURL[]; extern const char kCloudPrintLearnMoreURL[]; extern const char kCloudPrintTestPageURL[]; GURL GetCloudPrintURL(); GURL GetCloudPrintRelativeURL(const std::string& relative_path); +GURL GetCloudPrintAddAccountURL(); GURL GetCloudPrintEnableURL(const std::string& proxy_id); GURL GetCloudPrintEnableWithSigninURL(const std::string& proxy_id); GURL GetCloudPrintManageDeviceURL(const std::string& device_id); +GURL GetCloudPrintPrintersURL(); GURL GetCloudPrintSigninURL(); -GURL GetCloudPrintAddAccountURL(); bool IsCloudPrintURL(const GURL& url); } // namespace cloud_devices
diff --git a/components/consent_auditor/consent_auditor.h b/components/consent_auditor/consent_auditor.h index 8914fa7..59043f0 100644 --- a/components/consent_auditor/consent_auditor.h +++ b/components/consent_auditor/consent_auditor.h
@@ -5,15 +5,13 @@ #ifndef COMPONENTS_CONSENT_AUDITOR_CONSENT_AUDITOR_H_ #define COMPONENTS_CONSENT_AUDITOR_CONSENT_AUDITOR_H_ -#include <memory> #include <string> -#include <utility> -#include <vector> #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/sync/model/model_type_sync_bridge.h" +#include "components/sync/model/model_type_controller_delegate.h" +#include "components/sync/protocol/user_consent_types.pb.h" #include "google_apis/gaia/core_account_id.h" namespace consent_auditor { @@ -82,6 +80,12 @@ const sync_pb::UserConsentTypes::AssistantActivityControlConsent& consent) = 0; + // Records the |consent| to download and use passwords from the signed-in GAIA + // account with the ID |account_id| (as defined in AccountInfo). + virtual void RecordAccountPasswordsConsent( + const CoreAccountId& account_id, + const sync_pb::UserConsentTypes::AccountPasswordsConsent& consent) = 0; + // Records that the user consented to a |feature|. The user was presented with // |description_text| and accepted it by interacting |confirmation_text| // (e.g. clicking on a button; empty if not applicable).
diff --git a/components/consent_auditor/consent_auditor_impl.cc b/components/consent_auditor/consent_auditor_impl.cc index 74dacdb..3148dac 100644 --- a/components/consent_auditor/consent_auditor_impl.cc +++ b/components/consent_auditor/consent_auditor_impl.cc
@@ -131,6 +131,16 @@ consent_sync_bridge_->RecordConsent(std::move(specifics)); } +void ConsentAuditorImpl::RecordAccountPasswordsConsent( + const CoreAccountId& account_id, + const sync_pb::UserConsentTypes::AccountPasswordsConsent& consent) { + std::unique_ptr<sync_pb::UserConsentSpecifics> specifics = + CreateUserConsentSpecifics(account_id, app_locale_, clock_); + specifics->mutable_account_passwords_consent()->CopyFrom(consent); + + consent_sync_bridge_->RecordConsent(std::move(specifics)); +} + void ConsentAuditorImpl::RecordLocalConsent( const std::string& feature, const std::string& description_text,
diff --git a/components/consent_auditor/consent_auditor_impl.h b/components/consent_auditor/consent_auditor_impl.h index f8a66f8..7e569de 100644 --- a/components/consent_auditor/consent_auditor_impl.h +++ b/components/consent_auditor/consent_auditor_impl.h
@@ -14,12 +14,6 @@ #include "base/time/clock.h" #include "components/consent_auditor/consent_auditor.h" #include "components/consent_auditor/consent_sync_bridge.h" -#include "components/keyed_service/core/keyed_service.h" -#include "components/sync/model/model_type_sync_bridge.h" - -namespace sync_pb { -class UserConsentSpecifics; -} // namespace sync_pb class PrefService; class PrefRegistrySimple; @@ -60,6 +54,10 @@ const CoreAccountId& account_id, const sync_pb::UserConsentTypes::AssistantActivityControlConsent& consent) override; + void RecordAccountPasswordsConsent( + const CoreAccountId& account_id, + const sync_pb::UserConsentTypes::AccountPasswordsConsent& consent) + override; void RecordLocalConsent(const std::string& feature, const std::string& description_text, const std::string& confirmation_text) override; @@ -67,13 +65,6 @@ override; private: - std::unique_ptr<sync_pb::UserConsentSpecifics> ConstructUserConsentSpecifics( - const CoreAccountId& account_id, - Feature feature, - const std::vector<int>& description_grd_ids, - int confirmation_grd_id, - ConsentStatus status); - PrefService* pref_service_; std::unique_ptr<ConsentSyncBridge> consent_sync_bridge_; std::string app_version_;
diff --git a/components/consent_auditor/fake_consent_auditor.cc b/components/consent_auditor/fake_consent_auditor.cc index 62c9779..a7d5a93 100644 --- a/components/consent_auditor/fake_consent_auditor.cc +++ b/components/consent_auditor/fake_consent_auditor.cc
@@ -27,9 +27,9 @@ namespace consent_auditor { -FakeConsentAuditor::FakeConsentAuditor() {} +FakeConsentAuditor::FakeConsentAuditor() = default; -FakeConsentAuditor::~FakeConsentAuditor() {} +FakeConsentAuditor::~FakeConsentAuditor() = default; void FakeConsentAuditor::RecordSyncConsent( const CoreAccountId& account_id, @@ -49,6 +49,12 @@ NOTIMPLEMENTED(); } +void FakeConsentAuditor::RecordAccountPasswordsConsent( + const CoreAccountId& account_id, + const sync_pb::UserConsentTypes::AccountPasswordsConsent& consent) { + NOTIMPLEMENTED(); +} + void FakeConsentAuditor::RecordGaiaConsent( const CoreAccountId& account_id, consent_auditor::Feature feature,
diff --git a/components/consent_auditor/fake_consent_auditor.h b/components/consent_auditor/fake_consent_auditor.h index 45bffeb..aa2ccf0 100644 --- a/components/consent_auditor/fake_consent_auditor.h +++ b/components/consent_auditor/fake_consent_auditor.h
@@ -41,6 +41,10 @@ const CoreAccountId& account_id, const sync_pb::UserConsentTypes::AssistantActivityControlConsent& consent) override; + void RecordAccountPasswordsConsent( + const CoreAccountId& account_id, + const sync_pb::UserConsentTypes::AccountPasswordsConsent& consent) + override; void RecordLocalConsent(const std::string& feature, const std::string& description_text,
diff --git a/components/crash/content/browser/child_exit_observer_android.cc b/components/crash/content/browser/child_exit_observer_android.cc index 2fea14a..6b9a219 100644 --- a/components/crash/content/browser/child_exit_observer_android.cc +++ b/components/crash/content/browser/child_exit_observer_android.cc
@@ -189,12 +189,14 @@ // NOTIFICATION_RENDERER_PROCESS_TERMINATED is sent when the renderer // process is cleanly shutdown. info.normal_termination = true; + info.renderer_shutdown_requested = rph->ShutdownRequested(); break; } case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { // We do not care about android fast shutdowns as it is a known case where // the renderer is intentionally killed when we are done with it. info.normal_termination = rph->FastShutdownStarted(); + info.renderer_shutdown_requested = rph->ShutdownRequested(); info.app_state = base::android::ApplicationStatusListener::GetState(); const auto& content_info = *content::Details<content::ChildProcessTerminationInfo>(details)
diff --git a/components/crash/content/browser/child_exit_observer_android.h b/components/crash/content/browser/child_exit_observer_android.h index c7c8d1b..f70f5cf5e 100644 --- a/components/crash/content/browser/child_exit_observer_android.h +++ b/components/crash/content/browser/child_exit_observer_android.h
@@ -64,6 +64,9 @@ // tab is closed. Some fields below may not be populated if this is true. bool normal_termination = false; + // Renderer process shutdown started by RenderProcessHost::Shutdown. + bool renderer_shutdown_requested = false; + // Values from ChildProcessTerminationInfo. // Note base::TerminationStatus and exit_code are missing intentionally // because those fields hold no useful information on Android.
diff --git a/components/crash/content/browser/crash_metrics_reporter_android.cc b/components/crash/content/browser/crash_metrics_reporter_android.cc index 99b71091..7cce720 100644 --- a/components/crash/content/browser/crash_metrics_reporter_android.cc +++ b/components/crash/content/browser/crash_metrics_reporter_android.cc
@@ -117,6 +117,7 @@ base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES || info.app_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES; const bool intentional_kill = info.was_killed_intentionally_by_browser; + // TODO(crbug.com/1115517): Take into account renderer_shutdown_requested. const bool android_oom_kill = !info.was_killed_intentionally_by_browser && !crashed && !info.normal_termination; const bool renderer_visible = info.renderer_has_visible_clients; @@ -261,6 +262,12 @@ } } + if (!info.was_killed_intentionally_by_browser && !crashed && + !info.normal_termination && info.renderer_shutdown_requested) { + ReportCrashCount(ProcessedCrashCounts::kRendererProcessHostShutdown, + &reported_counts); + } + if (app_foreground && android_oom_kill && info.binding_state == base::android::ChildBindingState::STRONG) { const bool has_waived = info.remaining_process_with_waived_binding > 0;
diff --git a/components/crash/content/browser/crash_metrics_reporter_android.h b/components/crash/content/browser/crash_metrics_reporter_android.h index c2ededf..edc89ac 100644 --- a/components/crash/content/browser/crash_metrics_reporter_android.h +++ b/components/crash/content/browser/crash_metrics_reporter_android.h
@@ -50,7 +50,8 @@ kRendererAllocationFailureAll = 16, kUtilityForegroundOom = 17, kUtilityCrashAll = 18, - kMaxValue = kUtilityCrashAll + kRendererProcessHostShutdown = 19, + kMaxValue = kRendererProcessHostShutdown }; using ReportedCrashTypeSet = base::flat_set<ProcessedCrashCounts>;
diff --git a/components/exo/data_offer.cc b/components/exo/data_offer.cc index cb558f5..9027d77c 100644 --- a/components/exo/data_offer.cc +++ b/components/exo/data_offer.cc
@@ -31,8 +31,6 @@ namespace exo { namespace { -constexpr char kTextMimeTypeUtf8[] = "text/plain;charset=utf-8"; -constexpr char kUtf8String[] = "UTF8_STRING"; constexpr char kTextMimeTypeUtf16[] = "text/plain;charset=utf-16"; constexpr char kTextHtmlMimeTypeUtf8[] = "text/html;charset=utf-8"; constexpr char kTextHtmlMimeTypeUtf16[] = "text/html;charset=utf-16"; @@ -279,7 +277,7 @@ base::string16 string_content; if (data.HasString() && data.GetString(&string_content)) { - const std::string utf8_mime_type = std::string(kTextMimeTypeUtf8); + const std::string utf8_mime_type = std::string(ui::kMimeTypeTextUtf8); data_.emplace(utf8_mime_type, EncodeAsRefCountedString(string_content, kUTF8)); delegate_->OnOffer(utf8_mime_type); @@ -321,10 +319,11 @@ /* data_dst = */ nullptr)) { auto utf8_callback = base::BindRepeating(&ReadTextFromClipboard, std::string(kUTF8)); - delegate_->OnOffer(std::string(kTextMimeTypeUtf8)); - data_callbacks_.emplace(std::string(kTextMimeTypeUtf8), utf8_callback); - delegate_->OnOffer(std::string(kUtf8String)); - data_callbacks_.emplace(std::string(kUtf8String), utf8_callback); + delegate_->OnOffer(std::string(ui::kMimeTypeTextUtf8)); + data_callbacks_.emplace(std::string(ui::kMimeTypeTextUtf8), utf8_callback); + delegate_->OnOffer(std::string(ui::kMimeTypeLinuxUtf8String)); + data_callbacks_.emplace(std::string(ui::kMimeTypeLinuxUtf8String), + utf8_callback); delegate_->OnOffer(std::string(kTextMimeTypeUtf16)); data_callbacks_.emplace( std::string(kTextMimeTypeUtf16),
diff --git a/components/exo/data_source.cc b/components/exo/data_source.cc index 53765d91..e612082731 100644 --- a/components/exo/data_source.cc +++ b/components/exo/data_source.cc
@@ -22,6 +22,7 @@ #include "net/base/mime_util.h" #include "third_party/blink/public/common/mime_util/mime_util.h" #include "third_party/icu/source/common/unicode/ucnv.h" +#include "ui/base/clipboard/clipboard_constants.h" namespace exo { @@ -248,7 +249,7 @@ for (auto mime_type : mime_types_) { if (net::MatchesMimeType(std::string(kTextPlain), mime_type) || - mime_type == kEncodingUTF8Legacy) { + mime_type == ui::kMimeTypeLinuxUtf8String) { if (text_reader.is_null()) continue;
diff --git a/components/exo/mime_utils.cc b/components/exo/mime_utils.cc index b988607..40ae71f4 100644 --- a/components/exo/mime_utils.cc +++ b/components/exo/mime_utils.cc
@@ -4,6 +4,8 @@ #include "components/exo/mime_utils.h" +#include "ui/base/clipboard/clipboard_constants.h" + namespace { constexpr char kCharset[] = ";charset="; @@ -16,7 +18,7 @@ std::string GetCharset(const std::string& mime_type) { // We special case UTF8_STRING to provide minimal handling of X11 apps. - if (mime_type == kEncodingUTF8Legacy) + if (mime_type == ui::kMimeTypeLinuxUtf8String) return std::string(kEncodingUTF8Charset); auto pos = mime_type.find(kCharset);
diff --git a/components/exo/mime_utils.h b/components/exo/mime_utils.h index 8e2b4b5..5905e17 100644 --- a/components/exo/mime_utils.h +++ b/components/exo/mime_utils.h
@@ -9,8 +9,6 @@ namespace exo { -constexpr char kEncodingUTF8Legacy[] = "UTF8_STRING"; - // Takes a text/* mime type and returns the name of the character set specified // in the type. If no character set is specified, defaults to US-ASCII. std::string GetCharset(const std::string& mime_type);
diff --git a/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java b/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java index 63b8c61b..13c0438 100644 --- a/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java +++ b/components/external_intents/android/javatests/src/org/chromium/components/external_intents/ExternalNavigationHandlerTest.java
@@ -23,6 +23,7 @@ import androidx.browser.customtabs.CustomTabsIntent; import androidx.test.filters.SmallTest; +import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -147,6 +148,8 @@ private final TestExternalNavigationDelegate mDelegate; private ExternalNavigationHandlerForTesting mUrlHandler; + private Context mApplicationContextToRestore; + public ExternalNavigationHandlerTest() { mDelegate = new TestExternalNavigationDelegate(); mUrlHandler = new ExternalNavigationHandlerForTesting(mDelegate); @@ -154,12 +157,19 @@ @Before public void setUp() { + mApplicationContextToRestore = ContextUtils.getApplicationContext(); + mContext = new TestContext(InstrumentationRegistry.getTargetContext(), mDelegate); ContextUtils.initApplicationContextForTests(mContext); NativeLibraryTestUtils.loadNativeLibraryNoBrowserProcess(); } + @After + public void tearDown() { + ContextUtils.initApplicationContextForTests(mApplicationContextToRestore); + } + @Test @SmallTest public void testStartActivityToTrustedPackageWithoutUserGesture() {
diff --git a/components/feed/core/v2/feed_stream_unittest.cc b/components/feed/core/v2/feed_stream_unittest.cc index 80bfd41..b51d3009 100644 --- a/components/feed/core/v2/feed_stream_unittest.cc +++ b/components/feed/core/v2/feed_stream_unittest.cc
@@ -347,27 +347,28 @@ feedwire::Response response, StreamModelUpdateRequest::Source source, base::Time current_time) const override { - if (injected_response_) { - if (injected_response_->model_update_request) - injected_response_->model_update_request->source = source; - RefreshResponseData result = std::move(*injected_response_); - injected_response_.reset(); + if (!injected_responses_.empty()) { + if (injected_responses_[0].model_update_request) + injected_responses_[0].model_update_request->source = source; + RefreshResponseData result = std::move(injected_responses_[0]); + injected_responses_.erase(injected_responses_.begin()); return result; } return FeedStream::WireResponseTranslator::TranslateWireResponse( std::move(response), source, current_time); } void InjectResponse(std::unique_ptr<StreamModelUpdateRequest> response) { - injected_response_ = RefreshResponseData(); - injected_response_->model_update_request = std::move(response); + RefreshResponseData data; + data.model_update_request = std::move(response); + InjectResponse(std::move(data)); } void InjectResponse(RefreshResponseData response_data) { - injected_response_ = std::move(response_data); + injected_responses_.push_back(std::move(response_data)); } - bool InjectedResponseConsumed() const { return !injected_response_; } + bool InjectedResponseConsumed() const { return injected_responses_.empty(); } private: - mutable base::Optional<RefreshResponseData> injected_response_; + mutable std::vector<RefreshResponseData> injected_responses_; }; class FakeRefreshTaskScheduler : public RefreshTaskScheduler { @@ -1398,6 +1399,23 @@ EXPECT_EQ("loading -> 2 slices", surface.DescribeUpdates()); } +TEST_F(FeedStreamTest, ClearAllWhileLoadingMore) { + response_translator_.InjectResponse(MakeTypicalInitialModelState()); + TestSurface surface(stream_.get()); + WaitForIdleTaskQueue(); + + stream_->LoadMore(surface.GetSurfaceId(), base::DoNothing()); + response_translator_.InjectResponse(MakeTypicalNextPageState(2)); + response_translator_.InjectResponse(MakeTypicalInitialModelState()); + stream_->OnCacheDataCleared(); // triggers ClearAll(). + WaitForIdleTaskQueue(); + + EXPECT_EQ( + "loading -> 2 slices -> 2 slices +spinner -> 4 slices -> loading -> 2 " + "slices", + surface.DescribeUpdates()); +} + TEST_F(FeedStreamTest, ClearAllWipesAllState) { // Trigger saving a consistency token, so it can be cleared later. network_.consistency_token = "token-11";
diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index 1861d80..b720b91 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc
@@ -1137,8 +1137,9 @@ } NaClStartDebugExceptionHandlerThread( std::move(process), info, base::ThreadTaskRunnerHandle::Get(), - base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, - weak_factory_.GetWeakPtr())); + base::BindRepeating( + &NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, + weak_factory_.GetWeakPtr())); return true; } #endif
diff --git a/components/nacl/common/nacl_debug_exception_handler_win.cc b/components/nacl/common/nacl_debug_exception_handler_win.cc index a7d2d3e..7820ca86 100644 --- a/components/nacl/common/nacl_debug_exception_handler_win.cc +++ b/components/nacl/common/nacl_debug_exception_handler_win.cc
@@ -44,7 +44,8 @@ } else { LOG(ERROR) << "Invalid process handle"; } - task_runner_->PostTask(FROM_HERE, base::BindOnce(on_connected_, attached)); + task_runner_->PostTask(FROM_HERE, + base::BindOnce(std::move(on_connected_), attached)); if (attached) { NaClDebugExceptionHandlerRun( @@ -59,7 +60,7 @@ base::Process nacl_process_; std::string startup_info_; const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - base::Callback<void(bool)> on_connected_; + base::RepeatingCallback<void(bool)> on_connected_; DISALLOW_COPY_AND_ASSIGN(DebugExceptionHandler); }; @@ -70,7 +71,7 @@ base::Process nacl_process, const std::string& startup_info, scoped_refptr<base::SingleThreadTaskRunner> task_runner, - const base::RepeatingCallback<void(bool)>& on_connected) { + base::RepeatingCallback<void(bool)> on_connected) { // The new PlatformThread will take ownership of the // DebugExceptionHandler object, which will delete itself on exit. DebugExceptionHandler* handler = new DebugExceptionHandler(
diff --git a/components/nacl/common/nacl_debug_exception_handler_win.h b/components/nacl/common/nacl_debug_exception_handler_win.h index 936a1e40..95aaf6b 100644 --- a/components/nacl/common/nacl_debug_exception_handler_win.h +++ b/components/nacl/common/nacl_debug_exception_handler_win.h
@@ -18,6 +18,6 @@ base::Process nacl_process, const std::string& startup_info, scoped_refptr<base::SingleThreadTaskRunner> task_runner, - const base::Callback<void(bool)>& on_connected); + base::RepeatingCallback<void(bool)> on_connected); #endif // COMPONENTS_NACL_COMMON_NACL_DEBUG_EXCEPTION_HANDLER_WIN_H_
diff --git a/components/omnibox/browser/zero_suggest_provider.cc b/components/omnibox/browser/zero_suggest_provider.cc index a6318ce..27e91c3 100644 --- a/components/omnibox/browser/zero_suggest_provider.cc +++ b/components/omnibox/browser/zero_suggest_provider.cc
@@ -611,11 +611,18 @@ const auto page_class = input.current_page_classification(); const auto input_type = input.type(); + if (client()->IsOffTheRecord()) + return false; + if (input.focus_type() == OmniboxFocusType::DEFAULT) return false; - if (client()->IsOffTheRecord()) + if (input.focus_type() == OmniboxFocusType::ON_FOCUS && + page_class == metrics::OmniboxEventProto::OTHER && + !base::FeatureList::IsEnabled( + omnibox::kFocusGestureTriggersContextualWebZeroSuggest)) { return false; + } // When the omnibox is empty, only allow zero suggest for the ChromeOS // Launcher and NTP, unless the clobber flag is on.
diff --git a/components/omnibox/browser/zero_suggest_provider.h b/components/omnibox/browser/zero_suggest_provider.h index 90c84f9..6623202 100644 --- a/components/omnibox/browser/zero_suggest_provider.h +++ b/components/omnibox/browser/zero_suggest_provider.h
@@ -90,6 +90,12 @@ return results_.hidden_group_ids; } + // Whether ZeroSuggest is allowed for |input|, given its page classification + // and OmniboxFocusType (triggering UI gesture). Invoked early, before + // TypeOfResultToRun, and confirms all the external conditions for ZeroSuggest + // are met. + bool AllowZeroSuggestSuggestions(const AutocompleteInput& input) const; + private: FRIEND_TEST_ALL_PREFIXES(ZeroSuggestProviderTest, TypeOfResultToRun); FRIEND_TEST_ALL_PREFIXES(ZeroSuggestProviderTest, @@ -172,11 +178,6 @@ void OnRemoteSuggestionsLoaderAvailable( std::unique_ptr<network::SimpleURLLoader> loader); - // Whether zero suggest suggestions are allowed in the given context. - // Invoked early, confirms all the external conditions for ZeroSuggest are - // met. - bool AllowZeroSuggestSuggestions(const AutocompleteInput& input) const; - // Checks whether we have a set of zero suggest results cached, and if so // populates |matches_| with cached results. void MaybeUseCachedSuggestions();
diff --git a/components/omnibox/browser/zero_suggest_provider_unittest.cc b/components/omnibox/browser/zero_suggest_provider_unittest.cc index 7cf2105..1ec43a70 100644 --- a/components/omnibox/browser/zero_suggest_provider_unittest.cc +++ b/components/omnibox/browser/zero_suggest_provider_unittest.cc
@@ -207,6 +207,71 @@ variant}}); } +TEST_F(ZeroSuggestProviderTest, AllowZeroSuggestSuggestionsContextualWeb) { + provider_->SetPageClassificationForTesting(metrics::OmniboxEventProto::OTHER); + std::string input_url = "https://example.com/"; + + AutocompleteInput prefix_input(base::ASCIIToUTF16(input_url), + metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + prefix_input.set_focus_type(OmniboxFocusType::DEFAULT); + + AutocompleteInput on_focus_input(base::ASCIIToUTF16(input_url), + metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + on_focus_input.set_current_url(GURL(input_url)); + on_focus_input.set_focus_type(OmniboxFocusType::ON_FOCUS); + + AutocompleteInput on_clobber_input(base::string16(), + metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + on_clobber_input.set_current_url(GURL(input_url)); + on_clobber_input.set_focus_type(OmniboxFocusType::DELETED_PERMANENT_TEXT); + + EXPECT_FALSE(provider_->AllowZeroSuggestSuggestions(prefix_input)); + EXPECT_TRUE(provider_->AllowZeroSuggestSuggestions(on_focus_input)); + EXPECT_FALSE(provider_->AllowZeroSuggestSuggestions(on_clobber_input)); + + // Enable on-clobber in addition to on-focus. + { + base::test::ScopedFeatureList features; + features.InitAndEnableFeature(omnibox::kClobberIsZeroSuggestEntrypoint); + EXPECT_FALSE(provider_->AllowZeroSuggestSuggestions(prefix_input)); + EXPECT_TRUE(provider_->AllowZeroSuggestSuggestions(on_focus_input)); + EXPECT_TRUE(provider_->AllowZeroSuggestSuggestions(on_clobber_input)); + } + + // Disable on-focus. + { + base::test::ScopedFeatureList features; + features.InitAndDisableFeature( + omnibox::kFocusGestureTriggersContextualWebZeroSuggest); + EXPECT_FALSE(provider_->AllowZeroSuggestSuggestions(prefix_input)); + EXPECT_FALSE(provider_->AllowZeroSuggestSuggestions(on_focus_input)); + EXPECT_FALSE(provider_->AllowZeroSuggestSuggestions(on_clobber_input)); + + // Sanity check that we don't accidentally disable on-focus for NTP here. + AutocompleteInput on_focus_ntp( + base::ASCIIToUTF16(input_url), + metrics::OmniboxEventProto::INSTANT_NTP_WITH_OMNIBOX_AS_STARTING_FOCUS, + TestSchemeClassifier()); + on_focus_ntp.set_current_url(GURL(input_url)); + on_focus_ntp.set_focus_type(OmniboxFocusType::ON_FOCUS); + EXPECT_TRUE(provider_->AllowZeroSuggestSuggestions(on_focus_ntp)); + } + + // Enable on-clobber and disable on-focus. + { + base::test::ScopedFeatureList features; + features.InitWithFeatures( + {omnibox::kClobberIsZeroSuggestEntrypoint}, + {omnibox::kFocusGestureTriggersContextualWebZeroSuggest}); + EXPECT_FALSE(provider_->AllowZeroSuggestSuggestions(prefix_input)); + EXPECT_FALSE(provider_->AllowZeroSuggestSuggestions(on_focus_input)); + EXPECT_TRUE(provider_->AllowZeroSuggestSuggestions(on_clobber_input)); + } +} + TEST_F(ZeroSuggestProviderTest, TypeOfResultToRun) { provider_->SetPageClassificationForTesting(metrics::OmniboxEventProto::OTHER); GURL current_url = GURL("https://example.com/");
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index f9b38ff2..b3ca6131 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -224,6 +224,17 @@ const base::Feature kClobberIsZeroSuggestEntrypoint{ "OmniboxClobberIsZeroSuggestEntrypoint", base::FEATURE_DISABLED_BY_DEFAULT}; +// Disable this flag to prevent focus gestures (e.g. clicks, taps, Ctrl+L) from +// triggering ZeroSuggest for the OTHER page classification (contextual web). +// This is used to experiment with alternate ZeroSuggest triggers like clobber. +// +// Note, this flag is Enabled by default, as on-focus is the standard +// ZeroSuggest trigger. This flag doesn't affect the NTP or SERP. +// We don't want to accidentally unlaunch on-focus NTP ZeroSuggest. +const base::Feature kFocusGestureTriggersContextualWebZeroSuggest{ + "OmniboxFocusGestureTriggersContextualWebZeroSuggest", + base::FEATURE_ENABLED_BY_DEFAULT}; + // If enabled, ranks the local zero-prefix suggestions based on frecency // (combined frequency and recency). const base::Feature kOmniboxLocalZeroSuggestFrecencyRanking{
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h index 5c24b63a..ed8c63a 100644 --- a/components/omnibox/common/omnibox_features.h +++ b/components/omnibox/common/omnibox_features.h
@@ -55,6 +55,7 @@ // On-Focus Suggestions a.k.a. ZeroSuggest. extern const base::Feature kClobberIsZeroSuggestEntrypoint; +extern const base::Feature kFocusGestureTriggersContextualWebZeroSuggest; extern const base::Feature kOmniboxLocalZeroSuggestAgeThreshold; extern const base::Feature kOmniboxLocalZeroSuggestFrecencyRanking; extern const base::Feature kOnFocusSuggestions;
diff --git a/components/performance_manager/execution_context/execution_context_registry_impl.cc b/components/performance_manager/execution_context/execution_context_registry_impl.cc index dcaa747..92ad6e7 100644 --- a/components/performance_manager/execution_context/execution_context_registry_impl.cc +++ b/components/performance_manager/execution_context/execution_context_registry_impl.cc
@@ -103,7 +103,7 @@ } const FrameNode* ExecutionContextRegistryImpl::GetFrameNodeByFrameToken( - const FrameToken& token) { + const blink::LocalFrameToken& token) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // The casting is safe because ExecutionContextToken guarantees it has the // same layout as base::UnguessableToken. @@ -115,7 +115,7 @@ } const WorkerNode* ExecutionContextRegistryImpl::GetWorkerNodeByWorkerToken( - const WorkerToken& token) { + const blink::WorkerToken& token) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // The casting is safe because ExecutionContextToken guarantees it has the // same layout as base::UnguessableToken.
diff --git a/components/performance_manager/execution_context/execution_context_registry_impl.h b/components/performance_manager/execution_context/execution_context_registry_impl.h index ad9522f..8bc7030a 100644 --- a/components/performance_manager/execution_context/execution_context_registry_impl.h +++ b/components/performance_manager/execution_context/execution_context_registry_impl.h
@@ -41,9 +41,10 @@ void RemoveObserver(ExecutionContextObserver* observer) override; const ExecutionContext* GetExecutionContextByToken( const ExecutionContextToken& token) override; - const FrameNode* GetFrameNodeByFrameToken(const FrameToken& token) override; + const FrameNode* GetFrameNodeByFrameToken( + const blink::LocalFrameToken& token) override; const WorkerNode* GetWorkerNodeByWorkerToken( - const WorkerToken& token) override; + const blink::WorkerToken& token) override; const ExecutionContext* GetExecutionContextForFrameNode( const FrameNode* frame_node) override; const ExecutionContext* GetExecutionContextForWorkerNode(
diff --git a/components/performance_manager/execution_context/execution_context_registry_impl_unittest.cc b/components/performance_manager/execution_context/execution_context_registry_impl_unittest.cc index d405a31..d7a7045 100644 --- a/components/performance_manager/execution_context/execution_context_registry_impl_unittest.cc +++ b/components/performance_manager/execution_context/execution_context_registry_impl_unittest.cc
@@ -146,11 +146,8 @@ ExecutionContextToken(base::UnguessableToken::Null()))); EXPECT_FALSE(registry_->GetExecutionContextByToken( ExecutionContextToken(base::UnguessableToken::Create()))); - EXPECT_FALSE(registry_->GetFrameNodeByFrameToken( - FrameToken(base::UnguessableToken::Null()))); - EXPECT_FALSE(registry_->GetFrameNodeByFrameToken( - FrameToken(base::UnguessableToken::Create()))); - EXPECT_FALSE(registry_->GetWorkerNodeByWorkerToken(WorkerToken())); + EXPECT_FALSE(registry_->GetFrameNodeByFrameToken(blink::LocalFrameToken())); + EXPECT_FALSE(registry_->GetWorkerNodeByWorkerToken(blink::WorkerToken())); // Destroy nodes one by one and expect observer notifications. EXPECT_CALL(obs, OnBeforeExecutionContextRemoved(worker_ec));
diff --git a/components/performance_manager/graph/frame_node_impl.cc b/components/performance_manager/graph/frame_node_impl.cc index 1349cdc0..9fb8d29 100644 --- a/components/performance_manager/graph/frame_node_impl.cc +++ b/components/performance_manager/graph/frame_node_impl.cc
@@ -26,7 +26,7 @@ FrameNodeImpl* parent_frame_node, int frame_tree_node_id, int render_frame_id, - const FrameToken& frame_token, + const blink::LocalFrameToken& frame_token, int32_t browsing_instance_id, int32_t site_instance_id) : parent_frame_node_(parent_frame_node), @@ -138,7 +138,7 @@ return render_frame_id_; } -const FrameToken& FrameNodeImpl::frame_token() const { +const blink::LocalFrameToken& FrameNodeImpl::frame_token() const { return frame_token_; } @@ -371,7 +371,7 @@ return frame_tree_node_id(); } -const FrameToken& FrameNodeImpl::GetFrameToken() const { +const blink::LocalFrameToken& FrameNodeImpl::GetFrameToken() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return frame_token(); }
diff --git a/components/performance_manager/graph/frame_node_impl.h b/components/performance_manager/graph/frame_node_impl.h index 433be52..b88f286 100644 --- a/components/performance_manager/graph/frame_node_impl.h +++ b/components/performance_manager/graph/frame_node_impl.h
@@ -18,6 +18,7 @@ #include "components/performance_manager/public/render_frame_host_proxy.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "third_party/blink/public/common/tokens/tokens.h" #include "url/gurl.h" namespace performance_manager { @@ -70,7 +71,7 @@ FrameNodeImpl* parent_frame_node, int frame_tree_node_id, int render_frame_id, - const FrameToken& frame_token, + const blink::LocalFrameToken& frame_token, int32_t browsing_instance_id, int32_t site_instance_id); ~FrameNodeImpl() override; @@ -98,7 +99,7 @@ ProcessNodeImpl* process_node() const; int frame_tree_node_id() const; int render_frame_id() const; - const FrameToken& frame_token() const; + const blink::LocalFrameToken& frame_token() const; int32_t browsing_instance_id() const; int32_t site_instance_id() const; const RenderFrameHostProxy& render_frame_host_proxy() const; @@ -169,7 +170,7 @@ const PageNode* GetPageNode() const override; const ProcessNode* GetProcessNode() const override; int GetFrameTreeNodeId() const override; - const FrameToken& GetFrameToken() const override; + const blink::LocalFrameToken& GetFrameToken() const override; int32_t GetBrowsingInstanceId() const override; int32_t GetSiteInstanceId() const override; bool VisitChildFrameNodes(const FrameNodeVisitor& visitor) const override; @@ -263,7 +264,7 @@ // This is the unique token for this frame instance as per e.g. // RenderFrameHost::GetFrameToken(). - const FrameToken frame_token_; + const blink::LocalFrameToken frame_token_; // The unique ID of the BrowsingInstance this frame belongs to. Frames in the // same BrowsingInstance are allowed to script each other at least
diff --git a/components/performance_manager/graph/worker_node_impl.cc b/components/performance_manager/graph/worker_node_impl.cc index 9c723b1..99a9c9a 100644 --- a/components/performance_manager/graph/worker_node_impl.cc +++ b/components/performance_manager/graph/worker_node_impl.cc
@@ -12,7 +12,7 @@ WorkerNodeImpl::WorkerNodeImpl(const std::string& browser_context_id, WorkerType worker_type, ProcessNodeImpl* process_node, - const WorkerToken& worker_token) + const blink::WorkerToken& worker_token) : browser_context_id_(browser_context_id), worker_type_(worker_type), process_node_(process_node), @@ -120,7 +120,7 @@ return url_; } -const WorkerToken& WorkerNodeImpl::worker_token() const { +const blink::WorkerToken& WorkerNodeImpl::worker_token() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return worker_token_; } @@ -172,7 +172,7 @@ return url(); } -const WorkerToken& WorkerNodeImpl::GetWorkerToken() const { +const blink::WorkerToken& WorkerNodeImpl::GetWorkerToken() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return worker_token(); }
diff --git a/components/performance_manager/graph/worker_node_impl.h b/components/performance_manager/graph/worker_node_impl.h index f398bb9..dc64e8a 100644 --- a/components/performance_manager/graph/worker_node_impl.h +++ b/components/performance_manager/graph/worker_node_impl.h
@@ -14,6 +14,7 @@ #include "base/util/type_safety/pass_key.h" #include "components/performance_manager/graph/node_base.h" #include "components/performance_manager/public/graph/worker_node.h" +#include "third_party/blink/public/common/tokens/tokens.h" #include "url/gurl.h" namespace performance_manager { @@ -34,7 +35,7 @@ WorkerNodeImpl(const std::string& browser_context_id, WorkerType worker_type, ProcessNodeImpl* process_node, - const WorkerToken& worker_token); + const blink::WorkerToken& worker_token); ~WorkerNodeImpl() override; // Invoked when a frame starts/stops being a client of this worker. @@ -53,7 +54,7 @@ const std::string& browser_context_id() const; WorkerType worker_type() const; ProcessNodeImpl* process_node() const; - const WorkerToken& worker_token() const; + const blink::WorkerToken& worker_token() const; // Getters for non-const properties. These are not thread safe. const GURL& url() const; @@ -78,7 +79,7 @@ WorkerType GetWorkerType() const override; const std::string& GetBrowserContextID() const override; const ProcessNode* GetProcessNode() const override; - const WorkerToken& GetWorkerToken() const override; + const blink::WorkerToken& GetWorkerToken() const override; const GURL& GetURL() const override; const base::flat_set<const FrameNode*> GetClientFrames() const override; const base::flat_set<const WorkerNode*> GetClientWorkers() const override; @@ -102,7 +103,7 @@ // and the renderer hosting the worker. It should not be used to identify a // worker in browser-to-renderer control messages, but may be used to identify // a worker in informational messages going in either direction. - const WorkerToken worker_token_; + const blink::WorkerToken worker_token_; // The URL of the worker script. This is the final response URL which takes // into account redirections. This is initially empty and it is set when
diff --git a/components/performance_manager/graph/worker_node_impl_unittest.cc b/components/performance_manager/graph/worker_node_impl_unittest.cc index ce35cbad..d145febc 100644 --- a/components/performance_manager/graph/worker_node_impl_unittest.cc +++ b/components/performance_manager/graph/worker_node_impl_unittest.cc
@@ -49,7 +49,7 @@ const std::string kTestBrowserContextId = base::UnguessableToken::Create().ToString(); auto process = CreateNode<ProcessNodeImpl>(); - static const WorkerToken kTestWorkerToken = WorkerToken(); + static const blink::WorkerToken kTestWorkerToken; auto worker_impl = CreateNode<WorkerNodeImpl>( kWorkerType, process.get(), kTestBrowserContextId, kTestWorkerToken);
diff --git a/components/performance_manager/performance_manager_impl.cc b/components/performance_manager/performance_manager_impl.cc index a1ca8bd..b5cfc7f9 100644 --- a/components/performance_manager/performance_manager_impl.cc +++ b/components/performance_manager/performance_manager_impl.cc
@@ -117,7 +117,7 @@ FrameNodeImpl* parent_frame_node, int frame_tree_node_id, int render_frame_id, - const FrameToken& frame_token, + const blink::LocalFrameToken& frame_token, int32_t browsing_instance_id, int32_t site_instance_id, FrameNodeCreationCallback creation_callback) { @@ -154,7 +154,7 @@ const std::string& browser_context_id, WorkerNode::WorkerType worker_type, ProcessNodeImpl* process_node, - const WorkerToken& worker_token) { + const blink::WorkerToken& worker_token) { return CreateNodeImpl<WorkerNodeImpl>( base::OnceCallback<void(WorkerNodeImpl*)>(), browser_context_id, worker_type, process_node, worker_token);
diff --git a/components/performance_manager/performance_manager_impl.h b/components/performance_manager/performance_manager_impl.h index 38c9615..0bad843 100644 --- a/components/performance_manager/performance_manager_impl.h +++ b/components/performance_manager/performance_manager_impl.h
@@ -23,6 +23,7 @@ #include "components/performance_manager/public/render_process_host_proxy.h" #include "components/performance_manager/public/web_contents_proxy.h" #include "content/public/common/process_type.h" +#include "third_party/blink/public/common/tokens/tokens.h" class GURL; @@ -92,7 +93,7 @@ FrameNodeImpl* parent_frame_node, int frame_tree_node_id, int render_frame_id, - const FrameToken& frame_token, + const blink::LocalFrameToken& frame_token, int32_t browsing_instance_id, int32_t site_instance_id, FrameNodeCreationCallback creation_callback = @@ -111,7 +112,7 @@ const std::string& browser_context_id, WorkerNode::WorkerType worker_type, ProcessNodeImpl* process_node, - const WorkerToken& worker_token); + const blink::WorkerToken& worker_token); // Destroys a node returned from the creation functions above. May be called // from any sequence.
diff --git a/components/performance_manager/performance_manager_impl_unittest.cc b/components/performance_manager/performance_manager_impl_unittest.cc index e07263ed..00fba995 100644 --- a/components/performance_manager/performance_manager_impl_unittest.cc +++ b/components/performance_manager/performance_manager_impl_unittest.cc
@@ -16,6 +16,7 @@ #include "components/performance_manager/graph/process_node_impl.h" #include "components/performance_manager/public/render_process_host_proxy.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/tokens/tokens.h" namespace performance_manager { @@ -64,8 +65,7 @@ std::unique_ptr<FrameNodeImpl> frame_node = PerformanceManagerImpl::CreateFrameNode( process_node.get(), page_node.get(), nullptr, 0, - ++next_render_frame_id, FrameToken(base::UnguessableToken::Create()), - 0, 0); + ++next_render_frame_id, blink::LocalFrameToken(), 0, 0); EXPECT_NE(nullptr, frame_node.get()); PerformanceManagerImpl::DeleteNode(std::move(frame_node)); @@ -87,35 +87,29 @@ std::unique_ptr<FrameNodeImpl> parent1_frame = PerformanceManagerImpl::CreateFrameNode( process_node.get(), page_node.get(), nullptr, 0, - ++next_render_frame_id, FrameToken(base::UnguessableToken::Create()), - 0, 0); + ++next_render_frame_id, blink::LocalFrameToken(), 0, 0); std::unique_ptr<FrameNodeImpl> parent2_frame = PerformanceManagerImpl::CreateFrameNode( process_node.get(), page_node.get(), nullptr, 1, - ++next_render_frame_id, FrameToken(base::UnguessableToken::Create()), - 0, 0); + ++next_render_frame_id, blink::LocalFrameToken(), 0, 0); std::unique_ptr<FrameNodeImpl> child1_frame = PerformanceManagerImpl::CreateFrameNode( process_node.get(), page_node.get(), parent1_frame.get(), 2, - ++next_render_frame_id, FrameToken(base::UnguessableToken::Create()), - 0, 0); + ++next_render_frame_id, blink::LocalFrameToken(), 0, 0); std::unique_ptr<FrameNodeImpl> child2_frame = PerformanceManagerImpl::CreateFrameNode( process_node.get(), page_node.get(), parent2_frame.get(), 3, - ++next_render_frame_id, FrameToken(base::UnguessableToken::Create()), - 0, 0); + ++next_render_frame_id, blink::LocalFrameToken(), 0, 0); std::vector<std::unique_ptr<NodeBase>> nodes; for (size_t i = 0; i < 10; ++i) { nodes.push_back(PerformanceManagerImpl::CreateFrameNode( process_node.get(), page_node.get(), child1_frame.get(), 0, - ++next_render_frame_id, FrameToken(base::UnguessableToken::Create()), 0, - 0)); + ++next_render_frame_id, blink::LocalFrameToken(), 0, 0)); nodes.push_back(PerformanceManagerImpl::CreateFrameNode( process_node.get(), page_node.get(), child1_frame.get(), 1, - ++next_render_frame_id, FrameToken(base::UnguessableToken::Create()), 0, - 0)); + ++next_render_frame_id, blink::LocalFrameToken(), 0, 0)); } nodes.push_back(std::move(process_node));
diff --git a/components/performance_manager/performance_manager_tab_helper.cc b/components/performance_manager/performance_manager_tab_helper.cc index ae47965..b4dc3e9 100644 --- a/components/performance_manager/performance_manager_tab_helper.cc +++ b/components/performance_manager/performance_manager_tab_helper.cc
@@ -22,6 +22,7 @@ #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "third_party/blink/public/common/tokens/tokens.h" namespace performance_manager { @@ -166,7 +167,7 @@ process_node, page_node_.get(), parent_frame_node, render_frame_host->GetFrameTreeNodeId(), render_frame_host->GetRoutingID(), - FrameToken(render_frame_host->GetFrameToken()), + blink::LocalFrameToken(render_frame_host->GetFrameToken()), site_instance->GetBrowsingInstanceId(), site_instance->GetId(), base::BindOnce( [](const GURL& url, bool is_current, FrameNodeImpl* frame_node) {
diff --git a/components/performance_manager/public/execution_context/execution_context_registry.h b/components/performance_manager/public/execution_context/execution_context_registry.h index 9cc43e9..bd18e73 100644 --- a/components/performance_manager/public/execution_context/execution_context_registry.h +++ b/components/performance_manager/public/execution_context/execution_context_registry.h
@@ -8,6 +8,7 @@ #include "components/performance_manager/public/execution_context/execution_context_token.h" #include "components/performance_manager/public/graph/frame_node.h" #include "components/performance_manager/public/graph/worker_node.h" +#include "third_party/blink/public/common/tokens/tokens.h" namespace performance_manager { @@ -48,12 +49,12 @@ // Does a typed lookup of a FrameNode ExecutionContext by FrameToken, returns // nullptr if no such FrameNode exists. virtual const FrameNode* GetFrameNodeByFrameToken( - const FrameToken& token) = 0; + const blink::LocalFrameToken& token) = 0; // Does a typed lookup of a WorkerNode ExecutionContext by its DevToolsToken, // returns nullptr if no such WorkerNode exists. virtual const WorkerNode* GetWorkerNodeByWorkerToken( - const WorkerToken& token) = 0; + const blink::WorkerToken& token) = 0; // Returns the ExecutionContext associated with a node. virtual const ExecutionContext* GetExecutionContextForFrameNode(
diff --git a/components/performance_manager/public/graph/frame_node.h b/components/performance_manager/public/graph/frame_node.h index 1adfefa..f37a7d3 100644 --- a/components/performance_manager/public/graph/frame_node.h +++ b/components/performance_manager/public/graph/frame_node.h
@@ -12,13 +12,10 @@ #include "components/performance_manager/public/graph/node.h" #include "components/performance_manager/public/mojom/coordination_unit.mojom.h" #include "components/performance_manager/public/mojom/lifecycle.mojom.h" +#include "third_party/blink/public/common/tokens/tokens.h" class GURL; -namespace base { -class UnguessableToken; -} // namespace base - namespace performance_manager { class FrameNodeObserver; @@ -27,10 +24,6 @@ class RenderFrameHostProxy; class WorkerNode; -// A strongly typed unguessable token for the frame tokens. -using FrameToken = - util::StrongAlias<class FrameTokenTag, base::UnguessableToken>; - // Frame nodes form a tree structure, each FrameNode at most has one parent that // is a FrameNode. Conceptually, a frame corresponds to a // content::RenderFrameHost in the browser, and a content::RenderFrameImpl / @@ -92,7 +85,7 @@ // Gets the unique token associated with this frame. This is a constant over // the lifetime of the frame and unique across all frames for all time. - virtual const FrameToken& GetFrameToken() const = 0; + virtual const blink::LocalFrameToken& GetFrameToken() const = 0; // Gets the ID of the browsing instance to which this frame belongs. This is a // constant over the lifetime of the frame.
diff --git a/components/performance_manager/public/graph/worker_node.h b/components/performance_manager/public/graph/worker_node.h index cb763251..df9c15c 100644 --- a/components/performance_manager/public/graph/worker_node.h +++ b/components/performance_manager/public/graph/worker_node.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/util/type_safety/token_type.h" #include "components/performance_manager/public/graph/node.h" +#include "third_party/blink/public/common/tokens/tokens.h" class GURL; @@ -20,10 +21,6 @@ class FrameNode; class ProcessNode; -// TODO(chrisha): Once a variant-like WorkerToken is defined in blink, use that -// instead. -using WorkerToken = util::TokenType<class WorkerTokenTag>; - // Represents a running instance of a WorkerGlobalScope. // See https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope. // @@ -72,7 +69,7 @@ virtual const ProcessNode* GetProcessNode() const = 0; // Returns the unique token identifying this worker. - virtual const WorkerToken& GetWorkerToken() const = 0; + virtual const blink::WorkerToken& GetWorkerToken() const = 0; // Returns the URL of the worker script. This is the final response URL which // takes into account redirections.
diff --git a/components/performance_manager/test_support/graph_test_harness.h b/components/performance_manager/test_support/graph_test_harness.h index 30bec65a..404da23 100644 --- a/components/performance_manager/test_support/graph_test_harness.h +++ b/components/performance_manager/test_support/graph_test_harness.h
@@ -21,6 +21,7 @@ #include "components/performance_manager/public/render_process_host_proxy.h" #include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/tokens/tokens.h" namespace performance_manager { @@ -79,8 +80,7 @@ FrameNodeImpl* parent_frame_node, int frame_tree_node_id, int render_frame_id, - const FrameToken& frame_token = - FrameToken(base::UnguessableToken::Create()), + const blink::LocalFrameToken& frame_token = blink::LocalFrameToken(), int32_t browsing_instance_id = 0, int32_t site_instance_id = 0) { return std::make_unique<FrameNodeImpl>( @@ -126,7 +126,7 @@ WorkerNode::WorkerType worker_type, ProcessNodeImpl* process_node, const std::string& browser_context_id = std::string(), - const WorkerToken& token = WorkerToken()) { + const blink::WorkerToken& token = blink::WorkerToken()) { return std::make_unique<WorkerNodeImpl>(browser_context_id, worker_type, process_node, token); }
diff --git a/components/performance_manager/v8_memory/v8_per_frame_memory_decorator.cc b/components/performance_manager/v8_memory/v8_per_frame_memory_decorator.cc index 2d69b36..9e44e53 100644 --- a/components/performance_manager/v8_memory/v8_per_frame_memory_decorator.cc +++ b/components/performance_manager/v8_memory/v8_per_frame_memory_decorator.cc
@@ -26,6 +26,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" +#include "third_party/blink/public/common/tokens/tokens.h" namespace performance_manager { @@ -254,15 +255,17 @@ uint64_t unassociated_v8_bytes_used = result->unassociated_bytes_used; // Create a mapping from token to per-frame usage for the merge below. - std::vector<std::pair<FrameToken, blink::mojom::PerFrameV8MemoryUsageDataPtr>> + std::vector<std::pair<blink::LocalFrameToken, + blink::mojom::PerFrameV8MemoryUsageDataPtr>> tmp; for (auto& entry : result->associated_memory) { - tmp.emplace_back( - std::make_pair(FrameToken(entry->frame_token), std::move(entry))); + tmp.emplace_back(std::make_pair(blink::LocalFrameToken(entry->frame_token), + std::move(entry))); } DCHECK_EQ(tmp.size(), result->associated_memory.size()); - base::flat_map<FrameToken, blink::mojom::PerFrameV8MemoryUsageDataPtr> + base::flat_map<blink::LocalFrameToken, + blink::mojom::PerFrameV8MemoryUsageDataPtr> associated_memory(std::move(tmp)); // Validate that the frame tokens were all unique. If there are duplicates, // the map will arbirarily drop all but one record per unique token.
diff --git a/components/performance_manager/v8_memory/v8_per_frame_memory_decorator_unittest.cc b/components/performance_manager/v8_memory/v8_per_frame_memory_decorator_unittest.cc index e11cc6a..181a4a07 100644 --- a/components/performance_manager/v8_memory/v8_per_frame_memory_decorator_unittest.cc +++ b/components/performance_manager/v8_memory/v8_per_frame_memory_decorator_unittest.cc
@@ -29,6 +29,7 @@ #include "content/public/test/navigation_simulator.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/tokens/tokens.h" #include "url/gurl.h" namespace performance_manager { @@ -212,7 +213,7 @@ }; void AddPerFrameIsolateMemoryUsage( - FrameToken frame_token, + const blink::LocalFrameToken& frame_token, int64_t world_id, uint64_t bytes_used, blink::mojom::PerProcessV8MemoryUsageData* data) { @@ -490,8 +491,8 @@ { auto data = blink::mojom::PerProcessV8MemoryUsageData::New(); // Add data for an unknown frame. - AddPerFrameIsolateMemoryUsage(FrameToken(base::UnguessableToken::Create()), - 0, 1024u, data.get()); + AddPerFrameIsolateMemoryUsage(blink::LocalFrameToken(), 0, 1024u, + data.get()); ExpectBindAndRespondToQuery(&reporter, std::move(data)); } @@ -511,11 +512,11 @@ // Create a couple of frames with specified IDs. auto page = CreateNode<PageNodeImpl>(); - FrameToken frame1_id = FrameToken(base::UnguessableToken::Create()); + blink::LocalFrameToken frame1_id = blink::LocalFrameToken(); auto frame1 = CreateNode<FrameNodeImpl>(process.get(), page.get(), nullptr, 1, 2, frame1_id); - FrameToken frame2_id = FrameToken(base::UnguessableToken::Create()); + blink::LocalFrameToken frame2_id = blink::LocalFrameToken(); auto frame2 = CreateNode<FrameNodeImpl>(process.get(), page.get(), nullptr, 3, 4, frame2_id); { @@ -542,8 +543,8 @@ { auto data = blink::mojom::PerProcessV8MemoryUsageData::New(); AddPerFrameIsolateMemoryUsage(frame1_id, 0, 1003u, data.get()); - AddPerFrameIsolateMemoryUsage(FrameToken(base::UnguessableToken::Create()), - 0, 2233u, data.get()); + AddPerFrameIsolateMemoryUsage(blink::LocalFrameToken(), 0, 2233u, + data.get()); ExpectQueryAndReply(&reporter, std::move(data)); } task_env().FastForwardBy(kMinTimeBetweenRequests); @@ -1142,7 +1143,7 @@ content::RenderFrameHost* main_frame = web_contents()->GetMainFrame(); ASSERT_NE(nullptr, main_frame); const RenderProcessHostId process_id(main_frame->GetProcess()->GetID()); - const FrameToken frame_token(main_frame->GetFrameToken()); + const blink::LocalFrameToken frame_token(main_frame->GetFrameToken()); const content::GlobalFrameRoutingId frame_id(process_id.value(), main_frame->GetRoutingID());
diff --git a/components/performance_manager/worker_watcher.cc b/components/performance_manager/worker_watcher.cc index af09c71..1fb8469c 100644 --- a/components/performance_manager/worker_watcher.cc +++ b/components/performance_manager/worker_watcher.cc
@@ -155,7 +155,7 @@ auto worker_node = PerformanceManagerImpl::CreateWorkerNode( browser_context_id_, WorkerNode::WorkerType::kDedicated, process_node_source_->GetProcessNode(worker_process_id), - WorkerToken(dedicated_worker_token.value())); + dedicated_worker_token); auto insertion_result = dedicated_worker_nodes_.emplace( dedicated_worker_token, std::move(worker_node)); DCHECK(insertion_result.second); @@ -202,7 +202,7 @@ auto worker_node = PerformanceManagerImpl::CreateWorkerNode( browser_context_id_, WorkerNode::WorkerType::kShared, process_node_source_->GetProcessNode(worker_process_id), - WorkerToken(shared_worker_token.value())); + shared_worker_token); bool inserted = shared_worker_nodes_.emplace(shared_worker_token, std::move(worker_node)) @@ -259,7 +259,7 @@ auto worker_node = PerformanceManagerImpl::CreateWorkerNode( browser_context_id_, WorkerNode::WorkerType::kService, process_node_source_->GetProcessNode(running_info.render_process_id), - WorkerToken(running_info.token.value())); + running_info.token); bool inserted = service_worker_nodes_.emplace(version_id, std::move(worker_node)).second; DCHECK(inserted);
diff --git a/components/performance_manager/worker_watcher_unittest.cc b/components/performance_manager/worker_watcher_unittest.cc index 7ec634d..121cb84 100644 --- a/components/performance_manager/worker_watcher_unittest.cc +++ b/components/performance_manager/worker_watcher_unittest.cc
@@ -551,7 +551,7 @@ frame_id); auto frame_node = PerformanceManagerImpl::CreateFrameNode( process_node, page_node_.get(), nullptr, 0, frame_id, - FrameToken(base::UnguessableToken::Create()), 0, 0); + blink::LocalFrameToken(), 0, 0); bool inserted = frame_node_map_.insert({render_frame_host_id, std::move(frame_node)})
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index 96394b42..b0b6631 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc
@@ -321,8 +321,7 @@ } } -void WebViewPlugin::WebViewHelper::StartDragging(network::mojom::ReferrerPolicy, - const WebDragData&, +void WebViewPlugin::WebViewHelper::StartDragging(const WebDragData&, WebDragOperationsMask, const SkBitmap&, const gfx::Point&) {
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index 86580aa6..d721486 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h
@@ -176,8 +176,7 @@ void DidInvalidateRect(const blink::WebRect&) override; // WebWidgetClient methods: - void StartDragging(network::mojom::ReferrerPolicy, - const blink::WebDragData&, + void StartDragging(const blink::WebDragData&, blink::WebDragOperationsMask, const SkBitmap&, const gfx::Point&) override;
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 09ea3e0d..81ccac2 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -1035,6 +1035,8 @@ 'NativePrintersBulkAccessMode', 'NativePrintersBulkBlacklist', 'NativePrintersBulkWhitelist', + 'Printers', + 'PrintersBulkConfiguration', 'DeviceNativePrinters', 'DeviceNativePrintersAccessMode', 'DeviceNativePrintersBlacklist', @@ -14948,6 +14950,7 @@ 'dynamic_refresh': True, 'per_profile': True, }, + 'deprecated': True, # example_value is split onto multiple lines here for readability, but the # 'type': 'list' above means that each element has to fit inside a single- # line textbox in the GPO UI - so the example string is a single line. @@ -14979,6 +14982,83 @@ This policy has no effect on whether users can configure printers on individual devices. It is intended to be supplementary to the configuration of printers by individual users. For Active Directory managed devices this policy supports expansion of <ph name="MACHINE_NAME_VARIABLE">${MACHINE_NAME[,pos[,count]]}</ph> to the Active Directory machine name or a substring of it. For example, if the machine name is <ph name="MACHINE_NAME_EXAMPLE">CHROMEBOOK</ph>, then <ph name="MACHINE_NAME_VARIABLE_EXAMPLE">${MACHINE_NAME,6,4}</ph> would be replaced by the 4 characters starting after the 6th position, i.e. <ph name="MACHINE_NAME_PART_EXAMPLE">BOOK</ph>. Note that the position is zero-based. + + This policy is deprecated, please use <ph name="PRINTERS_POLICY_NAME">Printers</ph> instead. + ''', + }, + { + 'name': 'Printers', + 'owners': ['file://chromeos/printing/OWNERS'], + 'type': 'list', + 'schema': { + 'type': 'array', + 'items': { 'type': 'string' }, + }, + 'validation_schema': { + 'type': 'array', + 'items': { + 'type': 'object', + 'id': 'PrinterTypeInclusive', + 'properties': { + 'display_name': { 'type': 'string' }, + 'description': { 'type': 'string' }, + 'manufacturer': { 'type': 'string' }, + 'model': { 'type': 'string' }, + 'uri': { 'type': 'string' }, + 'uuid': { 'type': 'string' }, + 'ppd_resource': { + 'type': 'object', + 'id': 'PpdResourceInclusive', + 'properties': { + 'effective_model': { + 'type': 'string', + 'description': 'This field must match one of the strings which represent a <ph name="PRODUCT_NAME">$2<ex>Google Chrome OS</ex></ph> supported printer. The string will be used to identify and install the appropriate PPD for the printer. More information can be found at https://support.google.com/chrome?p=noncloudprint.' + }, + 'autoconf': { + 'type': 'boolean', + 'description': 'Boolean flag indicating whether IPP Everywhere should be used to set up the printer.' + } + } + } + } + } + }, + 'supported_on': [ 'chrome_os:86-' ], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + # example_value is split onto multiple lines here for readability, but the + # 'type': 'list' above means that each element has to fit inside a single- + # line textbox in the GPO UI - so the example string is a single line. + 'example_value': [ + '{ ' + '"display_name": "Color Laser", ' + '"description": "The printer next to the water cooler.", ' + '"manufacturer": "Printer Manufacturer", ' + '"model": "Color Laser 2004", ' + '"uri": "ipps://print-server.intranet.example.com:443/ipp/cl2k4", ' + '"uuid": "1c395fdb-5d93-4904-b246-b2c046e79d12", ' + '"ppd_resource": { "effective_model": "Printer Manufacturer ColorLaser2k4", "autoconf": false } ' + '}' + ], + 'id': 769, + 'caption': '''Configures a list of printers''', + 'tags': [], + 'desc': '''Configures a list of printers. + + This policy allows administrators to provide printer configurations for + their users. + + <ph name="PRINTER_DISPLAY_NAME">display_name</ph> and <ph name="PRINTER_DESCRIPTION">description</ph> are free-form strings that can be customized for ease of printer selection. <ph name="PRINTER_MANUFACTURER">manufacturer</ph> and <ph name="PRINTER_MODEL">model</ph> serve to ease printer identification by end users. They represent the manufacturer and model of the printer. <ph name="PRINTER_URI">uri</ph> should be an address reachable from a client computer including the <ph name="URI_SCHEME">scheme</ph>, <ph name="URI_PORT">port</ph>, and <ph name="URI_QUEUE">queue</ph>. <ph name="PRINTER_UUID">uuid</ph> is optional. If provided, it is used to help deduplicate <ph name="ZEROCONF_DISCOVERY">zeroconf</ph> printers. + + Either <ph name="PRINTER_EFFECTIVE_MODEL">effective_model</ph> should contain the name of the printer or <ph name="PRINTER_AUTOCONF">autoconf</ph> should be set to true. The printers with both or without any properties will be ignored. + + Printer setup is completed upon the first use of a printer. PPDs are not downloaded until the printer is used. After that time, frequently used PPDs are cached. + + This policy has no effect on whether users can configure printers on individual devices. It is intended to be supplementary to the configuration of printers by individual users. + + For Active Directory managed devices this policy supports expansion of <ph name="MACHINE_NAME_VARIABLE">${MACHINE_NAME[,pos[,count]]}</ph> to the Active Directory machine name or a substring of it. For example, if the machine name is <ph name="MACHINE_NAME_EXAMPLE">CHROMEBOOK</ph>, then <ph name="MACHINE_NAME_VARIABLE_EXAMPLE">${MACHINE_NAME,6,4}</ph> would be replaced by the 4 characters starting after the 6th position, i.e. <ph name="MACHINE_NAME_PART_EXAMPLE">BOOK</ph>. Note that the position is zero-based. ''', }, { @@ -14998,6 +15078,7 @@ 'dynamic_refresh': True, 'per_profile': True, }, + 'deprecated': True, 'example_value': { "url": "https://example.com/printerpolicy", "hash": "deadbeefdeadbeefdeadbeefdeadbeefdeafdeadbeefdeadbeef" @@ -15018,7 +15099,46 @@ If you set this policy, users cannot change or override it. This policy has no effect on whether users can configure printers on individual devices. It is intended to be supplementary to the configuration of printers by individual users. - ''', + + This policy is deprecated, please use <ph name="PRINTERS_BULK_CONFIGURATION">PrintersBulkConfiguration</ph> instead.''', + }, + { + 'name': 'PrintersBulkConfiguration', + 'owners': ['file://chromeos/printing/OWNERS'], + 'id': 770, + 'type': 'external', + 'schema': { + 'type': 'object', + 'properties': { + 'url': { 'type': 'string' }, + 'hash': { 'type': 'string' } + }, + }, + 'supported_on': ['chrome_os:86-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, + }, + 'example_value': { + "url": "https://example.com/printerpolicy", + "hash": "deadbeefdeadbeefdeadbeefdeadbeefdeafdeadbeefdeadbeef" + }, + 'max_size': 5242880, + 'caption': '''Enterprise printer configuration file''', + 'tags': [], + 'desc': '''Provides configurations for enterprise printers. + + This policy allows you to provide printer configurations to <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> devices. The format is the same as the <ph name="PRINTERS_POLICY_NAME">Printers</ph> dictionary, with an additional required "id" or "guid" field per printer for allowing or blocking. + + The size of the file must not exceed 5MB and must be encoded in JSON. It is estimated that a file containing approximately 21,000 printers will encode as a 5MB file. The cryptographic hash is used to verify the integrity of the download. + + The file is downloaded and cached. It will be re-downloaded whenever the URL or the hash changes. + + If this policy is set, <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> will download the file for printer configurations and make printers available in accordance with <ph name="PRINTERS_BULK_ACCESS_MODE">PrintersBulkAccessMode</ph>, <ph name="PRINTERS_BULK_ALLOWLIST">PrintersBulkAllowlist</ph>, and <ph name="PRINTERS_BULK_BLOCKLIST">PrintersBulkBlocklist</ph>. + + If you set this policy, users cannot change or override it. + + This policy has no effect on whether users can configure printers on individual devices. It is intended to be supplementary to the configuration of printers by individual users.''', }, { 'name': 'NativePrintersBulkAccessMode', @@ -23819,6 +23939,6 @@ ], 'placeholders': [], 'deleted_policy_ids': [412, 476, 546, 562, 569, 578], - 'highest_id_currently_used': 768, + 'highest_id_currently_used': 770, 'highest_atomic_group_id_currently_used': 40 }
diff --git a/components/policy/tools/syntax_check_policy_template_json.py b/components/policy/tools/syntax_check_policy_template_json.py index 76ceb00..362b823 100755 --- a/components/policy/tools/syntax_check_policy_template_json.py +++ b/components/policy/tools/syntax_check_policy_template_json.py
@@ -63,6 +63,7 @@ 'DeviceLoginScreenAutoSelectCertificateForUrls', 'DeviceOpenNetworkConfiguration', 'NativePrinters', + 'Printers', 'OpenNetworkConfiguration', 'RemoteAccessHostDebugOverridePolicies', # NOTE: Do not add any new policies to this list! Do not store policies with
diff --git a/components/printing/browser/print_manager.cc b/components/printing/browser/print_manager.cc index d5426757..2f1ee9b4 100644 --- a/components/printing/browser/print_manager.cc +++ b/components/printing/browser/print_manager.cc
@@ -27,7 +27,7 @@ manager->OnScriptedPrint(render_frame_host, scripted_params, reply_msg); } - void OnDidPrintDocument(const PrintHostMsg_DidPrintDocument_Params& params, + void OnDidPrintDocument(const mojom::DidPrintDocumentParams& params, IPC::Message* reply_msg) { // If DidPrintDocument message was received then need to transition from // a variable allocated on stack (which has efficient memory management @@ -74,7 +74,8 @@ } PrintManager::PrintManager(content::WebContents* contents) - : content::WebContentsObserver(contents) {} + : content::WebContentsObserver(contents), + print_manager_host_receivers_(contents, this) {} PrintManager::~PrintManager() = default; @@ -84,8 +85,6 @@ FrameDispatchHelper helper = {this, render_frame_host}; bool handled = true; IPC_BEGIN_MESSAGE_MAP(PrintManager, message) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount, - OnDidGetPrintedPagesCount) IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetDocumentCookie, OnDidGetDocumentCookie) IPC_MESSAGE_FORWARD_DELAY_REPLY( @@ -107,8 +106,8 @@ print_render_frames_.erase(render_frame_host); } -void PrintManager::OnDidGetPrintedPagesCount(int cookie, - int number_pages) { +void PrintManager::DidGetPrintedPagesCount(int32_t cookie, + int32_t number_pages) { DCHECK_GT(cookie, 0); DCHECK_GT(number_pages, 0); number_pages_ = number_pages;
diff --git a/components/printing/browser/print_manager.h b/components/printing/browser/print_manager.h index 8e9e9352..b215ea8 100644 --- a/components/printing/browser/print_manager.h +++ b/components/printing/browser/print_manager.h
@@ -12,6 +12,7 @@ #include "build/build_config.h" #include "components/printing/common/print.mojom.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_receiver_set.h" #include "mojo/public/cpp/bindings/associated_remote.h" #if defined(OS_ANDROID) @@ -22,12 +23,12 @@ class Message; } -struct PrintHostMsg_DidPrintDocument_Params; struct PrintHostMsg_ScriptedPrint_Params; namespace printing { -class PrintManager : public content::WebContentsObserver { +class PrintManager : public content::WebContentsObserver, + public mojom::PrintManagerHost { public: ~PrintManager() override; @@ -39,6 +40,9 @@ virtual void PdfWritingDone(int page_count) = 0; #endif + // printing::mojom::PrintManager: + void DidGetPrintedPagesCount(int32_t cookie, int32_t number_pages) override; + protected: explicit PrintManager(content::WebContents* contents); @@ -86,10 +90,9 @@ }; // IPC handlers - virtual void OnDidGetPrintedPagesCount(int cookie, int number_pages); virtual void OnDidPrintDocument( content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPrintDocument_Params& params, + const mojom::DidPrintDocumentParams& params, std::unique_ptr<DelayedFrameDispatchHelper> helper) = 0; virtual void OnGetDefaultPrintSettings( content::RenderFrameHost* render_frame_host, @@ -117,6 +120,9 @@ mojo::AssociatedRemote<printing::mojom::PrintRenderFrame>> print_render_frames_; + content::WebContentsFrameReceiverSet<printing::mojom::PrintManagerHost> + print_manager_host_receivers_; + DISALLOW_COPY_AND_ASSIGN(PrintManager); };
diff --git a/components/printing/common/print.mojom b/components/printing/common/print.mojom index 65e43c17..948c866 100644 --- a/components/printing/common/print.mojom +++ b/components/printing/common/print.mojom
@@ -139,6 +139,20 @@ uint32 pages_per_sheet = 1; }; +// Parameters to describe a rendered page. +struct DidPrintDocumentParams { + // Document's content including metafile data and subframe info. + DidPrintContentParams content; + // Cookie for the document to ensure correctness. + int32 document_cookie; + // The size of the page the page author specified. + gfx.mojom.Size page_size; + // The printable area the page author specified. + gfx.mojom.Rect content_area; + // The physical offsets of the printer in DPI. Used for PS printing. + gfx.mojom.Point physical_offsets; +}; + // Interface implemented by a class that desires to render print documents for // Chrome print preview. interface PrintRenderer { @@ -225,3 +239,11 @@ // particular node, depending on which mode the RenderFrame is in. PrintNodeUnderContextMenu(); }; + +// Browser process interface exposed to the renderer to handle the general +// print management. +interface PrintManagerHost { + // Tells the browser that the renderer is done calculating the number of + // rendered pages according to the specified settings. + DidGetPrintedPagesCount(int32 cookie, int32 number_pages); +};
diff --git a/components/printing/common/print_messages.h b/components/printing/common/print_messages.h index 2934287..805ceb0 100644 --- a/components/printing/common/print_messages.h +++ b/components/printing/common/print_messages.h
@@ -258,22 +258,22 @@ #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) // Parameters to describe a rendered page. -IPC_STRUCT_BEGIN(PrintHostMsg_DidPrintDocument_Params) +IPC_STRUCT_TRAITS_BEGIN(printing::mojom::DidPrintDocumentParams) // Document's content including metafile data and subframe info. - IPC_STRUCT_MEMBER(printing::mojom::DidPrintContentParams, content) + IPC_STRUCT_TRAITS_MEMBER(content) // Cookie for the document to ensure correctness. - IPC_STRUCT_MEMBER(int, document_cookie) + IPC_STRUCT_TRAITS_MEMBER(document_cookie) // The size of the page the page author specified. - IPC_STRUCT_MEMBER(gfx::Size, page_size) + IPC_STRUCT_TRAITS_MEMBER(page_size) // The printable area the page author specified. - IPC_STRUCT_MEMBER(gfx::Rect, content_area) + IPC_STRUCT_TRAITS_MEMBER(content_area) // The physical offsets of the printer in DPI. Used for PS printing. - IPC_STRUCT_MEMBER(gfx::Point, physical_offsets) -IPC_STRUCT_END() + IPC_STRUCT_TRAITS_MEMBER(physical_offsets) +IPC_STRUCT_TRAITS_END() // TODO(dgn) Rename *ScriptedPrint messages because they are not called only // from scripts. @@ -290,12 +290,6 @@ // Messages sent from the renderer to the browser. -// Tells the browser that the renderer is done calculating the number of -// rendered pages according to the specified settings. -IPC_MESSAGE_ROUTED2(PrintHostMsg_DidGetPrintedPagesCount, - int /* rendered document cookie */, - int /* number of rendered pages */) - // Sends the document cookie of the current printer query to the browser. IPC_MESSAGE_ROUTED1(PrintHostMsg_DidGetDocumentCookie, int /* rendered document cookie */) @@ -308,7 +302,7 @@ // this message is already valid in the browser process. Waits until the // document is complete ready before replying. IPC_SYNC_MESSAGE_ROUTED1_1(PrintHostMsg_DidPrintDocument, - PrintHostMsg_DidPrintDocument_Params + printing::mojom::DidPrintDocumentParams /* page content */, bool /* completed */)
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index 75637e6..b911872 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -41,6 +41,7 @@ #include "printing/metafile_skia.h" #include "printing/mojom/print.mojom.h" #include "printing/units.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/common/css/page_orientation.h" #include "third_party/blink/public/mojom/frame/frame_owner_element_type.mojom.h" @@ -1094,6 +1095,15 @@ g_is_preview_enabled = false; } +const mojo::AssociatedRemote<mojom::PrintManagerHost>& +PrintRenderFrameHelper::GetPrintManagerHost() { + if (!print_manager_host_) { + render_frame()->GetRemoteAssociatedInterfaces()->GetInterface( + &print_manager_host_); + } + return print_manager_host_; +} + bool PrintRenderFrameHelper::IsScriptInitiatedPrintAllowed( blink::WebLocalFrame* frame, bool user_initiated) { @@ -1921,8 +1931,8 @@ // TODO(vitalybuka): should be page_count or valid pages from params.pages. // See http://crbug.com/161576 - Send(new PrintHostMsg_DidGetPrintedPagesCount( - routing_id(), print_params.document_cookie, page_count)); + GetPrintManagerHost()->DidGetPrintedPagesCount(print_params.document_cookie, + page_count); if (print_params.preview_ui_id < 0) { // Printing for system dialog. @@ -1968,7 +1978,8 @@ snapshotter->Snapshot(ui::AXMode::kPDF, 0, &metafile.accessibility_tree()); } - PrintHostMsg_DidPrintDocument_Params page_params; + mojom::DidPrintDocumentParams page_params; + page_params.content = mojom::DidPrintContentParams::New(); gfx::Size* page_size_in_dpi; gfx::Rect* content_area_in_dpi; #if defined(OS_APPLE) || defined(OS_WIN) @@ -1992,7 +2003,8 @@ metafile.FinishDocument(); - if (!CopyMetafileDataToReadOnlySharedMem(metafile, &page_params.content)) { + if (!CopyMetafileDataToReadOnlySharedMem(metafile, + page_params.content.get())) { return false; }
diff --git a/components/printing/renderer/print_render_frame_helper.h b/components/printing/renderer/print_render_frame_helper.h index 6ad711f..b5ec1df 100644 --- a/components/printing/renderer/print_render_frame_helper.h +++ b/components/printing/renderer/print_render_frame_helper.h
@@ -138,6 +138,8 @@ // |is_pdf| is false, and 1.0f otherwise. static double GetScaleFactor(double input_scale_factor, bool is_pdf); + const mojo::AssociatedRemote<mojom::PrintManagerHost>& GetPrintManagerHost(); + private: friend class PrintRenderFrameHelperTestBase; FRIEND_TEST_ALL_PREFIXES(MAYBE_PrintRenderFrameHelperPreviewTest, @@ -638,6 +640,8 @@ // parameters so that it can be invoked after DidStopLoading. base::OnceClosure on_stop_loading_closure_; + mojo::AssociatedRemote<mojom::PrintManagerHost> print_manager_host_; + base::WeakPtrFactory<PrintRenderFrameHelper> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(PrintRenderFrameHelper);
diff --git a/components/printing/test/mock_printer.cc b/components/printing/test/mock_printer.cc index 130b3b0..6ad0ff7 100644 --- a/components/printing/test/mock_printer.cc +++ b/components/printing/test/mock_printer.cc
@@ -201,7 +201,7 @@ } void MockPrinter::PrintPage( - const PrintHostMsg_DidPrintDocument_Params& params) { + const printing::mojom::DidPrintDocumentParams& params) { // Verify the input parameter and update the printer status so that the // RenderViewTest class can verify the this function finishes without errors. EXPECT_EQ(PRINTER_PRINTING, printer_status_); @@ -209,9 +209,9 @@ #if defined(OS_WIN) || defined(OS_APPLE) // Load the data sent from a RenderView object and create a PageData object. - ASSERT_TRUE(params.content.metafile_data_region.IsValid()); + ASSERT_TRUE(params.content->metafile_data_region.IsValid()); base::ReadOnlySharedMemoryMapping mapping = - params.content.metafile_data_region.Map(); + params.content->metafile_data_region.Map(); ASSERT_TRUE(mapping.IsValid()); EXPECT_GT(mapping.size(), 0U);
diff --git a/components/printing/test/mock_printer.h b/components/printing/test/mock_printer.h index fa974d9..9e84fec 100644 --- a/components/printing/test/mock_printer.h +++ b/components/printing/test/mock_printer.h
@@ -21,7 +21,6 @@ #include "ui/gfx/geometry/size.h" struct PrintMsg_PrintPages_Params; -struct PrintHostMsg_DidPrintDocument_Params; // A class which represents an output page used in the MockPrinter class. // The MockPrinter class stores output pages in a vector, so, this class @@ -89,7 +88,7 @@ const gfx::Size& page_size, int scale_factor); void SetPrintedPagesCount(int cookie, int number_pages); - void PrintPage(const PrintHostMsg_DidPrintDocument_Params& params); + void PrintPage(const printing::mojom::DidPrintDocumentParams& params); // Functions that retrieve the output pages. Status GetPrinterStatus() const { return printer_status_; }
diff --git a/components/printing/test/print_mock_render_thread.cc b/components/printing/test/print_mock_render_thread.cc index c11598b9..4da7c576 100644 --- a/components/printing/test/print_mock_render_thread.cc +++ b/components/printing/test/print_mock_render_thread.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include "base/run_loop.h" #include "base/values.h" #include "build/build_config.h" #include "components/printing/common/print.mojom.h" @@ -28,8 +29,7 @@ { } -PrintMockRenderThread::~PrintMockRenderThread() { -} +PrintMockRenderThread::~PrintMockRenderThread() = default; scoped_refptr<base::SingleThreadTaskRunner> PrintMockRenderThread::GetIOTaskRunner() { @@ -45,6 +45,10 @@ if (content::MockRenderThread::OnMessageReceived(msg)) return true; + // Gives a chance to handle Mojo interfaces as some messages has been + // converted to Mojo. + base::RunLoop().RunUntilIdle(); + // Some messages we do special handling. bool handled = true; IPC_BEGIN_MESSAGE_MAP(PrintMockRenderThread, msg) @@ -53,8 +57,6 @@ OnGetDefaultPrintSettings) IPC_MESSAGE_HANDLER(PrintHostMsg_ScriptedPrint, OnScriptedPrint) IPC_MESSAGE_HANDLER(PrintHostMsg_UpdatePrintSettings, OnUpdatePrintSettings) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidGetPrintedPagesCount, - OnDidGetPrintedPagesCount) IPC_MESSAGE_HANDLER_DELAY_REPLY(PrintHostMsg_DidPrintDocument, OnDidPrintDocument) #if BUILDFLAG(ENABLE_PRINT_PREVIEW) @@ -90,7 +92,7 @@ } void PrintMockRenderThread::OnDidPrintDocument( - const PrintHostMsg_DidPrintDocument_Params& params, + const printing::mojom::DidPrintDocumentParams& params, IPC::Message* reply_msg) { printer_->PrintPage(params); PrintHostMsg_DidPrintDocument::WriteReplyParams(reply_msg, true);
diff --git a/components/printing/test/print_mock_render_thread.h b/components/printing/test/print_mock_render_thread.h index 8664622..8765e4c 100644 --- a/components/printing/test/print_mock_render_thread.h +++ b/components/printing/test/print_mock_render_thread.h
@@ -25,7 +25,6 @@ } class MockPrinter; -struct PrintHostMsg_DidPrintDocument_Params; struct PrintHostMsg_PreviewIds; struct PrintHostMsg_ScriptedPrint_Params; struct PrintMsg_PrintPages_Params; @@ -63,6 +62,8 @@ const std::vector<std::pair<int, uint32_t>>& print_preview_pages() const; #endif + MockPrinter* GetPrinter() { return printer_.get(); } + private: // Overrides base class implementation to add custom handling for print bool OnMessageReceived(const IPC::Message& msg) override; @@ -76,7 +77,7 @@ PrintMsg_PrintPages_Params* settings); void OnDidGetPrintedPagesCount(int cookie, int number_pages); - void OnDidPrintDocument(const PrintHostMsg_DidPrintDocument_Params& params, + void OnDidPrintDocument(const printing::mojom::DidPrintDocumentParams& params, IPC::Message* reply_msg); #if BUILDFLAG(ENABLE_PRINT_PREVIEW) void OnDidStartPreview(const printing::mojom::DidStartPreviewParams& params,
diff --git a/components/printing/test/print_render_frame_helper_browsertest.cc b/components/printing/test/print_render_frame_helper_browsertest.cc index 3447036..32b5fae 100644 --- a/components/printing/test/print_render_frame_helper_browsertest.cc +++ b/components/printing/test/print_render_frame_helper_browsertest.cc
@@ -17,6 +17,7 @@ #include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "components/printing/common/print.mojom-test-utils.h" #include "components/printing/common/print.mojom.h" #include "components/printing/common/print_messages.h" #include "components/printing/test/mock_printer.h" @@ -31,6 +32,7 @@ #include "printing/print_job_constants.h" #include "printing/units.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/input/web_mouse_event.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -209,6 +211,46 @@ }; #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) +class TestPrintManagerHost + : public mojom::PrintManagerHostInterceptorForTesting { + public: + TestPrintManagerHost(content::RenderView* view, MockPrinter* printer) + : printer_(printer) { + Init(view); + } + ~TestPrintManagerHost() override = default; + + // mojom::PrintManagerInterceptorForTesting + mojom::PrintManagerHost* GetForwardingInterface() override { return nullptr; } + void DidGetPrintedPagesCount(int32_t cookie, int32_t number_pages) override { + if (number_pages_ > 0) + EXPECT_EQ(number_pages, number_pages_); + printer_->SetPrintedPagesCount(cookie, number_pages); + } + + void SetExpectedPagesCount(int32_t number_pages) { + number_pages_ = number_pages; + } + + private: + void Init(content::RenderView* view) { + content::RenderFrame* main_frame = view->GetMainRenderFrame(); + main_frame->GetRemoteAssociatedInterfaces()->OverrideBinderForTesting( + mojom::PrintManagerHost::Name_, + base::BindRepeating(&TestPrintManagerHost::BindPrintManagerReceiver, + base::Unretained(this))); + } + + void BindPrintManagerReceiver(mojo::ScopedInterfaceEndpointHandle handle) { + receiver_.Bind(mojo::PendingAssociatedReceiver<mojom::PrintManagerHost>( + std::move(handle))); + } + + int32_t number_pages_ = -1; + MockPrinter* printer_; + mojo::AssociatedReceiver<mojom::PrintManagerHost> receiver_{this}; +}; + } // namespace class PrintRenderFrameHelperTestBase : public content::RenderViewTest { @@ -228,6 +270,8 @@ static_cast<PrintMockRenderThread*>(render_thread_.get()); content::RenderViewTest::SetUp(); + print_manager_ = std::make_unique<TestPrintManagerHost>( + view_, print_render_thread_->GetPrinter()); } void TearDown() override { @@ -245,26 +289,6 @@ base::RunLoop().RunUntilIdle(); } - // The renderer should be done calculating the number of rendered pages - // according to the specified settings defined in the mock render thread. - // Verify the page count is correct. - void VerifyPageCount(int expected_count) { -#if defined(OS_CHROMEOS) - // The DidGetPrintedPagesCount message isn't sent on ChromeOS. Right now we - // always print all pages, and there are checks to that effect built into - // the print code. -#else - const IPC::Message* page_cnt_msg = - render_thread_->sink().GetUniqueMessageMatching( - PrintHostMsg_DidGetPrintedPagesCount::ID); - ASSERT_TRUE(page_cnt_msg); - PrintHostMsg_DidGetPrintedPagesCount::Param post_page_count_param; - PrintHostMsg_DidGetPrintedPagesCount::Read(page_cnt_msg, - &post_page_count_param); - EXPECT_EQ(expected_count, std::get<1>(post_page_count_param)); -#endif // defined(OS_CHROMEOS) - } - #if BUILDFLAG(ENABLE_PRINT_PREVIEW) void BindToFakePrintPreviewUI() { PrintRenderFrameHelper* frame_helper = GetPrintRenderFrameHelper(); @@ -401,6 +425,7 @@ } PrintMockRenderThread* print_render_thread() { return print_render_thread_; } + TestPrintManagerHost* print_manager() { return print_manager_.get(); } #if BUILDFLAG(ENABLE_PRINT_PREVIEW) FakePrintPreviewUI* preview_ui() { return &preview_ui_; } #endif @@ -412,6 +437,7 @@ // Naked pointer as ownership is with // |content::RenderViewTest::render_thread_|. PrintMockRenderThread* print_render_thread_ = nullptr; + std::unique_ptr<TestPrintManagerHost> print_manager_ = nullptr; DISALLOW_COPY_AND_ASSIGN(PrintRenderFrameHelperTestBase); }; @@ -454,8 +480,8 @@ // Unblock script initiated printing and verify printing works. GetPrintRenderFrameHelper()->scripting_throttler_.Reset(); print_render_thread()->printer()->ResetPrinter(); + print_manager()->SetExpectedPagesCount(1); PrintWithJavaScript(); - VerifyPageCount(1); VerifyPagesPrinted(true); } @@ -481,19 +507,19 @@ gfx::Size new_size(200, 100); Resize(new_size, false); + print_manager()->SetExpectedPagesCount(1); gfx::Rect bounds = GetElementBounds("print"); ClickMouseButton(bounds); base::RunLoop().RunUntilIdle(); - VerifyPageCount(1); VerifyPagesPrinted(true); } // Duplicate of OnPrintPagesTest only using javascript to print. TEST_F(MAYBE_PrintRenderFrameHelperTest, PrintWithJavascript) { + print_manager()->SetExpectedPagesCount(1); PrintWithJavaScript(); - VerifyPageCount(1); VerifyPagesPrinted(true); } @@ -501,10 +527,10 @@ TEST_F(MAYBE_PrintRenderFrameHelperTest, WindowPrintBeforePrintAfterPrint) { LoadHTML(kBeforeAfterPrintHtml); ExpectNoBeforeNoAfterPrintEvent(); + print_manager()->SetExpectedPagesCount(1); PrintWithJavaScript(); - VerifyPageCount(1); VerifyPagesPrinted(true); ExpectOneBeforeOneAfterPrintEvent(); } @@ -514,9 +540,10 @@ // that channel all works. TEST_F(MAYBE_PrintRenderFrameHelperTest, OnPrintPages) { LoadHTML(kHelloWorldHTML); + + print_manager()->SetExpectedPagesCount(1); OnPrintPages(); - VerifyPageCount(1); VerifyPagesPrinted(true); } @@ -524,9 +551,9 @@ LoadHTML(kBeforeAfterPrintHtml); ExpectNoBeforeNoAfterPrintEvent(); + print_manager()->SetExpectedPagesCount(1); OnPrintPages(); - VerifyPageCount(1); VerifyPagesPrinted(true); ExpectOneBeforeOneAfterPrintEvent(); }
diff --git a/components/security_interstitials_strings.grdp b/components/security_interstitials_strings.grdp index 002f5e60..d544cb6 100644 --- a/components/security_interstitials_strings.grdp +++ b/components/security_interstitials_strings.grdp
@@ -461,20 +461,6 @@ Hide advanced </message> - <!-- Safety Tip summary strings for Android (Desktop is in page_info_strings.grdp) --> - <message name="IDS_SAFETY_TIP_ANDROID_BAD_REPUTATION_LEAVE_BUTTON" desc="Text of button to ignore the warning on a suspicious page. Shown on the safety tip infobar."> - Leave site - </message> - <message name="IDS_SAFETY_TIP_ANDROID_LOOKALIKE_LEAVE_BUTTON" desc="Text of button to leave a suspicious page. Shown on the safety tip infobar. Answers the question 'Did you mean example.com?'."> - Yes, continue - </message> - <message name="IDS_SAFETY_TIP_ANDROID_LOOKALIKE_TITLE" desc="Title of Safety Tip infobar on a domain that looks like another domain."> - Did you mean <ph name='SUGGESTED_DOMAIN'>$1<ex>google.com</ex></ph>? - </message> - <message name="IDS_SAFETY_TIP_ANDROID_LOOKALIKE_DESCRIPTION" desc="Body of an infobar warning when the user visits a page that triggered a Safety Tip because the domain looked like another domain."> - Attackers sometimes mimic sites by making hard-to-see-changes to the web address. - </message> - <if expr="not is_ios"> <!-- Blocked interception interstitial strings --> <message name="IDS_BLOCKED_INTERCEPTION_HEADING" desc="Large heading of the known interception interstitial.">
diff --git a/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_BAD_REPUTATION_LEAVE_BUTTON.png.sha1 b/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_BAD_REPUTATION_LEAVE_BUTTON.png.sha1 deleted file mode 100644 index 2fac269..0000000 --- a/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_BAD_REPUTATION_LEAVE_BUTTON.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -91ca6866ec9f7d9573a06b040443017f59d7dac5 \ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_LOOKALIKE_DESCRIPTION.png.sha1 b/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_LOOKALIKE_DESCRIPTION.png.sha1 deleted file mode 100644 index 8c61417..0000000 --- a/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_LOOKALIKE_DESCRIPTION.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -4453a422a7c4f017b650fcc89af959b0385feab5 \ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_LOOKALIKE_LEAVE_BUTTON.png.sha1 b/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_LOOKALIKE_LEAVE_BUTTON.png.sha1 deleted file mode 100644 index 8c61417..0000000 --- a/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_LOOKALIKE_LEAVE_BUTTON.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -4453a422a7c4f017b650fcc89af959b0385feab5 \ No newline at end of file
diff --git a/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_LOOKALIKE_TITLE.png.sha1 b/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_LOOKALIKE_TITLE.png.sha1 deleted file mode 100644 index 8c61417..0000000 --- a/components/security_interstitials_strings_grdp/IDS_SAFETY_TIP_ANDROID_LOOKALIKE_TITLE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -4453a422a7c4f017b650fcc89af959b0385feab5 \ No newline at end of file
diff --git a/components/soda/constants.cc b/components/soda/constants.cc index 2e26687..8d4abca2 100644 --- a/components/soda/constants.cc +++ b/components/soda/constants.cc
@@ -11,14 +11,16 @@ namespace speech { -constexpr base::FilePath::CharType kSodaInstallationRelativePath[] = - FILE_PATH_LITERAL("SODA"); - +#ifdef OS_WIN +constexpr base::FilePath::CharType kSodaBinaryRelativePath[] = + FILE_PATH_LITERAL("SODAFiles/SODA.dll"); +#else constexpr base::FilePath::CharType kSodaBinaryRelativePath[] = FILE_PATH_LITERAL("SODAFiles/libsoda.so"); +#endif -constexpr base::FilePath::CharType kSodaEnUsConfigFileRelativePath[] = - FILE_PATH_LITERAL("SODAFiles/en_us/dictation.ascii_proto"); +constexpr base::FilePath::CharType kSodaInstallationRelativePath[] = + FILE_PATH_LITERAL("SODA"); const base::FilePath GetSodaDirectory() { base::FilePath components_dir; @@ -49,10 +51,4 @@ : soda_dir.Append(kSodaBinaryRelativePath); } -const base::FilePath GetSodaConfigPath() { - base::FilePath soda_dir = GetLatestSodaDirectory(); - return soda_dir.empty() ? base::FilePath() - : soda_dir.Append(kSodaEnUsConfigFileRelativePath); -} - } // namespace speech
diff --git a/components/soda/constants.h b/components/soda/constants.h index e0c61857..39310d6 100644 --- a/components/soda/constants.h +++ b/components/soda/constants.h
@@ -33,10 +33,6 @@ // installed. const base::FilePath GetSodaBinaryPath(); -// Get the path to the dictation.ascii_proto config file used by SODA. Returns -// an empty path if SODA is not installed. -const base::FilePath GetSodaConfigPath(); - } // namespace speech #endif // COMPONENTS_SODA_CONSTANTS_H_
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc index 9972076..1f19957 100644 --- a/components/sync/driver/profile_sync_service.cc +++ b/components/sync/driver/profile_sync_service.cc
@@ -1567,7 +1567,12 @@ } // Try to start up again (in transport-only mode). - startup_controller_->TryStart(/*force_immediate=*/true); + // TODO(crbug.com/1035874): There's no real need to delay the startup here, + // i.e. it should be fine to set force_immediate to true. However currently + // some tests depend on the startup *not* happening immediately (because + // they want to check that Sync (the feature) got disabled, which is hard to + // do if the engine starts up again immediately). + startup_controller_->TryStart(/*force_immediate=*/false); } }
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index 155d696..4e6dfdd 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -1038,6 +1038,7 @@ VISIT(arc_backup_and_restore_consent); VISIT(arc_location_service_consent); VISIT(arc_play_terms_of_service_consent); + VISIT(account_passwords_consent); } VISIT_PROTO_FIELDS( @@ -1072,6 +1073,13 @@ VISIT_ENUM(status); } +VISIT_PROTO_FIELDS( + const sync_pb::UserConsentTypes::AccountPasswordsConsent& proto) { + VISIT_REP(description_grd_ids); + VISIT(confirmation_grd_id); + VISIT_ENUM(status); +} + VISIT_PROTO_FIELDS(const sync_pb::UserEventSpecifics& proto) { VISIT(event_time_usec); VISIT(navigation_id);
diff --git a/components/sync/protocol/user_consent_specifics.proto b/components/sync/protocol/user_consent_specifics.proto index d6a8675..f990be6f 100644 --- a/components/sync/protocol/user_consent_specifics.proto +++ b/components/sync/protocol/user_consent_specifics.proto
@@ -57,6 +57,8 @@ UserConsentTypes.AssistantActivityControlConsent assistant_activity_control_consent = 14; + + UserConsentTypes.AccountPasswordsConsent account_passwords_consent = 15; } reserved "arc_metrics_and_usage_consent"; reserved 11;
diff --git a/components/sync/protocol/user_consent_types.proto b/components/sync/protocol/user_consent_types.proto index df9c044..9b1d34f 100644 --- a/components/sync/protocol/user_consent_types.proto +++ b/components/sync/protocol/user_consent_types.proto
@@ -136,4 +136,19 @@ // whether the consent was given or not given. optional ConsentStatus status = 2; } + + // The User Consent for downloading and using passwords stored in the user's + // Google Account. Determined during the opt-in flow for the feature. + message AccountPasswordsConsent { + // Ids of the strings of the consent text presented to the user. + repeated int32 description_grd_ids = 1; + + // Id of the string of the UI element the user clicked in order to confirm + // the consent dialog. + optional int32 confirmation_grd_id = 2; + + // The status of the consent. This specifies whether the consent was given + // or not given/revoked. + optional ConsentStatus status = 3; + } }
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index cc936f9..d991c21 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -20,8 +20,10 @@ "display/bsp_walk_action.h", "display/damage_frame_annotator.cc", "display/damage_frame_annotator.h", - "display/delegated_ink_point_renderer.cc", - "display/delegated_ink_point_renderer.h", + "display/delegated_ink_point_renderer_base.cc", + "display/delegated_ink_point_renderer_base.h", + "display/delegated_ink_point_renderer_skia.cc", + "display/delegated_ink_point_renderer_skia.h", "display/direct_renderer.cc", "display/direct_renderer.h", "display/display.cc",
diff --git a/components/viz/service/display/delegated_ink_point_renderer.cc b/components/viz/service/display/delegated_ink_point_renderer.cc deleted file mode 100644 index 366e5771..0000000 --- a/components/viz/service/display/delegated_ink_point_renderer.cc +++ /dev/null
@@ -1,30 +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/viz/service/display/delegated_ink_point_renderer.h" - -#include <utility> - -#include "base/trace_event/trace_event.h" - -namespace viz { - -DelegatedInkPointRendererImpl::DelegatedInkPointRendererImpl( - mojo::PendingReceiver<mojom::DelegatedInkPointRenderer> receiver) - : receiver_(this, std::move(receiver)) {} -DelegatedInkPointRendererImpl::~DelegatedInkPointRendererImpl() = default; - -void DelegatedInkPointRendererImpl::StoreDelegatedInkPoint( - const DelegatedInkPoint& point) { - TRACE_EVENT_INSTANT1( - "viz", - "DelegatedInkPointRendererImpl::StoreDelegatedInkPoint - " - "Point arrived in viz", - TRACE_EVENT_SCOPE_THREAD, "point", point.ToString()); - // TODO(1052145): Start storing these points in something to be used during - // |Display::DrawAndSwap()| to draw the delegated ink trail. These points will - // need to be cleared when |device_scale_factor_| changes. -} - -} // namespace viz
diff --git a/components/viz/service/display/delegated_ink_point_renderer.h b/components/viz/service/display/delegated_ink_point_renderer.h deleted file mode 100644 index d297a25..0000000 --- a/components/viz/service/display/delegated_ink_point_renderer.h +++ /dev/null
@@ -1,41 +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_VIZ_SERVICE_DISPLAY_DELEGATED_INK_POINT_RENDERER_H_ -#define COMPONENTS_VIZ_SERVICE_DISPLAY_DELEGATED_INK_POINT_RENDERER_H_ - -#include "components/viz/service/viz_service_export.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "services/viz/public/mojom/compositing/delegated_ink_point.mojom.h" - -namespace viz { - -// This class is used for rendering delegated ink trails on the end of strokes -// to reduce user perceived latency. On initialization, it binds the mojo -// interface required for receiving delegated ink points that are made and sent -// from the browser process. -// TODO(1052145): Expand on this comment as more functionality is added to this -// function - it will ultimately be where the rendering actually occurs. -// -// For more information on the feature, please see the explainer: -// https://github.com/WICG/ink-enhancement/blob/master/README.md -class VIZ_SERVICE_EXPORT DelegatedInkPointRendererImpl - : public mojom::DelegatedInkPointRenderer { - public: - explicit DelegatedInkPointRendererImpl( - mojo::PendingReceiver<mojom::DelegatedInkPointRenderer> receiver); - ~DelegatedInkPointRendererImpl() override; - DelegatedInkPointRendererImpl(const DelegatedInkPointRendererImpl&) = delete; - DelegatedInkPointRendererImpl& operator=( - const DelegatedInkPointRendererImpl&) = delete; - - void StoreDelegatedInkPoint(const DelegatedInkPoint& point) override; - - private: - mojo::Receiver<mojom::DelegatedInkPointRenderer> receiver_; -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_DELEGATED_INK_POINT_RENDERER_H_
diff --git a/components/viz/service/display/delegated_ink_point_renderer_base.cc b/components/viz/service/display/delegated_ink_point_renderer_base.cc new file mode 100644 index 0000000..a54d732a --- /dev/null +++ b/components/viz/service/display/delegated_ink_point_renderer_base.cc
@@ -0,0 +1,64 @@ +// 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/viz/service/display/delegated_ink_point_renderer_base.h" + +#include "base/trace_event/trace_event.h" +#include "components/viz/common/delegated_ink_metadata.h" + +namespace viz { + +DelegatedInkPointRendererBase::DelegatedInkPointRendererBase() = default; +DelegatedInkPointRendererBase::~DelegatedInkPointRendererBase() = default; + +void DelegatedInkPointRendererBase::InitMessagePipeline( + mojo::PendingReceiver<mojom::DelegatedInkPointRenderer> receiver) { + receiver_.Bind(std::move(receiver)); +} + +void DelegatedInkPointRendererBase::DrawDelegatedInkTrail() { + if (!metadata_) + return; + + DrawDelegatedInkTrailInternal(); + + // Always reset |metadata_| regardless of the outcome of + // DrawDelegatedInkPathInternal() so that the trail is never incorrectly + // drawn if the aggregated frame did not contain delegated ink metadata. + metadata_.reset(); +} + +void DelegatedInkPointRendererBase::FilterPoints() { + if (points_.size() == 0) + return; + + auto first_valid_point = points_.find(metadata_->timestamp()); + // It is possible that this results in |points_| being empty. This occurs when + // the points being forwarded from the browser process lose the race against + // the ink metadata arriving in Display, including the point that matches the + // metadata. There may still be old points in |points_| allowing execution to + // get here, but none of them match the metadata point, so they are all + // erased. + points_.erase(points_.begin(), first_valid_point); + + TRACE_EVENT_INSTANT1("viz", "Filtered points for delegated ink trail", + TRACE_EVENT_SCOPE_THREAD, "points", points_.size()); +} + +void DelegatedInkPointRendererBase::StoreDelegatedInkPoint( + const DelegatedInkPoint& point) { + TRACE_EVENT_INSTANT1("viz", + "DelegatedInkPointRendererImpl::StoreDelegatedInkPoint", + TRACE_EVENT_SCOPE_THREAD, "point", point.ToString()); + + // Fail-safe to prevent storing excessive points if they are being sent but + // never filtered and used, like if the renderer has stalled during a long + // running script. + if (points_.size() == kMaximumDelegatedInkPointsStored) + points_.erase(points_.begin()); + + points_.insert({point.timestamp(), point.point()}); +} + +} // namespace viz
diff --git a/components/viz/service/display/delegated_ink_point_renderer_base.h b/components/viz/service/display/delegated_ink_point_renderer_base.h new file mode 100644 index 0000000..a6b962d --- /dev/null +++ b/components/viz/service/display/delegated_ink_point_renderer_base.h
@@ -0,0 +1,79 @@ +// 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_VIZ_SERVICE_DISPLAY_DELEGATED_INK_POINT_RENDERER_BASE_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_DELEGATED_INK_POINT_RENDERER_BASE_H_ + +#include <map> +#include <memory> +#include <utility> + +#include "components/viz/service/viz_service_export.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "services/viz/public/mojom/compositing/delegated_ink_point.mojom.h" + +namespace viz { +class DelegatedInkMetadata; + +// The maximum number of delegated ink points that will be stored at a time. +// When this is hit, the oldest one will be removed each time a new one is +// added. +constexpr int kMaximumDelegatedInkPointsStored = 10; + +// This is the base class used for rendering delegated ink trails on the end of +// strokes to reduce user perceived latency. On initialization, it binds the +// mojo interface required for receiving delegated ink points that are made and +// sent from the browser process. +// +// For more information on the feature, please see the explainer: +// https://github.com/WICG/ink-enhancement/blob/master/README.md +class VIZ_SERVICE_EXPORT DelegatedInkPointRendererBase + : public mojom::DelegatedInkPointRenderer { + public: + DelegatedInkPointRendererBase(); + ~DelegatedInkPointRendererBase() override; + DelegatedInkPointRendererBase(const DelegatedInkPointRendererBase&) = delete; + DelegatedInkPointRendererBase& operator=( + const DelegatedInkPointRendererBase&) = delete; + + void InitMessagePipeline( + mojo::PendingReceiver<mojom::DelegatedInkPointRenderer> receiver); + + void StoreDelegatedInkPoint(const DelegatedInkPoint& point) override; + void SetDelegatedInkMetadata(std::unique_ptr<DelegatedInkMetadata> metadata) { + metadata_ = std::move(metadata); + } + + void DrawDelegatedInkTrail(); + + protected: + // |points_| is not emptied each time after the points are drawn, because one + // point in |points_| could potentially be drawn in more than one delegated + // ink trail. However, if a point has a timestamp that is earlier than the + // timestamp on the metadata, then the point has already been drawn, and + // therefore should be removed from |points_| before drawing. + void FilterPoints(); + + std::unique_ptr<DelegatedInkMetadata> metadata_; + std::map<base::TimeTicks, gfx::PointF> points_; + + private: + FRIEND_TEST_ALL_PREFIXES(DisplayTest, SkiaDelegatedInkRenderer); + + void virtual DrawDelegatedInkTrailInternal() = 0; + + const std::map<base::TimeTicks, gfx::PointF>& GetPointsMapForTest() const { + return points_; + } + + const DelegatedInkMetadata* GetMetadataForTest() const { + return metadata_.get(); + } + + mojo::Receiver<mojom::DelegatedInkPointRenderer> receiver_{this}; +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_DELEGATED_INK_POINT_RENDERER_BASE_H_
diff --git a/components/viz/service/display/delegated_ink_point_renderer_skia.cc b/components/viz/service/display/delegated_ink_point_renderer_skia.cc new file mode 100644 index 0000000..cc291339 --- /dev/null +++ b/components/viz/service/display/delegated_ink_point_renderer_skia.cc
@@ -0,0 +1,31 @@ +// 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/viz/service/display/delegated_ink_point_renderer_skia.h" + +#include "components/viz/common/delegated_ink_metadata.h" + +namespace viz { + +void DelegatedInkPointRendererSkia::DrawDelegatedInkTrailInternal() { + // First, filter the delegated ink points so that only ones that have a + // timestamp that is equal to or later than the metadata still exist. + FilterPoints(); + + if (points_.size() == 0) + return; + + // Prediction will occur here. The CL to move prediction to ui/base must land + // first in order for this to happen. + + // If there is only one point total between |points_| and predicted points, + // then it will match the metadata point and therefore doesn't need to be + // drawn in this way, as it will be rendered normally. + // TODO(1052145): Early out here if the above condition is met. + + // TODO(1052145): Draw the all remaining points in |points_| with bezier + // curves between them onto the skia canvas. +} + +} // namespace viz
diff --git a/components/viz/service/display/delegated_ink_point_renderer_skia.h b/components/viz/service/display/delegated_ink_point_renderer_skia.h new file mode 100644 index 0000000..34f5011 --- /dev/null +++ b/components/viz/service/display/delegated_ink_point_renderer_skia.h
@@ -0,0 +1,36 @@ +// 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_VIZ_SERVICE_DISPLAY_DELEGATED_INK_POINT_RENDERER_SKIA_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_DELEGATED_INK_POINT_RENDERER_SKIA_H_ + +#include "components/viz/service/display/delegated_ink_point_renderer_base.h" +#include "components/viz/service/viz_service_export.h" + +namespace viz { + +// This class handles drawing the delegated ink trail when the Skia renderer +// is in use by filtering everything out with timestamps before the metadata, +// predicting another point or two, and drawing the points with bezier curves +// between them with Skia commands onto the canvas provided by the Skia +// renderer, the |current_canvas_|. +// TODO(1052145): Specify exactly how many points are predicted. +// +// For more information on the feature, please see the explainer: +// https://github.com/WICG/ink-enhancement/blob/master/README.md +class VIZ_SERVICE_EXPORT DelegatedInkPointRendererSkia + : public DelegatedInkPointRendererBase { + public: + DelegatedInkPointRendererSkia() = default; + DelegatedInkPointRendererSkia(const DelegatedInkPointRendererSkia&) = delete; + DelegatedInkPointRendererSkia& operator=( + const DelegatedInkPointRendererSkia&) = delete; + + private: + void DrawDelegatedInkTrailInternal() override; +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_DELEGATED_INK_POINT_RENDERER_SKIA_H_
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index 9aca9791..07fcea12 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc
@@ -714,6 +714,9 @@ DoDrawQuad(&quad, nullptr); } + if (is_root_render_pass && delegated_ink_point_renderer_) + delegated_ink_point_renderer_->DrawDelegatedInkTrail(); + FlushPolygons(&poly_list, render_pass_scissor_in_draw_space, render_pass_requires_scissor); FinishDrawingQuadList(); @@ -931,4 +934,23 @@ current_frame()->current_render_pass->content_color_usage); } +bool DirectRenderer::CreateDelegatedInkPointRenderer() { + return false; +} + +DelegatedInkPointRendererBase* DirectRenderer::GetDelegatedInkPointRenderer() { + if (!delegated_ink_point_renderer_ && !CreateDelegatedInkPointRenderer()) + return nullptr; + + return delegated_ink_point_renderer_.get(); +} + +void DirectRenderer::SetDelegatedInkMetadata( + std::unique_ptr<DelegatedInkMetadata> metadata) { + if (!delegated_ink_point_renderer_ && !CreateDelegatedInkPointRenderer()) + return; + + delegated_ink_point_renderer_->SetDelegatedInkMetadata(std::move(metadata)); +} + } // namespace viz
diff --git a/components/viz/service/display/direct_renderer.h b/components/viz/service/display/direct_renderer.h index 0ba5c04..07c87be7 100644 --- a/components/viz/service/display/direct_renderer.h +++ b/components/viz/service/display/direct_renderer.h
@@ -6,6 +6,7 @@ #define COMPONENTS_VIZ_SERVICE_DISPLAY_DIRECT_RENDERER_H_ #include <memory> +#include <utility> #include <vector> #include "base/callback.h" @@ -14,7 +15,9 @@ #include "base/macros.h" #include "base/optional.h" #include "build/build_config.h" +#include "components/viz/common/delegated_ink_metadata.h" #include "components/viz/common/quads/tile_draw_quad.h" +#include "components/viz/service/display/delegated_ink_point_renderer_base.h" #include "components/viz/service/display/display_resource_provider.h" #include "components/viz/service/display/overlay_candidate.h" #include "components/viz/service/display/overlay_processor_interface.h" @@ -134,8 +137,12 @@ return last_root_render_pass_scissor_rect_; } + DelegatedInkPointRendererBase* GetDelegatedInkPointRenderer(); + void SetDelegatedInkMetadata(std::unique_ptr<DelegatedInkMetadata> metadata); + protected: friend class BspWalkActionDrawPolygon; + FRIEND_TEST_ALL_PREFIXES(DisplayTest, SkiaDelegatedInkRenderer); enum SurfaceInitializationMode { SURFACE_INITIALIZATION_MODE_PRESERVE, @@ -299,6 +306,12 @@ return ¤t_frame_; } + // Return a bool to inform the caller if the delegated ink renderer was + // actually created or not. If the renderer doesn't support drawing delegated + // ink trails, then the delegated ink renderer won't be created. + virtual bool CreateDelegatedInkPointRenderer(); + std::unique_ptr<DelegatedInkPointRendererBase> delegated_ink_point_renderer_; + private: bool initialized_ = false; #if DCHECK_IS_ON()
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index 924beb7f..0cb2b75 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -678,9 +678,7 @@ "viz", "Delegated Ink Metadata was aggregated for DrawAndSwap.", TRACE_EVENT_SCOPE_THREAD, "ink metadata", frame.delegated_ink_metadata->ToString()); - // TODO(1052145): This metadata will be stored here and used to determine - // which points should be drawn onto the back buffer (via Skia or OS APIs) - // before being swapped onto the screen. + renderer_->SetDelegatedInkMetadata(std::move(frame.delegated_ink_metadata)); } #if defined(OS_ANDROID) @@ -1275,4 +1273,8 @@ resource_provider_->SetAllowAccessToGPUThread(false); } +DelegatedInkPointRendererBase* Display::GetDelegatedInkPointRenderer() { + return renderer_->GetDelegatedInkPointRenderer(); +} + } // namespace viz
diff --git a/components/viz/service/display/display.h b/components/viz/service/display/display.h index 5a139d2..7d146ec 100644 --- a/components/viz/service/display/display.h +++ b/components/viz/service/display/display.h
@@ -20,7 +20,6 @@ #include "components/viz/common/resources/returned_resource.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/surface_id.h" -#include "components/viz/service/display/delegated_ink_point_renderer.h" #include "components/viz/service/display/display_resource_provider.h" #include "components/viz/service/display/display_scheduler.h" #include "components/viz/service/display/frame_rate_decider.h" @@ -48,6 +47,7 @@ namespace viz { class AggregatedFrame; +class DelegatedInkPointRendererBase; class DirectRenderer; class DisplayClient; class DisplayResourceProvider; @@ -185,13 +185,10 @@ bool IsRootFrameMissing() const; bool HasPendingSurfaces(const BeginFrameArgs& args) const; - // Set the delegated ink renderer, which will be responsible for rendering - // the delegated ink trails. This should only be called when the delegated - // ink trails feature is being used. - void set_delegated_ink_point_renderer( - std::unique_ptr<DelegatedInkPointRendererImpl> ink_renderer) { - delegated_ink_point_renderer_ = std::move(ink_renderer); - } + // Return the delegated ink point renderer from |renderer_|, creating it if + // one doesn't exist. Should only be used when the delegated ink trails web + // API has been used. + DelegatedInkPointRendererBase* GetDelegatedInkPointRenderer(); private: friend class DisplayTest; @@ -296,10 +293,6 @@ // The height of the top-controls in the previously drawn frame. float last_top_controls_visible_height_ = 0.f; - // The renderer responsible for drawing delegated ink trails to the screen - // before swapping the buffers in DrawAndSwap(). - std::unique_ptr<DelegatedInkPointRendererImpl> delegated_ink_point_renderer_; - DISALLOW_COPY_AND_ASSIGN(Display); };
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc index 34d99466..7ed89e9 100644 --- a/components/viz/service/display/display_unittest.cc +++ b/components/viz/service/display/display_unittest.cc
@@ -5,6 +5,7 @@ #include "components/viz/service/display/display.h" #include <limits> +#include <map> #include <utility> #include "base/bind.h" @@ -14,6 +15,8 @@ #include "base/test/null_task_runner.h" #include "cc/base/math_util.h" #include "cc/test/scheduler_test_common.h" +#include "components/viz/common/delegated_ink_metadata.h" +#include "components/viz/common/delegated_ink_point.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" @@ -25,6 +28,7 @@ #include "components/viz/common/surfaces/aggregated_frame.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" +#include "components/viz/service/display/delegated_ink_point_renderer_base.h" #include "components/viz/service/display/direct_renderer.h" #include "components/viz/service/display/display_client.h" #include "components/viz/service/display/display_scheduler.h" @@ -36,6 +40,7 @@ #include "components/viz/service/surfaces/surface_manager.h" #include "components/viz/test/compositor_frame_helpers.h" #include "components/viz/test/fake_output_surface.h" +#include "components/viz/test/fake_skia_output_surface.h" #include "components/viz/test/mock_compositor_frame_sink_client.h" #include "components/viz/test/test_gles2_interface.h" #include "components/viz/test/viz_test_suite.h" @@ -162,6 +167,17 @@ std::move(output_surface)); } + void SetUpGpuDisplaySkia(const RendererSettings& settings) { + scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(); + provider->BindToCurrentThread(); + std::unique_ptr<FakeSkiaOutputSurface> skia_output_surface = + FakeSkiaOutputSurface::Create3d(std::move(provider)); + skia_output_surface_ = skia_output_surface.get(); + + CreateDisplaySchedulerAndDisplay(settings, kArbitraryFrameSinkId, + std::move(skia_output_surface)); + } + void CreateDisplaySchedulerAndDisplay( const RendererSettings& settings, const FrameSinkId& frame_sink_id, @@ -238,6 +254,7 @@ std::unique_ptr<Display> display_; TestSoftwareOutputDevice* software_output_device_ = nullptr; FakeOutputSurface* output_surface_ = nullptr; + FakeSkiaOutputSurface* skia_output_surface_ = nullptr; TestDisplayScheduler* scheduler_ = nullptr; }; @@ -4550,4 +4567,87 @@ } } +// Testing the delegated ink renderer when the skia renderer is in use. +TEST_F(DisplayTest, SkiaDelegatedInkRenderer) { + // First set up the display to use the Skia renderer. + RendererSettings settings; + settings.use_skia_renderer = true; + SetUpGpuDisplaySkia(settings); + + // Initialize the renderer and create an ink renderer. + StubDisplayClient client; + display_->Initialize(&client, manager_.surface_manager()); + display_->renderer_for_testing()->CreateDelegatedInkPointRenderer(); + + std::unique_ptr<DelegatedInkPointRendererBase>& ink_renderer = + display_->renderer_for_testing()->delegated_ink_point_renderer_; + + const std::map<base::TimeTicks, gfx::PointF>& stored_points = + ink_renderer->GetPointsMapForTest(); + + // First, a sanity check. + EXPECT_EQ(0, static_cast<int>(stored_points.size())); + + // Insert 3 arbitrary points into the ink renderer to confirm that they go + // where we expect and are all stored correctly. + base::TimeTicks timestamp = base::TimeTicks::Now(); + std::vector<DelegatedInkPoint> ink_points; + ink_points.emplace_back(gfx::PointF(10, 10), timestamp); + ink_points.emplace_back(gfx::PointF(20, 20), + timestamp + base::TimeDelta::FromMicroseconds(5)); + ink_points.emplace_back(gfx::PointF(30, 30), + timestamp + base::TimeDelta::FromMicroseconds(10)); + const int initial_delegated_points = 3; + + for (DelegatedInkPoint point : ink_points) + ink_renderer->StoreDelegatedInkPoint(point); + + EXPECT_EQ(initial_delegated_points, static_cast<int>(stored_points.size())); + + // No metadata has been provided yet, so filtering shouldn't occur and all + // points should still exist after a DrawDelegatedInkTrail() call. + ink_renderer->DrawDelegatedInkTrail(); + + EXPECT_EQ(initial_delegated_points, static_cast<int>(stored_points.size())); + + // Now provide metadata with a timestamp matching one of the points to + // confirm that earlier points are removed and later points remain. + const int ink_point_for_metadata = 1; + DelegatedInkMetadata metadata( + ink_points[ink_point_for_metadata].point(), 1, SK_ColorBLACK, + ink_points[ink_point_for_metadata].timestamp(), gfx::RectF()); + ink_renderer->SetDelegatedInkMetadata( + std::make_unique<DelegatedInkMetadata>(metadata)); + ink_renderer->DrawDelegatedInkTrail(); + + EXPECT_EQ(initial_delegated_points - ink_point_for_metadata, + static_cast<int>(stored_points.size())); + EXPECT_EQ(metadata.point(), stored_points.begin()->second); + EXPECT_EQ(ink_points[ink_points.size() - 1].point(), + stored_points.rbegin()->second); + EXPECT_FALSE(ink_renderer->GetMetadataForTest()); + + // Finally, add more points than the maximum that will be stored to confirm + // only the max is stored and the correct ones are removed first. + const int points_beyond_max_allowed = 2; + for (DelegatedInkPoint point : ink_points) + ink_renderer->StoreDelegatedInkPoint(point); + while (ink_points.size() < + kMaximumDelegatedInkPointsStored + points_beyond_max_allowed) { + gfx::PointF pt = ink_points[ink_points.size() - 1].point(); + pt.Offset(5, 5); + base::TimeTicks ts = ink_points[ink_points.size() - 1].timestamp() + + base::TimeDelta::FromMicroseconds(5); + ink_points.emplace_back(pt, ts); + ink_renderer->StoreDelegatedInkPoint(ink_points[ink_points.size() - 1]); + } + + EXPECT_EQ(kMaximumDelegatedInkPointsStored, + static_cast<int>(stored_points.size())); + EXPECT_EQ(ink_points[points_beyond_max_allowed].point(), + stored_points.begin()->second); + EXPECT_EQ(ink_points[ink_points.size() - 1].point(), + stored_points.rbegin()->second); +} + } // namespace viz
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index a6e6174..1df9ece 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -32,6 +32,7 @@ #include "components/viz/common/resources/platform_color.h" #include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/skia_helper.h" +#include "components/viz/service/display/delegated_ink_point_renderer_skia.h" #include "components/viz/service/display/display_resource_provider.h" #include "components/viz/service/display/output_surface.h" #include "components/viz/service/display/output_surface_frame.h" @@ -2777,4 +2778,11 @@ return it->second.size; } +bool SkiaRenderer::CreateDelegatedInkPointRenderer() { + DCHECK(!delegated_ink_point_renderer_); + delegated_ink_point_renderer_ = + std::make_unique<DelegatedInkPointRendererSkia>(); + return true; +} + } // namespace viz
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h index b6f81ae..75954c5 100644 --- a/components/viz/service/display/skia_renderer.h +++ b/components/viz/service/display/skia_renderer.h
@@ -92,6 +92,7 @@ void DidChangeVisibility() override; void FinishDrawingQuadList() override; void GenerateMipmap() override; + bool CreateDelegatedInkPointRenderer() override; private: enum class BypassMode;
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc index 7b8887ee..a9e05db 100644 --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -13,7 +13,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" -#include "components/viz/service/display/delegated_ink_point_renderer.h" +#include "components/viz/service/display/delegated_ink_point_renderer_base.h" #include "components/viz/service/display/display.h" #include "components/viz/service/display/output_surface.h" #include "components/viz/service/display_embedder/output_surface_provider.h" @@ -306,8 +306,8 @@ void RootCompositorFrameSinkImpl::SetDelegatedInkPointRenderer( mojo::PendingReceiver<mojom::DelegatedInkPointRenderer> receiver) { - display_->set_delegated_ink_point_renderer( - std::make_unique<DelegatedInkPointRendererImpl>(std::move(receiver))); + if (auto* ink_renderer = display_->GetDelegatedInkPointRenderer()) + ink_renderer->InitMessagePipeline(std::move(receiver)); } void RootCompositorFrameSinkImpl::SetNeedsBeginFrame(bool needs_begin_frame) {
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index 6aa45ad0..41fcc60 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -6,29 +6,37 @@ #include <unordered_map> #include "base/bind_helpers.h" +#include "base/callback_forward.h" #include "base/command_line.h" #include "base/hash/hash.h" #include "base/location.h" #include "base/metrics/metrics_hashes.h" #include "base/optional.h" +#include "base/run_loop.h" #include "base/strings/string_piece_forward.h" #include "base/system/sys_info.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_mock_time_task_runner.h" +#include "base/threading/thread_restrictions.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" +#include "base/trace_event/trace_log.h" #include "build/build_config.h" #include "components/network_session_configurator/common/network_switches.h" #include "components/ukm/test_ukm_recorder.h" +#include "content/browser/bad_message.h" #include "content/browser/frame_host/back_forward_cache_impl.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/generic_sensor/sensor_provider_proxy_impl.h" #include "content/browser/presentation/presentation_test_utils.h" +#include "content/browser/renderer_host/page_lifecycle_state_manager.h" #include "content/browser/web_contents/file_chooser_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/content_navigation_policy.h" +#include "content/common/render_accessibility.mojom.h" #include "content/public/browser/back_forward_cache.h" #include "content/public/browser/frame_service_base.h" #include "content/public/browser/global_routing_id.h" @@ -55,6 +63,9 @@ #include "content/test/content_browser_test_utils_internal.h" #include "content/test/echo.mojom.h" #include "media/base/media_switches.h" +#include "mojo/public/cpp/bindings/message.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "net/base/filename_util.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/controllable_http_response.h" @@ -120,6 +131,8 @@ // TODO(sreejakshetty): Initialize ScopedFeatureLists from test constructor. EnableFeatureAndSetParams(features::kBackForwardCache, "TimeToLiveInBackForwardCacheInSeconds", "3600"); + EnableFeatureAndSetParams(features::kBackForwardCache, + "message_handling_when_cached", "kill"); EnableFeatureAndSetParams( features::kBackForwardCache, "enable_same_site", same_site_back_forward_cache_enabled_ ? "true" : "false"); @@ -359,7 +372,10 @@ void EvictByJavaScript(RenderFrameHostImpl* rfh) { // Run JavaScript on a page in the back-forward cache. The page should be // evicted. As the frame is deleted, ExecJs returns false without executing. - EXPECT_FALSE(ExecJs(rfh, "console.log('hi');")); + // Run without user gesture to prevent UpdateUserActivationState message + // being sent back to browser. + EXPECT_FALSE( + ExecJs(rfh, "console.log('hi');", EXECUTE_SCRIPT_NO_USER_GESTURE)); } void StartRecordingEvents(RenderFrameHostImpl* rfh) { @@ -554,6 +570,64 @@ observer.Wait(); } +class PageLifecycleStateManagerTestDelegate + : public PageLifecycleStateManager::TestDelegate { + public: + explicit PageLifecycleStateManagerTestDelegate( + PageLifecycleStateManager* manager) + : manager_(manager) { + manager->SetDelegateForTesting(this); + } + + ~PageLifecycleStateManagerTestDelegate() override { + manager_->SetDelegateForTesting(nullptr); + } + + void WaitForInBackForwardCacheAck() { + if (manager_->last_acknowledged_state().is_in_back_forward_cache) { + return; + } + base::RunLoop loop; + store_in_back_forward_cache_ack_received_ = loop.QuitClosure(); + loop.Run(); + } + + void OnStoreInBackForwardCacheSent(base::OnceClosure cb) { + store_in_back_forward_cache_sent_ = std::move(cb); + } + + void OnRestoreFromBackForwardCacheSent(base::OnceClosure cb) { + restore_from_back_forward_cache_sent_ = std::move(cb); + } + + private: + void OnLastAcknowledgedStateChanged( + const blink::mojom::PageLifecycleState& old_state, + const blink::mojom::PageLifecycleState& new_state) override { + if (store_in_back_forward_cache_ack_received_ && + new_state.is_in_back_forward_cache) + std::move(store_in_back_forward_cache_ack_received_).Run(); + } + + void OnUpdateSentToRenderer( + const blink::mojom::PageLifecycleState& new_state) override { + if (store_in_back_forward_cache_sent_ && + new_state.is_in_back_forward_cache) { + std::move(store_in_back_forward_cache_sent_).Run(); + } + + if (restore_from_back_forward_cache_sent_ && + !new_state.is_in_back_forward_cache) { + std::move(restore_from_back_forward_cache_sent_).Run(); + } + } + + PageLifecycleStateManager* const manager_; + base::OnceClosure store_in_back_forward_cache_sent_; + base::OnceClosure store_in_back_forward_cache_ack_received_; + base::OnceClosure restore_from_back_forward_cache_sent_; +}; + } // namespace // Navigate from A to B and go back. @@ -636,9 +710,8 @@ } // Navigate from back and forward repeatedly. -// TODO(https://crbug.com/1099395): flaky. IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, - DISABLED_NavigateBackForwardRepeatedly) { + NavigateBackForwardRepeatedly) { ASSERT_TRUE(embedded_test_server()->Start()); GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html")); GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html")); @@ -2558,16 +2631,17 @@ // Execute JavaScript after committing but before swapping happens on the // renderer. ReadyToCommitNavigationCallback host_changed_callback( - web_contents(), base::BindOnce( - [](RenderFrameHostImpl* rfh_a, - RenderFrameDeletedObserver* delete_observer_rfh_a, - NavigationHandle* navigation_handle) { - EXPECT_FALSE(delete_observer_rfh_a->deleted()); - EXPECT_EQ(rfh_a, - navigation_handle->GetRenderFrameHost()); - ExecuteScriptAsync(rfh_a, "console.log('hi');"); - }, - rfh_a, &delete_observer_rfh_a)); + web_contents(), + base::BindOnce( + [](RenderFrameHostImpl* rfh_a, + RenderFrameDeletedObserver* delete_observer_rfh_a, + NavigationHandle* navigation_handle) { + ASSERT_FALSE(delete_observer_rfh_a->deleted()); + EXPECT_EQ(rfh_a, navigation_handle->GetRenderFrameHost()); + rfh_a->ExecuteJavaScriptForTests( + base::UTF8ToUTF16("console.log('hi');"), base::NullCallback()); + }, + rfh_a, &delete_observer_rfh_a)); // Wait for two navigations to finish. The first one is the BackForwardCache // navigation, the other is the reload caused by the eviction. @@ -6499,4 +6573,103 @@ EXPECT_TRUE(rfh_a->coop_reporter()); } +namespace { + +class EchoFakeWithFilter final : public mojom::Echo { + public: + explicit EchoFakeWithFilter(mojo::PendingReceiver<mojom::Echo> receiver, + std::unique_ptr<mojo::MessageFilter> filter) + : receiver_(this, std::move(receiver)) { + receiver_.SetFilter(std::move(filter)); + } + ~EchoFakeWithFilter() override = default; + + // mojom::Echo implementation + void EchoString(const std::string& input, + EchoStringCallback callback) override { + std::move(callback).Run(input); + } + + private: + mojo::Receiver<mojom::Echo> receiver_; +}; + +} // namespace + +IN_PROC_BROWSER_TEST_F( + BackForwardCacheBrowserTest, + ProcessKilledIfMessageReceivedOnAssociatedInterfaceWhileCached) { + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html")); + GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html")); + url::Origin origin_a = url::Origin::Create(url_a); + url::Origin origin_b = url::Origin::Create(url_b); + + // 1) Navigate to A. + EXPECT_TRUE(NavigateToURL(shell(), url_a)); + RenderFrameHostImpl* rfh_a = current_frame_host(); + RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a); + PageLifecycleStateManagerTestDelegate delegate( + rfh_a->render_view_host()->GetPageLifecycleStateManager()); + + // 2) Navigate to B. + EXPECT_TRUE(NavigateToURL(shell(), url_b)); + delegate.WaitForInBackForwardCacheAck(); + ASSERT_FALSE(delete_observer_rfh_a.deleted()); + EXPECT_TRUE(rfh_a->IsInBackForwardCache()); + + mojo::Remote<mojom::Echo> remote; + EchoFakeWithFilter echo( + remote.BindNewPipeAndPassReceiver(), + rfh_a->CreateMessageFilterForAssociatedReceiver(mojom::Echo::Name_)); + + ScopedAllowRendererCrashes allow_crash(rfh_a->GetProcess()); + RenderProcessHostBadIpcMessageWaiter bad_message_waiter(rfh_a->GetProcess()); + + remote->EchoString("", base::NullCallback()); + + EXPECT_THAT(bad_message_waiter.Wait(), + testing::Optional( + bad_message::RFH_RECEIVED_ASSOCIATED_MESSAGE_WHILE_BFCACHED)); + EXPECT_TRUE(delete_observer_rfh_a.deleted()); +} + +IN_PROC_BROWSER_TEST_F( + BackForwardCacheBrowserTest, + ProcessNotKilledIfMessageReceivedOnAssociatedInterfaceWhileFreezing) { + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html")); + GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html")); + url::Origin origin_a = url::Origin::Create(url_a); + url::Origin origin_b = url::Origin::Create(url_b); + + // 1) Navigate to A. + EXPECT_TRUE(NavigateToURL(shell(), url_a)); + RenderFrameHostImpl* rfh_a = current_frame_host(); + RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a); + PageLifecycleStateManagerTestDelegate delegate( + rfh_a->render_view_host()->GetPageLifecycleStateManager()); + + mojo::Remote<mojom::Echo> remote; + EchoFakeWithFilter echo( + remote.BindNewPipeAndPassReceiver(), + rfh_a->CreateMessageFilterForAssociatedReceiver(mojom::Echo::Name_)); + + delegate.OnStoreInBackForwardCacheSent(base::BindLambdaForTesting( + [&]() { remote->EchoString("", base::NullCallback()); })); + + delegate.OnRestoreFromBackForwardCacheSent(base::BindLambdaForTesting( + [&]() { remote->EchoString("", base::NullCallback()); })); + + // 2) Navigate to B. + EXPECT_TRUE(NavigateToURL(shell(), url_b)); + + // 3) Go back to A. + web_contents()->GetController().GoBack(); + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + + ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kRestored, + FROM_HERE); +} + } // namespace content
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h index 36e3e53b..e813ef5 100644 --- a/content/browser/bad_message.h +++ b/content/browser/bad_message.h
@@ -257,6 +257,7 @@ RFH_INACTIVE_CHECK_FROM_SPECULATIVE_RFH = 229, RFH_SUBFRAME_CAPTURE_ON_MAIN_FRAME = 230, RFH_CSP_ATTRIBUTE = 231, + RFH_RECEIVED_ASSOCIATED_MESSAGE_WHILE_BFCACHED = 232, // Please add new elements here. The naming convention is abbreviated class // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 76d20a57..f3533cf 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -77,7 +77,7 @@ #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/mojom/url_response_head.mojom.h" -#include "third_party/blink/public/common/loader/network_utils.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/platform/resource_request_blocked_reason.h" #include "third_party/boringssl/src/include/openssl/ssl.h" @@ -360,8 +360,8 @@ case network::mojom::ReferrerPolicy::kAlways: return Network::Request::ReferrerPolicyEnum::UnsafeUrl; case network::mojom::ReferrerPolicy::kDefault: - return referrerPolicy(blink::NetToMojoReferrerPolicy( - content::Referrer::GetDefaultReferrerPolicy())); + return referrerPolicy(blink::ReferrerUtils::NetToMojoReferrerPolicy( + blink::ReferrerUtils::GetDefaultNetReferrerPolicy())); case network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade: return Network::Request::ReferrerPolicyEnum::NoReferrerWhenDowngrade; case network::mojom::ReferrerPolicy::kNever: @@ -382,7 +382,8 @@ } String referrerPolicy(net::ReferrerPolicy referrer_policy) { - return referrerPolicy(blink::NetToMojoReferrerPolicy(referrer_policy)); + return referrerPolicy( + blink::ReferrerUtils::NetToMojoReferrerPolicy(referrer_policy)); } String securityState(const GURL& url, const net::CertStatus& cert_status) {
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index 6d11f22..b5146dd 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -79,8 +79,8 @@ #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h" -#include "third_party/blink/public/common/loader/network_utils.h" #include "third_party/blink/public/common/loader/previews_state.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/common/loader/throttling_url_loader.h" #if defined(USE_X11) @@ -536,9 +536,9 @@ url_chain.pop_back(); NavigationController::LoadURLParams params(url); params.has_user_gesture = info.has_user_gesture; - params.referrer = - Referrer(info.referrer_url, - blink::NetToMojoReferrerPolicy(info.referrer_policy)); + params.referrer = Referrer( + info.referrer_url, + blink::ReferrerUtils::NetToMojoReferrerPolicy(info.referrer_policy)); params.redirect_chain = url_chain; params.frame_tree_node_id = RenderFrameHost::GetFrameTreeNodeIdForRoutingId(
diff --git a/content/browser/frame_host/back_forward_cache_impl.cc b/content/browser/frame_host/back_forward_cache_impl.cc index 4bcbcd4..64985b1 100644 --- a/content/browser/frame_host/back_forward_cache_impl.cc +++ b/content/browser/frame_host/back_forward_cache_impl.cc
@@ -250,6 +250,34 @@ } // namespace +// static +BackForwardCacheImpl::MessageHandlingPolicyWhenCached +BackForwardCacheImpl::GetChannelAssociatedMessageHandlingPolicy() { + // Avoid activating BackForwardCache trial for checking the parameters + // associated with it. + if (!IsBackForwardCacheEnabled()) + return kMessagePolicyNone; + + static constexpr char kFieldTrialParam[] = "message_handling_when_cached"; + auto param = base::GetFieldTrialParamValueByFeature( + features::kBackForwardCache, kFieldTrialParam); + if (param.empty() || param == "log") { + return kMessagePolicyLog; + } else if (param == "none") { + return kMessagePolicyNone; + } else if (param == "dump") { + return kMessagePolicyDump; + } else if (param == "kill") { + return kMessagePolicyKill; + } else { + DLOG(WARNING) << "Failed to parse field trial param " << kFieldTrialParam + << " with string value " << param + << " under feature kBackForwardCache" + << features::kBackForwardCache.name; + return kMessagePolicyLog; + } +} + BackForwardCacheImpl::Entry::Entry( std::unique_ptr<RenderFrameHostImpl> rfh, RenderFrameProxyHostMap proxies,
diff --git a/content/browser/frame_host/back_forward_cache_impl.h b/content/browser/frame_host/back_forward_cache_impl.h index 2628cbea..a6b0c36 100644 --- a/content/browser/frame_host/back_forward_cache_impl.h +++ b/content/browser/frame_host/back_forward_cache_impl.h
@@ -46,6 +46,16 @@ // the current_frame_host. class CONTENT_EXPORT BackForwardCacheImpl : public BackForwardCache { public: + enum MessageHandlingPolicyWhenCached { + kMessagePolicyNone, + kMessagePolicyLog, + kMessagePolicyDump, + kMessagePolicyKill, + }; + + static MessageHandlingPolicyWhenCached + GetChannelAssociatedMessageHandlingPolicy(); + struct Entry { using RenderFrameProxyHostMap = std::unordered_map<int32_t /* SiteInstance ID */,
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index 2899140..e026cf13 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -63,6 +63,7 @@ #include "content/browser/web_package/web_bundle_navigation_info.h" #include "content/common/content_constants_internal.h" #include "content/common/frame_messages.h" +#include "content/common/trace_utils.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/content_browser_client.h" @@ -1252,10 +1253,14 @@ NavigationType NavigationControllerImpl::ClassifyNavigation( RenderFrameHostImpl* rfh, const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { + TraceReturnReason<TracingCategory::kNavigation> trace_return( + "ClassifyNavigation"); + if (params.did_create_new_entry) { // A new entry. We may or may not have a pending entry for the page, and // this may or may not be the main frame. if (!rfh->GetParent()) { + trace_return.set_return_reason("new entry, no parent, new page"); return NAVIGATION_TYPE_NEW_PAGE; } @@ -1264,10 +1269,13 @@ // navigated on a popup navigated to about:blank (the iframe would be // written into the popup by script on the main page). For these cases, // there isn't any navigation stuff we can do, so just ignore it. - if (!GetLastCommittedEntry()) + if (!GetLastCommittedEntry()) { + trace_return.set_return_reason("new entry, no last committed, ignore"); return NAVIGATION_TYPE_NAV_IGNORE; + } // Valid subframe navigation. + trace_return.set_return_reason("new entry, new subframe"); return NAVIGATION_TYPE_NEW_SUBFRAME; } @@ -1277,11 +1285,14 @@ if (rfh->GetParent()) { // All manual subframes would be did_create_new_entry and handled above, so // we know this is auto. - if (GetLastCommittedEntry()) + if (GetLastCommittedEntry()) { + trace_return.set_return_reason("subframe, last commmited, auto subframe"); return NAVIGATION_TYPE_AUTO_SUBFRAME; + } // We ignore subframes created in non-committed pages; we'd appreciate if // people stopped doing that. + trace_return.set_return_reason("subframe, no last commmited, ignore"); return NAVIGATION_TYPE_NAV_IGNORE; } @@ -1293,14 +1304,18 @@ // scribble onto an uncommitted page. Again, there isn't any navigation // stuff that we can do, so ignore it here as well. NavigationEntry* last_committed = GetLastCommittedEntry(); - if (!last_committed) + if (!last_committed) { + trace_return.set_return_reason("nav entry 0, no last committed, ignore"); return NAVIGATION_TYPE_NAV_IGNORE; + } // This is history.replaceState() or history.reload(). // TODO(nasko): With error page isolation, reloading an existing session // history entry can result in change of SiteInstance. Check for such a case // here and classify it as NEW_PAGE, as such navigations should be treated // as new with replacement. + trace_return.set_return_reason( + "nav entry 0, last committed, existing page"); return NAVIGATION_TYPE_EXISTING_PAGE; } @@ -1312,6 +1327,7 @@ // reloaded into a different SiteInstance. if (pending_entry_->site_instance() && pending_entry_->site_instance() != rfh->GetSiteInstance()) { + trace_return.set_return_reason("pending matching nav entry, new page"); return NAVIGATION_TYPE_NEW_PAGE; } @@ -1323,6 +1339,7 @@ // we must treat it as NEW since the SiteInstance doesn't match the entry. if (!GetLastCommittedEntry() || GetLastCommittedEntry()->site_instance() != rfh->GetSiteInstance()) { + trace_return.set_return_reason("no pending, new page"); return NAVIGATION_TYPE_NEW_PAGE; } @@ -1333,19 +1350,23 @@ // Therefore we want to just ignore the pending entry and go back to where // we were (the "existing entry"). // TODO(creis,avi): Eliminate SAME_PAGE in https://crbug.com/536102. + trace_return.set_return_reason("no pending, same page"); return NAVIGATION_TYPE_SAME_PAGE; } } // Everything below here is assumed to be an existing entry, but if there is // no last committed entry, we must consider it a new navigation instead. - if (!GetLastCommittedEntry()) + if (!GetLastCommittedEntry()) { + trace_return.set_return_reason("no last committed, new page"); return NAVIGATION_TYPE_NEW_PAGE; + } if (params.intended_as_new_entry) { // This was intended to be a navigation to a new entry but the pending entry // got cleared in the meanwhile. Classify as EXISTING_PAGE because we may or // may not have a pending entry. + trace_return.set_return_reason("indented as new entry, new page"); return NAVIGATION_TYPE_EXISTING_PAGE; } @@ -1355,19 +1376,25 @@ // of an error, this is the case of the user trying to retry a failed load // by pressing return. Classify as EXISTING_PAGE because we probably don't // have a pending entry. + trace_return.set_return_reason( + "unreachable, matching pending, existing page"); return NAVIGATION_TYPE_EXISTING_PAGE; } // Now we know that the notification is for an existing page. Find that entry. int existing_entry_index = GetEntryIndexWithUniqueID(params.nav_entry_id); + trace_return.traced_value()->SetInteger("existing_entry_index", + existing_entry_index); if (existing_entry_index == -1) { // The renderer has committed a navigation to an entry that no longer // exists. Because the renderer is showing that page, resurrect that entry. + trace_return.set_return_reason("existing entry -1, new page"); return NAVIGATION_TYPE_NEW_PAGE; } // Since we weeded out "new" navigations above, we know this is an existing // (back/forward) navigation. + trace_return.set_return_reason("default return, existing page"); return NAVIGATION_TYPE_EXISTING_PAGE; }
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index e97ac73..d8b4b66 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -635,7 +635,10 @@ WaitForLoadStop(web_contents); TestNavigationManager navigation_manager(web_contents, url); const GURL& current_url = web_contents->GetMainFrame()->GetLastCommittedURL(); - EXPECT_TRUE(ExecJs(shell, JsReplace("window.location.replace($1)", url))); + // Execute script in an isolated world to avoid causing a Trusted Types + // violation due to eval. + EXPECT_TRUE(ExecJs(shell, JsReplace("window.location.replace($1)", url), + EXECUTE_SCRIPT_DEFAULT_OPTIONS, /*world_id=*/1)); // Observe pending entry if it's not a same-document navigation. We can't // observe same-document navigations because it might finish in the renderer, // only telling the browser side at the end. @@ -718,13 +721,18 @@ ShellAddedObserver observer; GURL page_url = embedded_test_server()->GetURL( "/navigation_controller/simple_page_1.html"); - EXPECT_TRUE( - ExecJs(shell(), JsReplace("window.open($1, '_blank');", page_url))); + // Execute script in an isolated world to avoid causing a Trusted Types + // violation due to eval. + EXPECT_TRUE(ExecJs(shell(), JsReplace("window.open($1, '_blank');", page_url), + EXECUTE_SCRIPT_DEFAULT_OPTIONS, /*world_id=*/1)); Shell* shell2 = observer.GetShell(); EXPECT_TRUE(WaitForLoadStop(shell2->web_contents())); EXPECT_EQ(1, shell2->web_contents()->GetController().GetEntryCount()); - EXPECT_EQ(1, EvalJs(shell2, "history.length")); + // Execute script in an isolated world to avoid causing a Trusted Types + // violation due to eval. + EXPECT_EQ(1, EvalJs(shell2, "history.length", EXECUTE_SCRIPT_DEFAULT_OPTIONS, + /*world_id=*/1)); // Again, as above, there's no way to access the renderer's notion of the // history offset via JavaScript. Checking just the history length, again,
diff --git a/content/browser/frame_host/render_frame_host_delegate.h b/content/browser/frame_host/render_frame_host_delegate.h index ee78ae7..30c06a6 100644 --- a/content/browser/frame_host/render_frame_host_delegate.h +++ b/content/browser/frame_host/render_frame_host_delegate.h
@@ -392,9 +392,12 @@ // The window is identified by the |main_frame_widget_route_id| passed to // CreateNewWindow. // + // The passed |opener| is the RenderFrameHost initiating the window creation. + // It will never be null, even if the opener is suppressed via |params|. + // // Note: this is not called "ShowWindow" because that will clash with // the Windows function which is actually a #define. - virtual void ShowCreatedWindow(int process_id, + virtual void ShowCreatedWindow(RenderFrameHost* opener, int main_frame_widget_route_id, WindowOpenDisposition disposition, const gfx::Rect& initial_rect,
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 99a994f..19ae61c 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" +#include "base/compiler_specific.h" #include "base/containers/queue.h" #include "base/debug/alias.h" #include "base/debug/crash_logging.h" @@ -20,6 +21,7 @@ #include "base/lazy_instance.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" +#include "base/metrics/field_trial_params.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/metrics_hashes.h" @@ -28,6 +30,7 @@ #include "base/numerics/safe_conversions.h" #include "base/process/kill.h" #include "base/stl_util.h" +#include "base/task/current_thread.h" #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "base/threading/thread_task_runner_handle.h" @@ -95,6 +98,7 @@ #include "content/browser/renderer_host/dip_util.h" #include "content/browser/renderer_host/input/input_router.h" #include "content/browser/renderer_host/input/timeout_monitor.h" +#include "content/browser/renderer_host/page_lifecycle_state_manager.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/renderer_host/render_view_host_delegate.h" #include "content/browser/renderer_host/render_view_host_delegate_view.h" @@ -372,6 +376,124 @@ bool debug_url_set_ = false; }; +// This class can be added as a MessageFilter to a mojo receiver to kill the +// sending process if the associated frame is in the Back-Forward Cache. +// Documents that are in the bfcache should not be sending mojo messages back to +// the browser. +class KillIfInBackForwardCacheMessageFilter : public mojo::MessageFilter { + public: + explicit KillIfInBackForwardCacheMessageFilter( + RenderFrameHostImpl* render_frame_host, + const char* interface_name, + BackForwardCacheImpl::MessageHandlingPolicyWhenCached policy) + : render_frame_host_(render_frame_host), + interface_name_(interface_name), + policy_(policy) {} + + ~KillIfInBackForwardCacheMessageFilter() override = default; + + private: + // mojo::MessageFilter overrides. + bool WillDispatch(mojo::Message* message) override { + if (!IsFrameInBackForwardCache() || + policy_ == BackForwardCacheImpl::kMessagePolicyNone) { + return true; + } + + DLOG(ERROR) << "Received message " << message->name() << " on interface " + << interface_name_ << " from frame in bfcache."; + + TRACE_EVENT2( + "content", + "KillIfInBackForwardCacheMessageFilter::WillDispatch bad_message", + "interface_name", interface_name_, "message_name", message->name()); + + switch (policy_) { + case BackForwardCacheImpl::kMessagePolicyNone: + case BackForwardCacheImpl::kMessagePolicyLog: + return true; + case BackForwardCacheImpl::kMessagePolicyDump: + base::debug::DumpWithoutCrashing(); + return true; + case BackForwardCacheImpl::kMessagePolicyKill: + bad_message::ReceivedBadMessage( + render_frame_host_->GetProcess(), + bad_message::RFH_RECEIVED_ASSOCIATED_MESSAGE_WHILE_BFCACHED); + return false; + } + } + + void DidDispatchOrReject(mojo::Message* message, bool accepted) override {} + + // Returns true if both the renderer and the browser think the frame is in the + // bfcache. That is the PageLifecycleState is in sync with regards to bfcache. + // In the intermediate states (no ACK received yet) messages must be allowed. + bool IsFrameInBackForwardCache() { + PageLifecycleStateManager* mgr = + render_frame_host_->render_view_host()->GetPageLifecycleStateManager(); + + return mgr->last_acknowledged_state().is_in_back_forward_cache && + mgr->last_state_sent_to_renderer().is_in_back_forward_cache; + } + + RenderFrameHostImpl* const render_frame_host_; + const char* const interface_name_; + const BackForwardCacheImpl::MessageHandlingPolicyWhenCached policy_; +}; + +// This class is used to chain multiple mojo::MessageFilter. Messages will be +// processed by the filters in the same order as the filters are added with the +// Add() method. WillDispatch() might not be called for all filters or might see +// a modified message if a filter earlier in the chain discards or modifies it. +// Similarly a given filter instance might not receive a DidDispatchOrReject() +// call even if WillDispatch() was called if a filter further down the chain +// discarded it. Long story short, the order in which filters are added is +// important! +class MessageFilterChain : public mojo::MessageFilter { + public: + MessageFilterChain() = default; + ~MessageFilterChain() final = default; + + bool WillDispatch(mojo::Message* message) override { + for (auto& filter : filters_) { + if (!filter->WillDispatch(message)) + return false; + } + return true; + } + void DidDispatchOrReject(mojo::Message* message, bool accepted) override { + for (auto& filter : filters_) { + filter->DidDispatchOrReject(message, accepted); + } + } + + // Adds a filter to the end of the chain. See class description for ordering + // implications. + void Add(std::unique_ptr<mojo::MessageFilter> filter) { + filters_.push_back(std::move(filter)); + } + + private: + std::vector<std::unique_ptr<mojo::MessageFilter>> filters_; +}; + +std::unique_ptr<mojo::MessageFilter> +CreateMessageFilterForAssociatedReceiverImpl( + RenderFrameHostImpl* render_frame_host, + const char* interface_name, + BackForwardCacheImpl::MessageHandlingPolicyWhenCached policy) { + auto filter_chain = std::make_unique<MessageFilterChain>(); + filter_chain->Add(std::make_unique<KillIfInBackForwardCacheMessageFilter>( + render_frame_host, interface_name, policy)); + // KillIfInBackForwardCacheMessageFilter might drop messages so add + // ActiveURLMessageFilter at the end of the chain as we need to make sure that + // the debug url is reset, that is, DidDispatchOrReject() is called if + // WillDispatch(). + filter_chain->Add( + std::make_unique<ActiveURLMessageFilter>(render_frame_host)); + return filter_chain; +} + void GrantFileAccess(int child_id, const std::vector<base::FilePath>& file_paths) { ChildProcessSecurityPolicyImpl* policy = @@ -4269,7 +4391,8 @@ RenderFrameProxyHost* child_proxy = rfh->frame_tree_node()->render_manager()->GetRenderFrameProxyHost( parent_site_instance); - child_proxy->GetAssociatedRemoteFrame()->WillEnterFullscreen(); + child_proxy->GetAssociatedRemoteFrame()->WillEnterFullscreen( + options.Clone()); notified_instances.insert(parent_site_instance); } @@ -4597,6 +4720,9 @@ receiver) { DCHECK(receiver.is_valid()); dom_automation_controller_receiver_.Bind(std::move(receiver)); + dom_automation_controller_receiver_.SetFilter( + CreateMessageFilterForAssociatedReceiver( + mojom::DomAutomationControllerHost::Name_)); } void RenderFrameHostImpl::SetKeepAliveTimeoutForTesting( @@ -4610,8 +4736,8 @@ WindowOpenDisposition disposition, const gfx::Rect& initial_rect, bool user_gesture) { - delegate_->ShowCreatedWindow(GetProcess()->GetID(), pending_widget_routing_id, - disposition, initial_rect, user_gesture); + delegate_->ShowCreatedWindow(this, pending_widget_routing_id, disposition, + initial_rect, user_gesture); } void RenderFrameHostImpl::UpdateState(const PageState& state) { @@ -6368,12 +6494,26 @@ mojo::PendingAssociatedReceiver<mojom::FrameHost> receiver) { impl->frame_host_associated_receiver_.Bind(std::move(receiver)); impl->frame_host_associated_receiver_.SetFilter( - std::make_unique<ActiveURLMessageFilter>(impl)); + impl->CreateMessageFilterForAssociatedReceiver( + mojom::FrameHost::Name_)); }; associated_registry_->AddInterface( base::BindRepeating(bind_frame_host_receiver, base::Unretained(this))); associated_registry_->AddInterface(base::BindRepeating( + [](RenderFrameHostImpl* impl, + mojo::PendingAssociatedReceiver< + blink::mojom::BackForwardCacheControllerHost> receiver) { + impl->back_forward_cache_controller_host_associated_receiver_.Bind( + std::move(receiver)); + impl->back_forward_cache_controller_host_associated_receiver_.SetFilter( + CreateMessageFilterForAssociatedReceiverImpl( + impl, blink::mojom::BackForwardCacheControllerHost::Name_, + BackForwardCacheImpl::kMessagePolicyNone)); + }, + base::Unretained(this))); + + associated_registry_->AddInterface(base::BindRepeating( [](RenderFrameHostImpl* self, mojo::PendingAssociatedReceiver<blink::mojom::PortalHost> receiver) { Portal::BindPortalHostReceiver(self, std::move(receiver)); @@ -6386,7 +6526,8 @@ receiver) { impl->local_frame_host_receiver_.Bind(std::move(receiver)); impl->local_frame_host_receiver_.SetFilter( - std::make_unique<ActiveURLMessageFilter>(impl)); + impl->CreateMessageFilterForAssociatedReceiver( + blink::mojom::LocalFrameHost::Name_)); }, base::Unretained(this))); @@ -6397,7 +6538,8 @@ receiver) { impl->local_main_frame_host_receiver_.Bind(std::move(receiver)); impl->local_main_frame_host_receiver_.SetFilter( - std::make_unique<ActiveURLMessageFilter>(impl)); + impl->CreateMessageFilterForAssociatedReceiver( + blink::mojom::LocalMainFrameHost::Name_)); }, base::Unretained(this))); @@ -6416,6 +6558,9 @@ mojo::PendingAssociatedReceiver<mojom::RenderAccessibilityHost> receiver) { impl->render_accessibility_host_receiver_.Bind(std::move(receiver)); + impl->render_accessibility_host_receiver_.SetFilter( + impl->CreateMessageFilterForAssociatedReceiver( + mojom::RenderAccessibilityHost::Name_)); }, base::Unretained(this))); @@ -7871,6 +8016,14 @@ std::move(hashed_device_id)); } +std::unique_ptr<mojo::MessageFilter> +RenderFrameHostImpl::CreateMessageFilterForAssociatedReceiver( + const char* interface_name) { + return CreateMessageFilterForAssociatedReceiverImpl( + this, interface_name, + BackForwardCacheImpl::GetChannelAssociatedMessageHandlingPolicy()); +} + bool RenderFrameHostImpl::ValidateDidCommitParams( NavigationRequest* navigation_request, FrameHostMsg_DidCommitProvisionalLoad_Params* params,
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 6c4e3b9..ff48cc63 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -67,6 +67,7 @@ #include "media/mojo/services/media_metrics_provider.h" #include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -100,6 +101,7 @@ #include "third_party/blink/public/mojom/devtools/inspector_issue.mojom.h" #include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h" #include "third_party/blink/public/mojom/font_access/font_access.mojom.h" +#include "third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom.h" #include "third_party/blink/public/mojom/frame/blocked_navigation_types.mojom.h" #include "third_party/blink/public/mojom/frame/find_in_page.mojom.h" #include "third_party/blink/public/mojom/frame/frame.mojom-forward.h" @@ -242,6 +244,7 @@ public RenderProcessHostObserver, public SiteInstanceImpl::Observer, public service_manager::mojom::InterfaceProvider, + public blink::mojom::BackForwardCacheControllerHost, public blink::mojom::LocalFrameHost, public network::CSPContext, public blink::mojom::LocalMainFrameHost, @@ -1745,6 +1748,12 @@ void SetAudioOutputDeviceIdForGlobalMediaControls( std::string hashed_device_id); + // Returns a filter that should be associated with all AssociatedReceivers for + // this frame. |interface_name| is used for logging purposes and must be valid + // for the entire program duration. + std::unique_ptr<mojo::MessageFilter> CreateMessageFilterForAssociatedReceiver( + const char* interface_name); + protected: friend class RenderFrameHostFactory; @@ -2755,6 +2764,8 @@ mojo::AssociatedReceiver<mojom::FrameHost> frame_host_associated_receiver_{ this}; + mojo::AssociatedReceiver<blink::mojom::BackForwardCacheControllerHost> + back_forward_cache_controller_host_associated_receiver_{this}; mojo::Remote<mojom::Frame> frame_; mojo::AssociatedRemote<mojom::FrameBindingsControl> frame_bindings_control_; mojo::AssociatedRemote<mojom::FrameNavigationControl> navigation_control_;
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc index 7cc8b721..858f7a9c 100644 --- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -3593,8 +3593,11 @@ // Check the document is correctly reloaded. RenderFrameHostImpl* main_document = wc->GetMainFrame(); EXPECT_EQ(main_frame_url, main_document->GetLastCommittedURL()); + // Execute script in an isolated world to avoid causing a Trusted Types + // violation due to eval. EXPECT_EQ("Graphics Feature Status", - EvalJs(main_document, "document.querySelector('h3').textContent")); + EvalJs(main_document, "document.querySelector('h3').textContent", + EXECUTE_SCRIPT_DEFAULT_OPTIONS, /*world_id=*/1)); } // Start with A(B), navigate A to C. By emulating a slow unload handler B, check
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index 954a1730..01dfeb9 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -131,7 +131,11 @@ {"video_decode", SafeGetFeatureStatus(gpu_feature_info, gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE), +#if defined(OS_LINUX) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS) + !command_line.HasSwitch(switches::kEnableAcceleratedVideoDecode), +#else command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode), +#endif // defined(OS_LINUX) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS) DisableInfo::Problem( "Accelerated video decode has been disabled, either via blocklist, " "about:flags or the command line."),
diff --git a/content/browser/manifest/manifest_manager_host.cc b/content/browser/manifest/manifest_manager_host.cc index 2b847ca0..bca8465 100644 --- a/content/browser/manifest/manifest_manager_host.cc +++ b/content/browser/manifest/manifest_manager_host.cc
@@ -7,8 +7,8 @@ #include <stdint.h> #include "base/bind.h" +#include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/browser/render_frame_host.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/manifest/manifest.h" @@ -16,7 +16,8 @@ namespace content { ManifestManagerHost::ManifestManagerHost(RenderFrameHost* render_frame_host) - : manifest_manager_frame_(render_frame_host) { + : manifest_manager_frame_( + static_cast<RenderFrameHostImpl*>(render_frame_host)) { // Check that |manifest_manager_frame_| is a main frame. DCHECK(!manifest_manager_frame_->GetParent()); } @@ -29,6 +30,9 @@ mojo::PendingAssociatedReceiver<blink::mojom::ManifestUrlChangeObserver> receiver) { manifest_url_change_observer_receiver_.Bind(std::move(receiver)); + manifest_url_change_observer_receiver_.SetFilter( + manifest_manager_frame_->CreateMessageFilterForAssociatedReceiver( + blink::mojom::ManifestUrlChangeObserver::Name_)); } void ManifestManagerHost::GetManifest(GetManifestCallback callback) {
diff --git a/content/browser/manifest/manifest_manager_host.h b/content/browser/manifest/manifest_manager_host.h index f706c20..6b1304b 100644 --- a/content/browser/manifest/manifest_manager_host.h +++ b/content/browser/manifest/manifest_manager_host.h
@@ -20,7 +20,7 @@ namespace content { -class RenderFrameHost; +class RenderFrameHostImpl; // ManifestManagerHost is a helper class that allows callers to get the Manifest // associated with the main frame of the observed WebContents. It handles the @@ -66,7 +66,7 @@ // blink::mojom::ManifestUrlChangeObserver: void ManifestUrlChanged(const base::Optional<GURL>& manifest_url) override; - RenderFrameHost* manifest_manager_frame_; + RenderFrameHostImpl* manifest_manager_frame_; mojo::Remote<blink::mojom::ManifestManager> manifest_manager_; CallbackMap callbacks_;
diff --git a/content/browser/media/capture/desktop_capturer_lacros.cc b/content/browser/media/capture/desktop_capturer_lacros.cc index 5a5b4721..67343dd 100644 --- a/content/browser/media/capture/desktop_capturer_lacros.cc +++ b/content/browser/media/capture/desktop_capturer_lacros.cc
@@ -7,7 +7,7 @@ #include "base/task/task_traits.h" #include "base/task/thread_pool.h" -#include "chromeos/crosapi/cpp/window_snapshot.h" +#include "chromeos/crosapi/cpp/bitmap.h" #include "chromeos/lacros/lacros_chrome_service_impl.h" namespace content { @@ -75,7 +75,7 @@ void DesktopCapturerLacros::CaptureFrame() { if (capture_type_ == kScreen) { - crosapi::WindowSnapshot snapshot; + crosapi::Bitmap snapshot; { // lacros-chrome is allowed to make sync calls to ash-chrome. mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call; @@ -84,7 +84,7 @@ DidTakeSnapshot(/*success=*/true, snapshot); } else { bool success; - crosapi::WindowSnapshot snapshot; + crosapi::Bitmap snapshot; { // lacros-chrome is allowed to make sync calls to ash-chrome. mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call; @@ -104,9 +104,8 @@ void DesktopCapturerLacros::SetExcludedWindow(webrtc::WindowId window) {} -void DesktopCapturerLacros::DidTakeSnapshot( - bool success, - const crosapi::WindowSnapshot& snapshot) { +void DesktopCapturerLacros::DidTakeSnapshot(bool success, + const crosapi::Bitmap& snapshot) { if (!success) { callback_->OnCaptureResult(Result::ERROR_PERMANENT, std::unique_ptr<webrtc::DesktopFrame>()); @@ -120,7 +119,7 @@ // This code assumes that the stride is 4 * width. This relies on the // assumption that there's no padding and each pixel is 4 bytes. frame->CopyPixelsFrom( - snapshot.bitmap.data(), 4 * snapshot.width, + snapshot.pixels.data(), 4 * snapshot.width, webrtc::DesktopRect::MakeWH(snapshot.width, snapshot.height)); callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
diff --git a/content/browser/media/capture/desktop_capturer_lacros.h b/content/browser/media/capture/desktop_capturer_lacros.h index 2fdb2fd..cbdcf137 100644 --- a/content/browser/media/capture/desktop_capturer_lacros.h +++ b/content/browser/media/capture/desktop_capturer_lacros.h
@@ -12,7 +12,7 @@ #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" namespace crosapi { -struct WindowSnapshot; +struct Bitmap; } // namespace crosapi namespace content { @@ -46,7 +46,7 @@ private: // Callback for when ash-chrome returns a snapshot of the screen or window as // a bitmap. - void DidTakeSnapshot(bool success, const crosapi::WindowSnapshot& snapshot); + void DidTakeSnapshot(bool success, const crosapi::Bitmap& snapshot); // Whether this object is capturing screens or windows. const CaptureType capture_type_;
diff --git a/content/browser/native_file_system/file_system_chooser_browsertest.cc b/content/browser/native_file_system/file_system_chooser_browsertest.cc index 7322505..58a76ab5 100644 --- a/content/browser/native_file_system/file_system_chooser_browsertest.cc +++ b/content/browser/native_file_system/file_system_chooser_browsertest.cc
@@ -9,7 +9,9 @@ #include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" #include "content/browser/native_file_system/file_system_chooser_test_helpers.h" +#include "content/browser/native_file_system/fixed_native_file_system_permission_grant.h" #include "content/browser/native_file_system/mock_native_file_system_permission_context.h" +#include "content/browser/native_file_system/mock_native_file_system_permission_grant.h" #include "content/browser/native_file_system/native_file_system_manager_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_context.h" @@ -367,21 +369,43 @@ ->GetNativeFileSystemEntryFactory()) ->SetPermissionContextForTesting(&permission_context); + auto read_grant = base::MakeRefCounted< + testing::StrictMock<MockNativeFileSystemPermissionGrant>>(); + auto write_grant = base::MakeRefCounted<FixedNativeFileSystemPermissionGrant>( + PermissionStatus::ASK); + EXPECT_CALL(permission_context, ConfirmSensitiveDirectoryAccess_( testing::_, testing::_, testing::_, testing::_, testing::_)) .WillOnce(RunOnceCallback<4>(SensitiveDirectoryResult::kAllowed)); + auto origin = + url::Origin::Create(embedded_test_server()->GetURL("/title1.html")); + EXPECT_CALL(permission_context, + GetReadPermissionGrant( + origin, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen)) + .WillOnce(testing::Return(read_grant)); + EXPECT_CALL(permission_context, + GetWritePermissionGrant( + origin, test_dir, + NativeFileSystemPermissionContext::HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen)) + .WillOnce(testing::Return(write_grant)); + EXPECT_CALL( - permission_context, - ConfirmDirectoryReadAccess_( - url::Origin::Create(embedded_test_server()->GetURL("/title1.html")), - test_dir, + *read_grant, + RequestPermission_( GlobalFrameRoutingId( shell()->web_contents()->GetMainFrame()->GetProcess()->GetID(), shell()->web_contents()->GetMainFrame()->GetRoutingID()), + NativeFileSystemPermissionGrant::UserActivationState::kNotRequired, testing::_)) - .WillOnce(RunOnceCallback<3>(PermissionStatus::DENIED)); + .WillOnce(RunOnceCallback<2>(NativeFileSystemPermissionGrant:: + PermissionRequestOutcome::kUserDenied)); + EXPECT_CALL(*read_grant, GetStatus()) + .WillRepeatedly(testing::Return(PermissionStatus::ASK)); ASSERT_TRUE( NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html")));
diff --git a/content/browser/native_file_system/fixed_native_file_system_permission_grant.cc b/content/browser/native_file_system/fixed_native_file_system_permission_grant.cc index d372b0fe..54d92c0f 100644 --- a/content/browser/native_file_system/fixed_native_file_system_permission_grant.cc +++ b/content/browser/native_file_system/fixed_native_file_system_permission_grant.cc
@@ -20,6 +20,7 @@ void FixedNativeFileSystemPermissionGrant::RequestPermission( GlobalFrameRoutingId frame_id, + UserActivationState user_activation_state, base::OnceCallback<void(PermissionRequestOutcome)> callback) { std::move(callback).Run(PermissionRequestOutcome::kRequestAborted); }
diff --git a/content/browser/native_file_system/fixed_native_file_system_permission_grant.h b/content/browser/native_file_system/fixed_native_file_system_permission_grant.h index 064150c..935cce80 100644 --- a/content/browser/native_file_system/fixed_native_file_system_permission_grant.h +++ b/content/browser/native_file_system/fixed_native_file_system_permission_grant.h
@@ -25,6 +25,7 @@ PermissionStatus GetStatus() override; void RequestPermission( GlobalFrameRoutingId frame_id, + UserActivationState user_activation_state, base::OnceCallback<void(PermissionRequestOutcome)> callback) override; protected:
diff --git a/content/browser/native_file_system/mock_native_file_system_permission_context.cc b/content/browser/native_file_system/mock_native_file_system_permission_context.cc index 059fcf0..702f21f 100644 --- a/content/browser/native_file_system/mock_native_file_system_permission_context.cc +++ b/content/browser/native_file_system/mock_native_file_system_permission_context.cc
@@ -11,14 +11,6 @@ MockNativeFileSystemPermissionContext:: ~MockNativeFileSystemPermissionContext() = default; -void MockNativeFileSystemPermissionContext::ConfirmDirectoryReadAccess( - const url::Origin& origin, - const base::FilePath& path, - GlobalFrameRoutingId frame_id, - base::OnceCallback<void(PermissionStatus)> callback) { - ConfirmDirectoryReadAccess_(origin, path, frame_id, callback); -} - void MockNativeFileSystemPermissionContext::ConfirmSensitiveDirectoryAccess( const url::Origin& origin, const std::vector<base::FilePath>& paths,
diff --git a/content/browser/native_file_system/mock_native_file_system_permission_context.h b/content/browser/native_file_system/mock_native_file_system_permission_context.h index 480d4d3a..82fe8a2 100644 --- a/content/browser/native_file_system/mock_native_file_system_permission_context.h +++ b/content/browser/native_file_system/mock_native_file_system_permission_context.h
@@ -21,7 +21,6 @@ const url::Origin& origin, const base::FilePath& path, HandleType handle_type, - NativeFileSystemPermissionContext::UserAction user_action)); MOCK_METHOD4(GetWritePermissionGrant, @@ -29,20 +28,8 @@ const url::Origin& origin, const base::FilePath& path, HandleType handle_type, - NativeFileSystemPermissionContext::UserAction user_action)); - void ConfirmDirectoryReadAccess( - const url::Origin& origin, - const base::FilePath& path, - GlobalFrameRoutingId frame_id, - base::OnceCallback<void(PermissionStatus)> callback) override; - MOCK_METHOD4(ConfirmDirectoryReadAccess_, - void(const url::Origin& origin, - const base::FilePath& path, - GlobalFrameRoutingId frame_id, - base::OnceCallback<void(PermissionStatus)>& callback)); - void ConfirmSensitiveDirectoryAccess( const url::Origin& origin, const std::vector<base::FilePath>& paths,
diff --git a/content/browser/native_file_system/mock_native_file_system_permission_grant.cc b/content/browser/native_file_system/mock_native_file_system_permission_grant.cc index 7698d079..44cbbff2 100644 --- a/content/browser/native_file_system/mock_native_file_system_permission_grant.cc +++ b/content/browser/native_file_system/mock_native_file_system_permission_grant.cc
@@ -13,8 +13,9 @@ void MockNativeFileSystemPermissionGrant::RequestPermission( GlobalFrameRoutingId frame_id, + UserActivationState user_activation_state, base::OnceCallback<void(PermissionRequestOutcome)> callback) { - RequestPermission_(frame_id, callback); + RequestPermission_(frame_id, user_activation_state, callback); } } // namespace content
diff --git a/content/browser/native_file_system/mock_native_file_system_permission_grant.h b/content/browser/native_file_system/mock_native_file_system_permission_grant.h index 7e185e74..e57ccef9 100644 --- a/content/browser/native_file_system/mock_native_file_system_permission_grant.h +++ b/content/browser/native_file_system/mock_native_file_system_permission_grant.h
@@ -19,9 +19,11 @@ MOCK_METHOD0(GetStatus, PermissionStatus()); void RequestPermission( GlobalFrameRoutingId frame_id, + UserActivationState user_activation_state, base::OnceCallback<void(PermissionRequestOutcome)> callback) override; - MOCK_METHOD2(RequestPermission_, + MOCK_METHOD3(RequestPermission_, void(GlobalFrameRoutingId frame_id, + UserActivationState user_activation_state, base::OnceCallback<void(PermissionRequestOutcome)>&)); using NativeFileSystemPermissionGrant::NotifyPermissionStatusChanged;
diff --git a/content/browser/native_file_system/native_file_system_handle_base.cc b/content/browser/native_file_system/native_file_system_handle_base.cc index 88a32b1..0ae3ee0 100644 --- a/content/browser/native_file_system/native_file_system_handle_base.cc +++ b/content/browser/native_file_system/native_file_system_handle_base.cc
@@ -113,6 +113,7 @@ if (!writable) { handle_state_.read_grant->RequestPermission( context().frame_id, + NativeFileSystemPermissionGrant::UserActivationState::kRequired, base::BindOnce(&NativeFileSystemHandleBase::DidRequestPermission, AsWeakPtr(), writable, std::move(callback))); return; @@ -125,12 +126,15 @@ // the write permission request probably fails the same way. And we check // the final permission status after the permission request completes // anyway. - handle_state_.read_grant->RequestPermission(context().frame_id, - base::DoNothing()); + handle_state_.read_grant->RequestPermission( + context().frame_id, + NativeFileSystemPermissionGrant::UserActivationState::kRequired, + base::DoNothing()); } handle_state_.write_grant->RequestPermission( context().frame_id, + NativeFileSystemPermissionGrant::UserActivationState::kRequired, base::BindOnce(&NativeFileSystemHandleBase::DidRequestPermission, AsWeakPtr(), writable, std::move(callback))); }
diff --git a/content/browser/native_file_system/native_file_system_handle_base_unittest.cc b/content/browser/native_file_system/native_file_system_handle_base_unittest.cc index a1bc5cc5..5090b6e1 100644 --- a/content/browser/native_file_system/native_file_system_handle_base_unittest.cc +++ b/content/browser/native_file_system/native_file_system_handle_base_unittest.cc
@@ -21,6 +21,8 @@ using base::test::RunOnceCallback; using blink::mojom::PermissionStatus; using storage::FileSystemURL; +using UserActivationState = + NativeFileSystemPermissionGrant::UserActivationState; class TestNativeFileSystemHandle : public NativeFileSystemHandleBase { public: @@ -188,9 +190,11 @@ testing::InSequence sequence; EXPECT_CALL(*write_grant_, GetStatus()) .WillOnce(testing::Return(PermissionStatus::ASK)); - EXPECT_CALL(*write_grant_, RequestPermission_(kFrameId, testing::_)) + EXPECT_CALL(*write_grant_, + RequestPermission_(kFrameId, UserActivationState::kRequired, + testing::_)) .WillOnce( - RunOnceCallback<1>(NativeFileSystemPermissionGrant:: + RunOnceCallback<2>(NativeFileSystemPermissionGrant:: PermissionRequestOutcome::kUserGranted)); EXPECT_CALL(*write_grant_, GetStatus()) .WillOnce(testing::Return(PermissionStatus::GRANTED));
diff --git a/content/browser/native_file_system/native_file_system_manager_impl.cc b/content/browser/native_file_system/native_file_system_manager_impl.cc index bb6eed3..e7630d2 100644 --- a/content/browser/native_file_system/native_file_system_manager_impl.cc +++ b/content/browser/native_file_system/native_file_system_manager_impl.cc
@@ -823,16 +823,15 @@ if (options.type() == blink::mojom::ChooseFileSystemEntryType::kOpenDirectory) { DCHECK_EQ(entries.size(), 1u); - if (permission_context_) { - permission_context_->ConfirmDirectoryReadAccess( - binding_context.origin, entries.front(), binding_context.frame_id, - base::BindOnce(&NativeFileSystemManagerImpl::DidChooseDirectory, this, - binding_context, entries.front(), - std::move(callback))); - } else { - DidChooseDirectory(binding_context, entries.front(), std::move(callback), - PermissionStatus::GRANTED); - } + SharedHandleState shared_handle_state = GetSharedHandleStateForPath( + entries.front(), binding_context.origin, {}, HandleType::kDirectory, + NativeFileSystemPermissionContext::UserAction::kOpen); + shared_handle_state.read_grant->RequestPermission( + binding_context.frame_id, + NativeFileSystemPermissionGrant::UserActivationState::kNotRequired, + base::BindOnce(&NativeFileSystemManagerImpl::DidChooseDirectory, this, + binding_context, entries.front(), std::move(callback), + shared_handle_state)); return; } @@ -881,20 +880,31 @@ const BindingContext& binding_context, const base::FilePath& path, ChooseEntriesCallback callback, - NativeFileSystemPermissionContext::PermissionStatus permission) { + const SharedHandleState& shared_handle_state, + NativeFileSystemPermissionGrant::PermissionRequestOutcome outcome) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); base::UmaHistogramEnumeration( - "NativeFileSystemAPI.ConfirmReadDirectoryResult", permission); + "NativeFileSystemAPI.ConfirmReadDirectoryResult", + shared_handle_state.read_grant->GetStatus()); std::vector<blink::mojom::NativeFileSystemEntryPtr> result_entries; - if (permission != PermissionStatus::GRANTED) { + if (shared_handle_state.read_grant->GetStatus() != + PermissionStatus::GRANTED) { std::move(callback).Run(native_file_system_error::FromStatus( NativeFileSystemStatus::kOperationAborted), std::move(result_entries)); return; } - result_entries.push_back(CreateDirectoryEntryFromPath(binding_context, path)); + auto url = CreateFileSystemURLFromPath(binding_context.origin, path); + + result_entries.push_back(blink::mojom::NativeFileSystemEntry::New( + blink::mojom::NativeFileSystemHandle::NewDirectory(CreateDirectoryHandle( + binding_context, url.url, + SharedHandleState(shared_handle_state.read_grant, + shared_handle_state.write_grant, + std::move(url.file_system)))), + url.base_name)); std::move(callback).Run(native_file_system_error::Ok(), std::move(result_entries)); }
diff --git a/content/browser/native_file_system/native_file_system_manager_impl.h b/content/browser/native_file_system/native_file_system_manager_impl.h index 48e3203..1158d25d 100644 --- a/content/browser/native_file_system/native_file_system_manager_impl.h +++ b/content/browser/native_file_system/native_file_system_manager_impl.h
@@ -261,7 +261,8 @@ const BindingContext& binding_context, const base::FilePath& path, ChooseEntriesCallback callback, - NativeFileSystemPermissionContext::PermissionStatus permission); + const SharedHandleState& shared_handle_state, + NativeFileSystemPermissionGrant::PermissionRequestOutcome outcome); void CreateTransferTokenImpl( const storage::FileSystemURL& url,
diff --git a/content/browser/portal/portal.cc b/content/browser/portal/portal.cc index 506852d..4da15e4 100644 --- a/content/browser/portal/portal.cc +++ b/content/browser/portal/portal.cc
@@ -96,6 +96,8 @@ if (receiver.is_bound()) receiver.reset(); receiver.Bind(std::move(pending_receiver)); + receiver.SetFilter(frame->CreateMessageFilterForAssociatedReceiver( + blink::mojom::PortalHost::Name_)); } void Portal::Bind(
diff --git a/content/browser/renderer_host/page_lifecycle_state_manager.cc b/content/browser/renderer_host/page_lifecycle_state_manager.cc index 4be5301..4ac9c39 100644 --- a/content/browser/renderer_host/page_lifecycle_state_manager.cc +++ b/content/browser/renderer_host/page_lifecycle_state_manager.cc
@@ -15,6 +15,17 @@ namespace content { +PageLifecycleStateManager::TestDelegate::TestDelegate() = default; + +PageLifecycleStateManager::TestDelegate::~TestDelegate() = default; + +void PageLifecycleStateManager::TestDelegate::OnLastAcknowledgedStateChanged( + const blink::mojom::PageLifecycleState& old_state, + const blink::mojom::PageLifecycleState& new_state) {} + +void PageLifecycleStateManager::TestDelegate::OnUpdateSentToRenderer( + const blink::mojom::PageLifecycleState& new_state) {} + PageLifecycleStateManager::PageLifecycleStateManager( RenderViewHostImpl* render_view_host_impl, blink::mojom::PageVisibilityState web_contents_visibility_state) @@ -24,7 +35,9 @@ last_state_sent_to_renderer_ = last_acknowledged_state_.Clone(); } -PageLifecycleStateManager::~PageLifecycleStateManager() = default; +PageLifecycleStateManager::~PageLifecycleStateManager() { + DCHECK(!test_delegate_); +} void PageLifecycleStateManager::SetIsFrozen(bool frozen) { if (is_set_frozen_called_ == frozen) @@ -84,6 +97,10 @@ last_state_sent_to_renderer_ = new_state.Clone(); auto state = new_state.Clone(); + + if (test_delegate_) + test_delegate_->OnUpdateSentToRenderer(*last_state_sent_to_renderer_); + render_view_host_impl_->GetAssociatedPageBroadcast()->SetPageLifecycleState( std::move(state), std::move(navigation_start), base::BindOnce(&PageLifecycleStateManager::OnPageLifecycleChangedAck, @@ -103,11 +120,18 @@ void PageLifecycleStateManager::OnPageLifecycleChangedAck( blink::mojom::PageLifecycleStatePtr acknowledged_state) { + blink::mojom::PageLifecycleStatePtr old_state = + std::move(last_acknowledged_state_); last_acknowledged_state_ = std::move(acknowledged_state); if (last_acknowledged_state_->is_in_back_forward_cache) { back_forward_cache_timeout_monitor_.reset(nullptr); } + + if (test_delegate_) { + test_delegate_->OnLastAcknowledgedStateChanged(*old_state, + *last_acknowledged_state_); + } } void PageLifecycleStateManager::OnBackForwardCacheTimeout() { @@ -116,4 +140,10 @@ back_forward_cache_timeout_monitor_.reset(nullptr); } +void PageLifecycleStateManager::SetDelegateForTesting( + PageLifecycleStateManager::TestDelegate* test_delegate) { + DCHECK(!test_delegate_ || !test_delegate); + test_delegate_ = test_delegate; +} + } // namespace content
diff --git a/content/browser/renderer_host/page_lifecycle_state_manager.h b/content/browser/renderer_host/page_lifecycle_state_manager.h index 371095d..889f88b7 100644 --- a/content/browser/renderer_host/page_lifecycle_state_manager.h +++ b/content/browser/renderer_host/page_lifecycle_state_manager.h
@@ -5,6 +5,8 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_PAGE_LIFECYCLE_STATE_MANAGER_H_ #define CONTENT_BROWSER_RENDERER_HOST_PAGE_LIFECYCLE_STATE_MANAGER_H_ +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" #include "content/browser/renderer_host/input/one_shot_timeout_monitor.h" #include "content/common/content_export.h" #include "content/public/common/page_visibility_state.h" @@ -19,6 +21,17 @@ // and communicating in to the RenderView. 1:1 with RenderViewHostImpl. class CONTENT_EXPORT PageLifecycleStateManager { public: + class CONTENT_EXPORT TestDelegate { + public: + TestDelegate(); + virtual ~TestDelegate(); + virtual void OnLastAcknowledgedStateChanged( + const blink::mojom::PageLifecycleState& old_state, + const blink::mojom::PageLifecycleState& new_state); + virtual void OnUpdateSentToRenderer( + const blink::mojom::PageLifecycleState& new_state); + }; + explicit PageLifecycleStateManager( RenderViewHostImpl* render_view_host_impl, blink::mojom::PageVisibilityState web_contents_visibility_state); @@ -35,6 +48,16 @@ // lifecycle state saved in this instance. blink::mojom::PageLifecycleStatePtr CalculatePageLifecycleState(); + const blink::mojom::PageLifecycleState& last_acknowledged_state() const { + return *last_acknowledged_state_; + } + + const blink::mojom::PageLifecycleState& last_state_sent_to_renderer() const { + return *last_state_sent_to_renderer_; + } + + void SetDelegateForTesting(TestDelegate* test_delegate_); + private: // Send mojo message to renderer if the effective (page) lifecycle state has // changed. @@ -70,6 +93,8 @@ blink::mojom::PageLifecycleStatePtr last_state_sent_to_renderer_; std::unique_ptr<OneShotTimeoutMonitor> back_forward_cache_timeout_monitor_; + + TestDelegate* test_delegate_{nullptr}; // NOTE: This must be the last member. base::WeakPtrFactory<PageLifecycleStateManager> weak_ptr_factory_{this}; };
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 8cf487c..cf41625 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1881,6 +1881,7 @@ child_process_.get()); fast_shutdown_started_ = false; + shutdown_requested_ = false; } init_time_ = clock_->NowTicks(); @@ -3279,6 +3280,9 @@ #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !BUILDFLAG(IS_LACROS) switches::kDisableDevShmUsage, #endif +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + switches::kEnableAcceleratedVideoDecode, +#endif #if defined(OS_MAC) // Allow this to be set when invoking the browser and relayed along. sandbox::policy::switches::kEnableSandboxLogging, @@ -3320,7 +3324,6 @@ switches::kDisableSpeechAPI, switches::kDisableThreadedCompositing, switches::kDisableThreadedScrolling, - switches::kDisableTouchAdjustment, switches::kDisableTouchDragDrop, switches::kDisableV8IdleTasks, switches::kDisableVideoCaptureUseGpuMemoryBuffer, @@ -3558,9 +3561,14 @@ return false; shutdown_exit_code_ = exit_code; + shutdown_requested_ = true; return child_process_launcher_->Terminate(exit_code); } +bool RenderProcessHostImpl::ShutdownRequested() { + return shutdown_requested_; +} + bool RenderProcessHostImpl::FastShutdownIfPossible(size_t page_count, bool skip_unload_handlers) { // Do not shut down the process if there are active or pending views other @@ -4549,6 +4557,8 @@ void RenderProcessHostImpl::ProcessDied( bool already_dead, ChildProcessTerminationInfo* known_info) { + TRACE_EVENT1("content", "RenderProcessHostImpl::ProcessDied", "already_dead", + already_dead); // Our child process has died. If we didn't expect it, it's a crash. // In any case, we need to let everyone know it's gone. // The OnChannelError notification can fire multiple times due to nested
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 38e81681..4d9e7ef 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -200,6 +200,7 @@ bool IsForGuestsOnly() override; StoragePartition* GetStoragePartition() override; bool Shutdown(int exit_code) override; + bool ShutdownRequested() override; bool FastShutdownIfPossible(size_t page_count = 0, bool skip_unload_handlers = false) override; const base::Process& GetProcess() override; @@ -691,6 +692,9 @@ // True if fast shutdown has been performed on this RPH. bool fast_shutdown_started_; + // True if shutdown from started by the |Shutdown()| method. + bool shutdown_requested_ = false; + // True if we've posted a DeleteTask and will be deleted soon. bool deleting_soon_; @@ -938,7 +942,7 @@ // Creates a URLLoaderFactory that can be used by the renderer process, // without binding it to a specific frame or an origin. // - // TODO(kinuko, lukasza): https://crbug.com/1098938: Remove, once all + // TODO(kinuko, lukasza): https://crbug.com/1114822: Remove, once all // URLLoaderFactories vended to a renderer process are associated with a // specific origin and an execution context (e.g. a frame, a service worker or // any other kind of worker).
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index d56bdbc..7dcc21f6 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -101,6 +101,7 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/system/platform_handle.h" #include "net/base/filename_util.h" +#include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "skia/ext/image_operations.h" #include "skia/ext/platform_canvas.h" #include "storage/browser/file_system/isolated_context.h" @@ -308,8 +309,9 @@ items.push_back(blink::mojom::DragItem::NewString(std::move(item))); } - return blink::mojom::DragData::New( - std::move(items), base::UTF16ToUTF8(drop_data.filesystem_id)); + return blink::mojom::DragData::New(std::move(items), + base::UTF16ToUTF8(drop_data.filesystem_id), + drop_data.referrer_policy); } class UnboundWidgetInputHandler : public blink::mojom::WidgetInputHandler { @@ -512,6 +514,8 @@ } void RenderWidgetHostImpl::SetView(RenderWidgetHostViewBase* view) { + synthetic_gesture_controller_.reset(); + if (view) { view_ = view->GetWeakPtr(); if (!create_frame_sink_callback_.is_null()) @@ -519,8 +523,6 @@ } else { view_.reset(); } - - synthetic_gesture_controller_.reset(); } // static
diff --git a/content/browser/service_worker/service_worker_registry.cc b/content/browser/service_worker/service_worker_registry.cc index ef7d4f7..cb2a54b 100644 --- a/content/browser/service_worker/service_worker_registry.cc +++ b/content/browser/service_worker/service_worker_registry.cc
@@ -1164,22 +1164,6 @@ return; } - // Purge the deleted version's resources now if needed. This is subtle. The - // version might still be used for a long time even after it's deleted. We can - // only purge safely once the version is REDUNDANT, since it will never be - // used again. - // - // If the deleted version's ServiceWorkerVersion doesn't exist, we can assume - // it's effectively REDUNDANT so it's safe to purge now. This is because the - // caller is assumed to promote the new version to active unless the deleted - // version is doing work, and it can't be doing work if it's not live. - // - // If the ServiceWorkerVersion does exist, it triggers purging once it reaches - // REDUNDANT. Otherwise, purging happens on the next browser session (via - // DeleteStaleResources). - if (!context_->GetLiveVersion(deleted_version_id)) - storage()->PurgeResources(newly_purgeable_resources); - scoped_refptr<ServiceWorkerRegistration> registration = context_->GetLiveRegistration(stored_registration_id); if (registration) { @@ -1215,9 +1199,6 @@ return; } - if (!context_->GetLiveVersion(deleted_version_id)) - storage()->PurgeResources(newly_purgeable_resources); - scoped_refptr<ServiceWorkerRegistration> registration = context_->GetLiveRegistration(registration_id); if (registration)
diff --git a/content/browser/service_worker/service_worker_storage_control_impl.cc b/content/browser/service_worker/service_worker_storage_control_impl.cc index 56ed554d..81c094d 100644 --- a/content/browser/service_worker/service_worker_storage_control_impl.cc +++ b/content/browser/service_worker/service_worker_storage_control_impl.cc
@@ -49,9 +49,18 @@ void set_purgeable_resources( const std::vector<int64_t>& purgeable_resources) { - DCHECK(purgeable_resources_.empty()); + if (!purgeable_resources_.empty()) { + // This setter method can be called multiple times but the resource ids + // should be the same. + DCHECK(std::set<int64_t>(purgeable_resources_.begin(), + purgeable_resources_.end()) == + std::set<int64_t>(purgeable_resources.begin(), + purgeable_resources.end())); + return; + } purgeable_resources_ = purgeable_resources; } + const std::vector<int64_t>& purgeable_resources() const { return purgeable_resources_; } @@ -90,8 +99,7 @@ void ServiceWorkerStorageControlImpl::OnNoLiveVersion(int64_t version_id) { auto it = live_versions_.find(version_id); DCHECK(it != live_versions_.end()); - if (purge_resources_when_no_live_versions_ && - it->second->purgeable_resources().size() > 0) { + if (it->second->purgeable_resources().size() > 0) { storage_->PurgeResources(it->second->purgeable_resources()); } live_versions_.erase(it); @@ -101,11 +109,6 @@ storage_->LazyInitializeForTest(); } -void ServiceWorkerStorageControlImpl:: - EnableResourcePurgingOnNoLiveVersionForTest() { - purge_resources_when_no_live_versions_ = true; -} - void ServiceWorkerStorageControlImpl::GetRegisteredOrigins( GetRegisteredOriginsCallback callback) { storage_->GetRegisteredOrigins(std::move(callback)); @@ -469,8 +472,7 @@ void ServiceWorkerStorageControlImpl::MaybePurgeResources( int64_t version_id, const std::vector<int64_t>& purgeable_resources) { - if (!purge_resources_when_no_live_versions_ || - version_id == blink::mojom::kInvalidServiceWorkerVersionId || + if (version_id == blink::mojom::kInvalidServiceWorkerVersionId || purgeable_resources.size() == 0) { return; }
diff --git a/content/browser/service_worker/service_worker_storage_control_impl.h b/content/browser/service_worker/service_worker_storage_control_impl.h index 626a4d8..1a681bc 100644 --- a/content/browser/service_worker/service_worker_storage_control_impl.h +++ b/content/browser/service_worker/service_worker_storage_control_impl.h
@@ -47,12 +47,6 @@ void LazyInitializeForTest(); - // When enabled, the instance of this class manages when to purge resources - // (service worker scripts) which are no longer used. - // TODO(crbug.com/1055677): Remove this once resource purging logic is - // completely moved from ServiceWorkerRegistry to this class. - void EnableResourcePurgingOnNoLiveVersionForTest(); - private: // storage::mojom::ServiceWorkerStorageControl implementations: void GetRegisteredOrigins(GetRegisteredOriginsCallback callback) override; @@ -199,8 +193,6 @@ std::unique_ptr<ServiceWorkerLiveVersionRefImpl>> live_versions_; - bool purge_resources_when_no_live_versions_ = false; - base::WeakPtrFactory<ServiceWorkerStorageControlImpl> weak_ptr_factory_{this}; };
diff --git a/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc b/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc index c3cf229..ca11258 100644 --- a/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc +++ b/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc
@@ -185,7 +185,6 @@ /*quota_manager_proxy=*/nullptr); storage_impl_ = std::make_unique<ServiceWorkerStorageControlImpl>(std::move(storage)); - storage_impl_->EnableResourcePurgingOnNoLiveVersionForTest(); } void DestroyStorage() {
diff --git a/content/browser/service_worker/service_worker_storage_unittest.cc b/content/browser/service_worker/service_worker_storage_unittest.cc index 2a64914..cd1c9e1 100644 --- a/content/browser/service_worker/service_worker_storage_unittest.cc +++ b/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -1481,8 +1481,6 @@ } TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) { - registration_->SetWaitingVersion(nullptr); - // Deleting the registration should result in the resources being added to the // purgeable list and then doomed in the disk cache and removed from that // list. @@ -1490,9 +1488,15 @@ storage()->SetPurgingCompleteCallbackForTest(loop.QuitClosure()); EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, DeleteRegistration(registration_, scope_.GetOrigin())); + // At this point registration_->waiting_version() has a remote reference, so + // the resources should be in the purgeable list. EXPECT_EQ(2u, GetPurgeableResourceIdsFromDB().size()); + + registration_->SetWaitingVersion(nullptr); loop.Run(); + // registration_->waiting_version() is cleared. The resources should be + // purged at this point. EXPECT_TRUE(GetPurgeableResourceIdsFromDB().empty()); EXPECT_FALSE(VerifyBasicResponse(storage_control(), resource_id1_, false)); EXPECT_FALSE(VerifyBasicResponse(storage_control(), resource_id2_, false)); @@ -1770,9 +1774,6 @@ live_version->set_fetch_handler_existence( ServiceWorkerVersion::FetchHandlerExistence::EXISTS); - // Destroy the active version. - registration_->UnsetVersion(registration_->active_version()); - // Writing the registration should purge the old version's resources, // since it's not live. base::RunLoop loop; @@ -1782,6 +1783,9 @@ StoreRegistration(registration_.get(), registration_->waiting_version())); EXPECT_EQ(2u, GetPurgeableResourceIdsFromDB().size()); + // Destroy the active version. + registration_->UnsetVersion(registration_->active_version()); + // The resources should be purged. loop.Run(); EXPECT_TRUE(GetPurgeableResourceIdsFromDB().empty());
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 1d3dd19..82ff3d7 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -374,11 +374,9 @@ } else if (status == REDUNDANT) { embedded_worker_->OnWorkerVersionDoomed(); - // Tell the storage system that this worker's script resources can now be - // deleted. - std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources; - script_cache_map_.GetResources(&resources); - context_->storage()->PurgeResources(resources); + // Drop the remote reference to tell the storage system that the worker + // script resources can now be deleted. + remote_reference_.reset(); } }
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index 4a060707..b167aaf4 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc
@@ -1185,28 +1185,6 @@ return true; } -// static -base::Optional<url::Origin> SiteInstanceImpl::GetRequestInitiatorSiteLock( - const ProcessLock& lock) { - // The following schemes are safe for sites that require a process lock: - // - data: - locking |request_initiator| to an opaque origin - // - http/https - requiring |request_initiator| to match |site_url| with - // DomainIs (i.e. suffix-based) comparison. - if (lock.matches_scheme(url::kHttpScheme) || - lock.matches_scheme(url::kHttpsScheme) || - lock.matches_scheme(url::kDataScheme)) { - url::Origin origin = url::Origin::Create(lock.lock_url()); - // Only return an opaque origin if it's a data url. If http/https creates an - // opaque origin, then the url was invalid to begin with. - if (!origin.opaque() || lock.matches_scheme(url::kDataScheme)) - return origin; - } - - // Other schemes might not be safe to use as |request_initiator_site_lock|. - // One example is chrome-guest://... - return base::nullopt; -} - void SiteInstanceImpl::RenderProcessHostDestroyed(RenderProcessHost* host) { DCHECK_EQ(process_, host); process_->RemoveObserver(this);
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h index 40567ece..9fffa8c 100644 --- a/content/browser/site_instance_impl.h +++ b/content/browser/site_instance_impl.h
@@ -9,7 +9,6 @@ #include <stdint.h> #include "base/observer_list.h" -#include "base/optional.h" #include "content/browser/isolation_context.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/common/content_export.h" @@ -421,17 +420,6 @@ const GURL& site_url, const bool is_guest); - // Converts |lock| into an origin that can be used as - // |URLLoaderFactoryParams::request_initiator_site_lock|. - // This means that the returned origin can be safely used in a eTLD+1 - // comparison against |network::ResourceRequest::request_initiator|. - // - // base::nullopt is returned if |lock| cannot be used as a - // |request_initiator_site_lock| (e.g. in case of site_url = - // chrome-guest://...). - static base::Optional<url::Origin> GetRequestInitiatorSiteLock( - const ProcessLock& lock); - // Return an ID of the next BrowsingInstance to be created. This ID is // guaranteed to be higher than any ID of an existing BrowsingInstance. // This is useful when process model decisions need to be scoped only to
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 8c16f55..384831e 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -8155,10 +8155,10 @@ // Now, simulate that both FrameHostMsg_ShowCreatedWindow messages arrive by // showing both of the pending WebContents. - web_contents()->ShowCreatedWindow(process1->GetID(), routing_id1, + web_contents()->ShowCreatedWindow(frame1, routing_id1, WindowOpenDisposition::NEW_FOREGROUND_TAB, gfx::Rect(), true); - web_contents()->ShowCreatedWindow(process2->GetID(), routing_id2, + web_contents()->ShowCreatedWindow(frame2, routing_id2, WindowOpenDisposition::NEW_FOREGROUND_TAB, gfx::Rect(), true);
diff --git a/content/browser/url_loader_factory_params_helper.cc b/content/browser/url_loader_factory_params_helper.cc index f8d1492d..0c19cbc 100644 --- a/content/browser/url_loader_factory_params_helper.cc +++ b/content/browser/url_loader_factory_params_helper.cc
@@ -6,9 +6,7 @@ #include "base/command_line.h" #include "base/optional.h" -#include "content/browser/child_process_security_policy_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h" -#include "content/browser/site_instance_impl.h" #include "content/browser/storage_partition_impl.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_process_host.h" @@ -35,14 +33,10 @@ // network::ResourceRequest::request_initiator, except when // |is_for_isolated_world|. See also the doc comment for // extensions::URLLoaderFactoryManager::CreateFactory. -// -// TODO(kinuko, lukasza): https://crbug.com/1098938: Make -// |request_initiator_site_lock| non-optional, once -// URLLoaderFactoryParamsHelper::CreateForRendererProcess is removed. network::mojom::URLLoaderFactoryParamsPtr CreateParams( RenderProcessHost* process, const url::Origin& origin, - const base::Optional<url::Origin>& request_initiator_site_lock, + const url::Origin& request_initiator_site_lock, bool is_trusted, const base::Optional<base::UnguessableToken>& top_frame_token, const net::IsolationInfo& isolation_info, @@ -57,8 +51,7 @@ // "chrome-guest://..." is never used as a main or isolated world origin. DCHECK_NE(kGuestScheme, origin.scheme()); - DCHECK(!request_initiator_site_lock.has_value() || - request_initiator_site_lock->scheme() != kGuestScheme); + DCHECK_NE(kGuestScheme, request_initiator_site_lock.scheme()); network::mojom::URLLoaderFactoryParamsPtr params = network::mojom::URLLoaderFactoryParams::New(); @@ -205,13 +198,13 @@ network::mojom::URLLoaderFactoryParamsPtr URLLoaderFactoryParamsHelper::CreateForRendererProcess( RenderProcessHost* process) { - // Attempt to use the process lock as |request_initiator_site_lock|. - auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); - ProcessLock process_lock = policy->GetProcessLock(process->GetID()); - base::Optional<url::Origin> request_initiator_site_lock = - SiteInstanceImpl::GetRequestInitiatorSiteLock(process_lock); + // Lock the |request_initiator| to an opaque origin - before something commits + // in a frame, requests initiated by such frame should use an opaque + // |request_initiator|. See also https://crbug.com/1105794 and + // https://crbug.com/1098938. + url::Origin request_initiator_site_lock = url::Origin(); - // Since this function is about to get deprecated (crbug.com/1098938), it + // Since this function is about to get deprecated (crbug.com/1114822), it // should be fine to not add support for isolation info thus using an empty // NetworkIsolationKey. //
diff --git a/content/browser/url_loader_factory_params_helper.h b/content/browser/url_loader_factory_params_helper.h index 8096520..426779e 100644 --- a/content/browser/url_loader_factory_params_helper.h +++ b/content/browser/url_loader_factory_params_helper.h
@@ -72,7 +72,7 @@ mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter> coep_reporter); - // TODO(kinuko, lukasza): https://crbug.com/1098938: Remove, once all + // TODO(kinuko, lukasza): https://crbug.com/1114822: Remove, once all // URLLoaderFactories vended to a renderer process are associated with a // specific origin and an execution context (e.g. a frame, a service worker or // any other kind of worker).
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 8194f70..478fee6 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -75,6 +75,7 @@ #include "content/browser/media/capture/web_contents_audio_muter.h" #include "content/browser/media/media_web_contents_observer.h" #include "content/browser/media/session/media_session_impl.h" +#include "content/browser/permissions/permission_controller_impl.h" #include "content/browser/plugin_content_origin_allowlist.h" #include "content/browser/portal/portal.h" #include "content/browser/renderer_host/frame_token_message_queue.h" @@ -457,6 +458,36 @@ return set_holder->set(); } +// Adjust the requested |bounds| for opening or placing a window. The bounds +// may not extend outside a single screen's work area, and the |host| requires +// permission to specify bounds on a screen other than its current screen. +// TODO(crbug.com/897300): These adjustments are inaccurate for window.open(), +// which specifies the inner content size, and for window.moveTo, resizeTo, etc. +// calls on newly created windows, which may pass empty sizes or positions to +// indicate uninitialized placement information in the renderer. Constraints +// enforced later should resolve most inaccuracies, but this early enforcement +// is needed to ensure bounds indicate the appropriate display. +gfx::Rect AdjustRequestedWindowBounds(gfx::Rect bounds, RenderFrameHost* host) { + auto* screen = display::Screen::GetScreen(); + auto display = screen->GetDisplayMatching(bounds); + + // Check, but do not prompt, for permission to place windows on other screens. + // Sites generally need permission to get such bounds in the first place. + // Also clamp offscreen bounds to the window's current screen. + auto* controller = + PermissionControllerImpl::FromBrowserContext(host->GetBrowserContext()); + if (!bounds.Intersects(display.bounds()) || !controller || + controller->GetPermissionStatusForFrame(PermissionType::WINDOW_PLACEMENT, + host, + host->GetLastCommittedURL()) != + blink::mojom::PermissionStatus::GRANTED) { + display = screen->GetDisplayNearestView(host->GetNativeView()); + } + + bounds.AdjustToFit(display.work_area()); + return bounds; +} + } // namespace CreatedWindow::CreatedWindow() = default; @@ -2252,9 +2283,6 @@ base::FeatureList::IsEnabled(features::kDirectManipulationStylus); #endif // defined(OS_WIN) - prefs.touch_adjustment_enabled = - !command_line.HasSwitch(switches::kDisableTouchAdjustment); - prefs.enable_scroll_animator = command_line.HasSwitch(switches::kEnableSmoothScrolling) || (!command_line.HasSwitch(switches::kDisableSmoothScrolling) && @@ -3512,7 +3540,7 @@ widget_view; } -void WebContentsImpl::ShowCreatedWindow(int process_id, +void WebContentsImpl::ShowCreatedWindow(RenderFrameHost* opener, int main_frame_widget_route_id, WindowOpenDisposition disposition, const gfx::Rect& initial_rect, @@ -3525,8 +3553,8 @@ // TODO(danakj): Why do we defer this show step until the renderer asks for it // when it will always do so. What needs to happen in the renderer before we // reach here? - base::Optional<CreatedWindow> owned_created = - GetCreatedWindow(process_id, main_frame_widget_route_id); + base::Optional<CreatedWindow> owned_created = GetCreatedWindow( + opener->GetProcess()->GetID(), main_frame_widget_route_id); // The browser may have rejected the request to make a new window, or the // renderer could be sending an invalid route id. Ignore the request then. @@ -3547,11 +3575,20 @@ if (delegate->ShouldResumeRequestsForCreatedWindow()) created->ResumeLoadingCreatedWebContents(); + // Individual members of |initial_rect| may be 0 to indicate that the + // window.open() feature string did not specify a value. This code does not + // have the ability to distinguish between an unspecified value and 0. + // Assume that if any single value is non-zero, all values should be used. + // TODO(crbug.com/897300): Plumb values as specified; set defaults here? + gfx::Rect adjusted_rect = initial_rect; + if (adjusted_rect != gfx::Rect()) + adjusted_rect = AdjustRequestedWindowBounds(adjusted_rect, opener); + base::WeakPtr<WebContentsImpl> weak_created = created->weak_factory_.GetWeakPtr(); delegate->AddNewContents(this, std::move(owned_created->contents), std::move(owned_created->target_url), disposition, - initial_rect, user_gesture, nullptr); + adjusted_rect, user_gesture, nullptr); // The delegate may delete |created| during AddNewContents(). if (!weak_created) return; @@ -6462,8 +6499,19 @@ } void WebContentsImpl::RequestSetBounds(const gfx::Rect& new_bounds) { - if (delegate_) - delegate_->SetContentsBounds(this, new_bounds); + if (!delegate_) + return; + + // Members of |new_bounds| may be 0 to indicate uninitialized values for newly + // opened windows, even if the |GetContainerBounds()| inner rect is correct. + // TODO(crbug.com/897300): Plumb values as specified; fallback on outer rect. + auto bounds = new_bounds; + if (bounds.IsEmpty()) + bounds.set_size(GetContainerBounds().size()); + + // Only requests from the main frame, not subframes, should reach this code. + bounds = AdjustRequestedWindowBounds(bounds, GetMainFrame()); + delegate_->SetContentsBounds(this, bounds); } void WebContentsImpl::DidStartLoading(FrameTreeNode* frame_tree_node,
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index f219f9a..0de7c43 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -645,7 +645,7 @@ bool is_new_browsing_instance, bool has_user_gesture, SessionStorageNamespace* session_storage_namespace) override; - void ShowCreatedWindow(int process_id, + void ShowCreatedWindow(RenderFrameHost* opener, int main_frame_widget_route_id, WindowOpenDisposition disposition, const gfx::Rect& initial_rect,
diff --git a/content/browser/webui/web_ui_mojo_browsertest.cc b/content/browser/webui/web_ui_mojo_browsertest.cc index 7f40a5f2..43056e7 100644 --- a/content/browser/webui/web_ui_mojo_browsertest.cc +++ b/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -121,6 +121,7 @@ data_source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::ScriptSrc, "script-src chrome://resources 'self' 'unsafe-eval';"); + data_source->DisableTrustedTypesCSP(); data_source->SetRequestFilter( base::BindRepeating([](const std::string& path) { return true; }), base::BindRepeating(&GetResource));
diff --git a/content/browser/webui/web_ui_security_browsertest.cc b/content/browser/webui/web_ui_security_browsertest.cc index e3da149..f8f700af 100644 --- a/content/browser/webui/web_ui_security_browsertest.cc +++ b/content/browser/webui/web_ui_security_browsertest.cc
@@ -508,6 +508,7 @@ // Add a DataSource whose CSP allows chrome-untrusted://resources scripts. TestUntrustedDataSourceCSP csp; csp.script_src = "script-src chrome-untrusted://resources;"; + csp.no_trusted_types = true; AddUntrustedDataSource(shell()->web_contents()->GetBrowserContext(), "test-host", csp); GURL main_frame_url(GetChromeUntrustedUIURL("test-host/title1.html"));
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index a6061da..93ced4d 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -615,7 +615,8 @@ // TODO(crbug.com/1016541): After M82, remove when the corresponding // enterprise policy has been deleted. WebRuntimeFeatures::EnableReducedReferrerGranularity( - base::FeatureList::IsEnabled(features::kReducedReferrerGranularity) && + base::FeatureList::IsEnabled( + blink::features::kReducedReferrerGranularity) && !content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()); if (base::FeatureList::IsEnabled(
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 13d4d9fc..d3bd1ddc 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -185,6 +185,7 @@ "state_transitions.h", "thread_pool_util.cc", "thread_pool_util.h", + "trace_utils.h", "unfreezable_frame_messages.h", "unique_name_helper.cc", "unique_name_helper.h",
diff --git a/content/common/fetch/fetch_request_type_converters.cc b/content/common/fetch/fetch_request_type_converters.cc index edb4772..0bc3104 100644 --- a/content/common/fetch/fetch_request_type_converters.cc +++ b/content/common/fetch/fetch_request_type_converters.cc
@@ -5,7 +5,7 @@ #include "content/common/fetch/fetch_request_type_converters.h" #include "content/common/service_worker/service_worker_utils.h" -#include "third_party/blink/public/common/loader/network_utils.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "ui/base/page_transition_types.h" namespace mojo { @@ -28,7 +28,8 @@ if (input.request_body) output->body = input.request_body; output->referrer = blink::mojom::Referrer::New( - input.referrer, blink::NetToMojoReferrerPolicy(input.referrer_policy)); + input.referrer, + blink::ReferrerUtils::NetToMojoReferrerPolicy(input.referrer_policy)); output->mode = input.mode; output->is_main_resource_load = content::ServiceWorkerUtils::IsMainRequestDestination(input.destination);
diff --git a/content/common/trace_utils.h b/content/common/trace_utils.h new file mode 100644 index 0000000..4989685 --- /dev/null +++ b/content/common/trace_utils.h
@@ -0,0 +1,70 @@ +// 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_COMMON_TRACE_UTILS_H_ +#define CONTENT_COMMON_TRACE_UTILS_H_ + +#include <string> + +#include "base/trace_event/traced_value.h" + +namespace content { + +struct TracingCategory { + static constexpr const char kNavigation[] = "navigation"; +}; + +// Class which facilitates annotating with traces all possible return paths +// from a function or a method. Setting the return reason is enforced by a +// CHECK at runtime to ensure that no return branches have been missed. +// Template usage is necessary since the tracing code requires the category to +// be constant at compile time. +// +// Example usage: +// +// void SomeMethod() { +// TraceReturnReason<TracingCategory::kNavigation> trace_return("Method"); +// +// if (condition) { +// trace_return.set_return_reason("foo"); +// trace_return.traced_value()->SetBoolean("condition", true); +// return; +// } +// +// trace_return.set_return_reason("default return"); +// return; +// } +// +template <const char* category> +class TraceReturnReason { + public: + explicit TraceReturnReason(const char* const name) + : name_(name), + traced_value_(std::make_unique<base::trace_event::TracedValue>()) { + TRACE_EVENT_BEGIN0(category, name_); + } + + ~TraceReturnReason() { + CHECK(reason_set_); + TRACE_EVENT_END1(category, name_, "return", std::move(traced_value_)); + } + + void set_return_reason(const std::string& reason) { + reason_set_ = true; + traced_value_->SetString("reason", reason); + } + + // This method exposes the internal TracedValue member so usage of this + // class allows easy addition of more data to the end of the event. + base::trace_event::TracedValue* traced_value() { return traced_value_.get(); } + + private: + const char* const name_; + bool reason_set_ = false; + std::unique_ptr<base::trace_event::TracedValue> traced_value_; +}; + +} // namespace content + +#endif // CONTENT_COMMON_TRACE_UTILS_H_
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 07b603d..a48e491 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -481,6 +481,7 @@ "javatests/src/org/chromium/content/browser/ContentViewLocationTest.java", "javatests/src/org/chromium/content/browser/ContentViewPointerTypeTest.java", "javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java", + "javatests/src/org/chromium/content/browser/CriteriaHelperTest.java", "javatests/src/org/chromium/content/browser/EncodeHtmlDataUriTest.java", "javatests/src/org/chromium/content/browser/GestureDetectorResetTest.java", "javatests/src/org/chromium/content/browser/GestureListenerManagerTest.java", @@ -542,7 +543,6 @@ sources = [ "junit/src/org/chromium/content/browser/BindingManagerTest.java", "junit/src/org/chromium/content/browser/ChildProcessRankingTest.java", - "junit/src/org/chromium/content/browser/CriteriaHelperTest.java", "junit/src/org/chromium/content/browser/ScreenOrientationProviderImplTest.java", "junit/src/org/chromium/content/browser/SpareChildConnectionTest.java", "junit/src/org/chromium/content/browser/UiThreadTaskTraitsImplTest.java",
diff --git a/content/public/android/junit/src/org/chromium/content/browser/CriteriaHelperTest.java b/content/public/android/javatests/src/org/chromium/content/browser/CriteriaHelperTest.java similarity index 67% rename from content/public/android/junit/src/org/chromium/content/browser/CriteriaHelperTest.java rename to content/public/android/javatests/src/org/chromium/content/browser/CriteriaHelperTest.java index 98fad5b..da73ecf2 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/CriteriaHelperTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/CriteriaHelperTest.java
@@ -5,11 +5,8 @@ package org.chromium.content.browser; import static org.hamcrest.CoreMatchers.containsString; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.chromium.base.task.TaskTraits.THREAD_POOL; import static org.chromium.content_public.browser.test.util.CriteriaHelper.DEFAULT_POLLING_INTERVAL; import androidx.test.filters.MediumTest; @@ -22,8 +19,9 @@ import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; -import org.chromium.base.task.PostTask; -import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.BaseJUnit4ClassRunner; +import org.chromium.base.test.UiThreadTest; +import org.chromium.base.test.util.Batch; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.CriteriaNotSatisfiedException; @@ -34,7 +32,8 @@ /** * Tests for {@link CriteriaHelper}. */ -@RunWith(BaseRobolectricTestRunner.class) +@RunWith(BaseJUnit4ClassRunner.class) +@Batch(Batch.UNIT_TESTS) public class CriteriaHelperTest { private static final String ERROR_MESSAGE = "my special error message"; @@ -44,29 +43,23 @@ @Test @MediumTest public void testUiThread() { - // Robolectric runs the test on UI thread. - assertTrue(ThreadUtils.runningOnUiThread()); - // In Instrumented tests, the tests would be on instrumentation thread instead. - // Emulate that behavior by posting the body of the test. - PostTask.postTask(THREAD_POOL, () -> { - assertFalse(ThreadUtils.runningOnUiThread()); - CriteriaHelper.pollUiThread( - () -> Criteria.checkThat(ThreadUtils.runningOnUiThread(), Matchers.is(true))); - }); + CriteriaHelper.pollUiThread( + () -> Criteria.checkThat(ThreadUtils.runningOnUiThread(), Matchers.is(true))); + } + + @Test + @MediumTest + @UiThreadTest + public void testUiThreadNested() { + CriteriaHelper.pollUiThreadNested( + () -> Criteria.checkThat(ThreadUtils.runningOnUiThread(), Matchers.is(true))); } @Test @MediumTest public void testInstrumentationThread() { - // Robolectric runs the test on UI thread. - assertTrue(ThreadUtils.runningOnUiThread()); - // In Instrumented tests, the tests would be on instrumentation thread instead. - // Emulate that behavior by posting the body of the test. - PostTask.postTask(THREAD_POOL, () -> { - assertFalse(ThreadUtils.runningOnUiThread()); - CriteriaHelper.pollInstrumentationThread( - () -> Criteria.checkThat(ThreadUtils.runningOnUiThread(), Matchers.is(false))); - }); + CriteriaHelper.pollInstrumentationThread( + () -> Criteria.checkThat(ThreadUtils.runningOnUiThread(), Matchers.is(false))); } @Test @@ -77,6 +70,13 @@ @Test @MediumTest + @UiThreadTest + public void testPass_Runnable_UiThreadNested() { + CriteriaHelper.pollUiThreadNested(() -> {}); + } + + @Test + @MediumTest public void testPass_Runnable_InstrumentationThread() { CriteriaHelper.pollInstrumentationThread(() -> {}); } @@ -89,6 +89,13 @@ @Test @MediumTest + @UiThreadTest + public void testPass_Callable_UiThreadNested() { + CriteriaHelper.pollUiThreadNested(() -> true); + } + + @Test + @MediumTest public void testPass_Callable_InstrumentationThread() { CriteriaHelper.pollInstrumentationThread(() -> true); } @@ -104,6 +111,16 @@ @Test @MediumTest + @UiThreadTest + public void testThrow_Runnable_UiThreadNested() { + thrown.expect(AssertionError.class); + CriteriaHelper.pollUiThreadNested(() -> { + throw new CriteriaNotSatisfiedException(""); + }, 0, DEFAULT_POLLING_INTERVAL); + } + + @Test + @MediumTest public void testThrow_Runnable_InstrumentationThread() { thrown.expect(AssertionError.class); CriteriaHelper.pollInstrumentationThread(() -> { @@ -120,6 +137,14 @@ @Test @MediumTest + @UiThreadTest + public void testThrow_Callable_UiThreadNested() { + thrown.expect(AssertionError.class); + CriteriaHelper.pollUiThreadNested(() -> false, 0, DEFAULT_POLLING_INTERVAL); + } + + @Test + @MediumTest public void testThrow_Callable_InstrumentationThread() { thrown.expect(AssertionError.class); CriteriaHelper.pollInstrumentationThread(() -> false, 0, DEFAULT_POLLING_INTERVAL); @@ -136,6 +161,16 @@ @Test @MediumTest + @UiThreadTest + public void testMessage_Runnable_UiThreadNested() { + thrown.expectMessage(ERROR_MESSAGE); + CriteriaHelper.pollUiThreadNested(() -> { + throw new CriteriaNotSatisfiedException(ERROR_MESSAGE); + }, 0, DEFAULT_POLLING_INTERVAL); + } + + @Test + @MediumTest public void testMessage_Runnable_InstrumentationThread() { thrown.expectMessage(ERROR_MESSAGE); CriteriaHelper.pollInstrumentationThread(() -> { @@ -181,6 +216,22 @@ @Test @MediumTest + @UiThreadTest + public void testStack_Runnable_UiThreadNested() { + try { + CriteriaHelper.pollUiThreadNested(() -> { + throw new CriteriaNotSatisfiedException("test"); + }, 0, DEFAULT_POLLING_INTERVAL); + } catch (AssertionError e) { + assertThat(getStackTrace(e), + containsString("CriteriaHelperTest.testStack_Runnable_UiThreadNested(")); + return; + } + Assert.fail(); + } + + @Test + @MediumTest public void testStack_Runnable_InstrumentationThread() { try { CriteriaHelper.pollInstrumentationThread(() -> { @@ -209,6 +260,20 @@ @Test @MediumTest + @UiThreadTest + public void testStack_Callable_UiThreadNested() { + try { + CriteriaHelper.pollUiThreadNested(() -> false, 0, DEFAULT_POLLING_INTERVAL); + } catch (AssertionError e) { + assertThat(getStackTrace(e), + containsString("CriteriaHelperTest.testStack_Callable_UiThreadNested(")); + return; + } + Assert.fail(); + } + + @Test + @MediumTest public void testStack_Callable_InstrumentationThread() { try { CriteriaHelper.pollInstrumentationThread(() -> false, 0, DEFAULT_POLLING_INTERVAL);
diff --git a/content/public/browser/native_file_system_permission_context.h b/content/public/browser/native_file_system_permission_context.h index 6c81fe2..af40f0e 100644 --- a/content/public/browser/native_file_system_permission_context.h +++ b/content/public/browser/native_file_system_permission_context.h
@@ -59,15 +59,6 @@ HandleType handle_type, UserAction user_action) = 0; - // Displays a dialog to confirm that the user intended to give read access to - // a specific directory. - using PermissionStatus = blink::mojom::PermissionStatus; - virtual void ConfirmDirectoryReadAccess( - const url::Origin& origin, - const base::FilePath& path, - GlobalFrameRoutingId frame_id, - base::OnceCallback<void(PermissionStatus)> callback) = 0; - // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum class SensitiveDirectoryResult {
diff --git a/content/public/browser/native_file_system_permission_grant.h b/content/public/browser/native_file_system_permission_grant.h index 70c54f2..a6f7ea2 100644 --- a/content/public/browser/native_file_system_permission_grant.h +++ b/content/public/browser/native_file_system_permission_grant.h
@@ -49,11 +49,16 @@ kMaxValue = kGrantedByContentSetting }; + // Passed to |RequestPermission| to indicate if for this particular permission + // request user activation is required or not. + enum class UserActivationState { kRequired, kNotRequired }; + // Call this method to request permission for this grant. The |callback| // should be called after the status of this grant has been updated with // the outcome of the request. virtual void RequestPermission( GlobalFrameRoutingId frame_id, + UserActivationState user_activation_state, base::OnceCallback<void(PermissionRequestOutcome)> callback) = 0; // This observer can be used to be notified of changes to the permission
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h index 5b4ecff..8f613aa 100644 --- a/content/public/browser/render_process_host.h +++ b/content/public/browser/render_process_host.h
@@ -213,6 +213,9 @@ // RenderProcessExited may never be called. virtual bool Shutdown(int exit_code) = 0; + // Returns true if shutdown was started by calling |Shutdown()|. + virtual bool ShutdownRequested() = 0; + // Try to shut down the associated renderer process as fast as possible. // If a non-zero |page_count| value is provided, then a fast shutdown will // only happen if the count matches the active view count. If
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index 1c6f22d..2eaca2b 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -156,7 +156,6 @@ IPC_STRUCT_TRAITS_MEMBER(password_echo_enabled) IPC_STRUCT_TRAITS_MEMBER(should_clear_document_background) IPC_STRUCT_TRAITS_MEMBER(touch_event_feature_detection_enabled) - IPC_STRUCT_TRAITS_MEMBER(touch_adjustment_enabled) IPC_STRUCT_TRAITS_MEMBER(pointer_events_max_touch_points) IPC_STRUCT_TRAITS_MEMBER(available_pointer_types) IPC_STRUCT_TRAITS_MEMBER(primary_pointer_type)
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 4b40291..a27721ce5 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -498,11 +498,6 @@ const base::Feature kPushSubscriptionChangeEvent{ "PushSubscriptionChangeEvent", base::FEATURE_DISABLED_BY_DEFAULT}; -// Reduce the amount of information in the default 'referer' header for -// cross-origin requests. -const base::Feature kReducedReferrerGranularity{ - "ReducedReferrerGranularity", base::FEATURE_DISABLED_BY_DEFAULT}; - // Controls whether FileURLLoaderFactory can fetch additional files based on the // isolated world's origin. This feature is disabled by default because we want // content scripts to have the same permissions as the page they are injected
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index a2adf90..5c9e551 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -110,7 +110,6 @@ CONTENT_EXPORT extern const base::Feature kProcessSharingWithStrictSiteInstances; CONTENT_EXPORT extern const base::Feature kPushSubscriptionChangeEvent; -CONTENT_EXPORT extern const base::Feature kReducedReferrerGranularity; CONTENT_EXPORT extern const base::Feature kRelaxIsolatedWorldCorsInFileUrlLoaderFactory; CONTENT_EXPORT extern const base::Feature kReloadHiddenTabsWithCrashedSubframes;
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 2ab2a020..680de1f 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -84,10 +84,6 @@ // Enable in-progress canvas 2d API features. const char kEnableNewCanvas2DAPI[] = "new-canvas-2d-api"; -// Disables hardware acceleration of video decode, where available. -const char kDisableAcceleratedVideoDecode[] = - "disable-accelerated-video-decode"; - // Disables hardware acceleration of video encode, where available. const char kDisableAcceleratedVideoEncode[] = "disable-accelerated-video-encode"; @@ -478,13 +474,6 @@ // would have been used. Enables the chromium_raster_transport extension. const char kEnableOopRasterization[] = "enable-oop-rasterization"; -// Pins the default referrer policy to the pre-M80 value of -// no-referrer-when-downgrade. -// TODO(crbug.com/1016541): After M82, remove when the corresponding -// enterprise policy has been deleted. -const char kForceLegacyDefaultReferrerPolicy[] = - "force-legacy-default-referrer-policy"; - // Forces use of hardware overlay for fullscreen video playback. Useful for // testing the Android overlay fullscreen functionality on other platforms. const char kForceOverlayFullscreenVideo[] = "force-overlay-fullscreen-video"; @@ -911,6 +900,9 @@ // without restarting the browser and relaunching without this flag. const char kWebRtcLocalEventLogging[] = "webrtc-event-logging"; +// This switch disables the ScrollToTextFragment feature. +const char kDisableScrollToTextFragment[] = "disable-scroll-to-text-fragment"; + // Forcibly enable and select the specified runtime for webxr. // Note that this provides an alternative means of enabling a runtime, and will // also functionally disable all other runtimes. @@ -927,8 +919,14 @@ const char kWebXrRuntimeOpenXr[] = "openxr"; const char kWebXrRuntimeWMR[] = "windows-mixed-reality"; -// This switch disables the ScrollToTextFragment feature. -const char kDisableScrollToTextFragment[] = "disable-scroll-to-text-fragment"; +// Disables hardware acceleration of video decode, where available. +const char kDisableAcceleratedVideoDecode[] = + "disable-accelerated-video-decode"; + +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_ANDROID) +// Enables hardware acceleration of video decoding on linux. (defaults to off) +const char kEnableAcceleratedVideoDecode[] = "enable-accelerated-video-decode"; +#endif #if defined(OS_ANDROID) // Disable Media Session API
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 12f04f66..1411ca02 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -34,7 +34,6 @@ CONTENT_EXPORT extern const char kDisable3DAPIs[]; CONTENT_EXPORT extern const char kDisableAccelerated2dCanvas[]; CONTENT_EXPORT extern const char kDisableYUVImageDecoding[]; -CONTENT_EXPORT extern const char kDisableAcceleratedVideoDecode[]; CONTENT_EXPORT extern const char kDisableAcceleratedVideoEncode[]; extern const char kDisableBackingStoreLimit[]; CONTENT_EXPORT extern const char @@ -143,7 +142,6 @@ CONTENT_EXPORT extern const char kForceDisplayList2dCanvas[]; CONTENT_EXPORT extern const char kDisableOopRasterization[]; CONTENT_EXPORT extern const char kEnableOopRasterization[]; -CONTENT_EXPORT extern const char kForceLegacyDefaultReferrerPolicy[]; CONTENT_EXPORT extern const char kForceOverlayFullscreenVideo[]; CONTENT_EXPORT extern const char kForcePresentationReceiverForTesting[]; CONTENT_EXPORT extern const char kForceRendererAccessibility[]; @@ -255,6 +253,11 @@ CONTENT_EXPORT extern const char kWebXrRuntimeOpenXr[]; CONTENT_EXPORT extern const char kWebXrRuntimeWMR[]; +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(OS_ANDROID) +CONTENT_EXPORT extern const char kEnableAcceleratedVideoDecode[]; +#endif +CONTENT_EXPORT extern const char kDisableAcceleratedVideoDecode[]; + #if defined(OS_ANDROID) CONTENT_EXPORT extern const char kDisableMediaSessionAPI[]; CONTENT_EXPORT extern const char kDisableOoprDebugCrashDump[];
diff --git a/content/public/common/referrer.cc b/content/public/common/referrer.cc index 264634a..22e7ffb 100644 --- a/content/public/common/referrer.cc +++ b/content/public/common/referrer.cc
@@ -18,32 +18,11 @@ #include "services/network/public/cpp/resource_request.h" #include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "third_party/blink/public/common/loader/network_utils.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/mojom/loader/referrer.mojom.h" namespace content { -namespace { - -// Using an atomic is necessary because this code is called from both the -// browser and the renderer (so that access is not on a single sequence when in -// single-process mode), and because it is called from multiple threads within -// the renderer. -bool ReadModifyWriteForceLegacyPolicyFlag( - base::Optional<bool> maybe_new_value) { - // Default to false in the browser process (it is not expected - // that the browser will be provided this switch). - // The value is propagated to other processes through the command line. - DCHECK(base::CommandLine::InitializedForCurrentProcess()); - static std::atomic<bool> value( - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kForceLegacyDefaultReferrerPolicy)); - if (!maybe_new_value.has_value()) - return value; - return value.exchange(*maybe_new_value); -} - -} // namespace - Referrer::Referrer(const blink::mojom::Referrer& referrer) : url(referrer.url), policy(referrer.policy) {} @@ -61,8 +40,8 @@ const blink::mojom::Referrer& referrer) { network::mojom::ReferrerPolicy effective_policy = referrer.policy; if (effective_policy == network::mojom::ReferrerPolicy::kDefault) { - effective_policy = - blink::NetToMojoReferrerPolicy(GetDefaultReferrerPolicy()); + effective_policy = blink::ReferrerUtils::NetToMojoReferrerPolicy( + blink::ReferrerUtils::GetDefaultNetReferrerPolicy()); } DCHECK_NE(effective_policy, network::mojom::ReferrerPolicy::kDefault); @@ -87,37 +66,20 @@ net::ReferrerPolicy Referrer::ReferrerPolicyForUrlRequest( network::mojom::ReferrerPolicy referrer_policy) { if (referrer_policy == network::mojom::ReferrerPolicy::kDefault) { - return GetDefaultReferrerPolicy(); + return blink::ReferrerUtils::GetDefaultNetReferrerPolicy(); } return network::ReferrerPolicyForUrlRequest(referrer_policy); } // static -net::ReferrerPolicy Referrer::GetDefaultReferrerPolicy() { - // The ReducedReferrerGranularity feature sets the default referrer - // policy to strict-origin-when-cross-origin unless forbidden - // by the "force legacy policy" global. - // TODO(M82, crbug.com/1016541) Once the pertinent enterprise policy has - // been removed, update this to remove the global. - - // Short-circuit to avoid acquiring the lock unless necessary. - if (!base::FeatureList::IsEnabled(features::kReducedReferrerGranularity)) - return net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE; - - return ShouldForceLegacyDefaultReferrerPolicy() - ? net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE - : net::ReferrerPolicy:: - REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN; -} - -// static void Referrer::SetForceLegacyDefaultReferrerPolicy(bool force) { - ReadModifyWriteForceLegacyPolicyFlag(force); + blink::ReferrerUtils::ReadModifyWriteForceLegacyPolicyFlag(force); } // static bool Referrer::ShouldForceLegacyDefaultReferrerPolicy() { - return ReadModifyWriteForceLegacyPolicyFlag(base::nullopt); + return blink::ReferrerUtils::ReadModifyWriteForceLegacyPolicyFlag( + base::nullopt); } // static
diff --git a/content/public/common/referrer.h b/content/public/common/referrer.h index 989b372..512fbfc 100644 --- a/content/public/common/referrer.h +++ b/content/public/common/referrer.h
@@ -50,8 +50,6 @@ static net::ReferrerPolicy ReferrerPolicyForUrlRequest( network::mojom::ReferrerPolicy referrer_policy); - static net::ReferrerPolicy GetDefaultReferrerPolicy(); - // Configures retaining the pre-M80 default referrer // policy of no-referrer-when-downgrade. // TODO(crbug.com/1016541): After M82, remove when the corresponding
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc index ee25c1b..839e3cbd 100644 --- a/content/public/common/web_preferences.cc +++ b/content/public/common/web_preferences.cc
@@ -133,7 +133,6 @@ enable_scroll_animator(false), prefers_reduced_motion(false), touch_event_feature_detection_enabled(false), - touch_adjustment_enabled(true), pointer_events_max_touch_points(0), available_pointer_types(0), primary_pointer_type(ui::POINTER_TYPE_NONE),
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h index 5880505e..700b47b 100644 --- a/content/public/common/web_preferences.h +++ b/content/public/common/web_preferences.h
@@ -152,7 +152,6 @@ bool enable_scroll_animator; bool prefers_reduced_motion; bool touch_event_feature_detection_enabled; - bool touch_adjustment_enabled; int pointer_events_max_touch_points; int available_pointer_types; ui::PointerType primary_pointer_type;
diff --git a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/CriteriaHelper.java b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/CriteriaHelper.java index 8cf7c01..37cbf941 100644 --- a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/CriteriaHelper.java +++ b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/CriteriaHelper.java
@@ -4,12 +4,18 @@ package org.chromium.content_public.browser.test.util; +import android.os.Handler; +import android.os.Looper; + import org.hamcrest.Matchers; import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.TimeoutTimer; +import org.chromium.content_public.browser.test.NestedSystemMessageHandler; +import java.lang.reflect.InvocationTargetException; import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; /** @@ -73,6 +79,12 @@ */ public static void pollInstrumentationThread( Runnable criteria, long maxTimeoutMs, long checkIntervalMs) { + assert !ThreadUtils.runningOnUiThread(); + pollThreadInternal(criteria, maxTimeoutMs, checkIntervalMs, false); + } + + private static void pollThreadInternal( + Runnable criteria, long maxTimeoutMs, long checkIntervalMs, boolean isUiThread) { CriteriaNotSatisfiedException throwable; try { criteria.run(); @@ -82,11 +94,10 @@ } TimeoutTimer timer = new TimeoutTimer(maxTimeoutMs); while (!timer.isTimedOut()) { - try { - Thread.sleep(checkIntervalMs); - } catch (InterruptedException e) { - // Catch the InterruptedException. If the exception occurs before maxTimeoutMs - // and the criteria is not satisfied, the while loop will run again. + if (isUiThread) { + loopUiThread(checkIntervalMs); + } else { + sleepInstrumentationThread(checkIntervalMs); } try { criteria.run(); @@ -98,6 +109,34 @@ throw new AssertionError(throwable); } + private static void sleepInstrumentationThread(long checkIntervalMs) { + assert !ThreadUtils.runningOnUiThread(); + try { + Thread.sleep(checkIntervalMs); + } catch (InterruptedException e) { + // Catch the InterruptedException. If the exception occurs before maxTimeoutMs + // and the criteria is not satisfied, the while loop will run again. + } + } + + private static void loopUiThread(long checkIntervalMs) { + assert ThreadUtils.runningOnUiThread(); + AtomicBoolean called = new AtomicBoolean(false); + + // Ensure we pump the message handler in case no new tasks arrive. + new Handler(Looper.myLooper()).postDelayed(() -> { called.set(true); }, checkIntervalMs); + + TimeoutTimer timer = new TimeoutTimer(checkIntervalMs); + while (!timer.isTimedOut() && !called.get()) { + try { + NestedSystemMessageHandler.runSingleNestedLooperTask(Looper.myQueue()); + } catch (IllegalArgumentException | IllegalAccessException | SecurityException + | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } + /** * Checks whether the given Runnable completes without exception at the default interval. * @@ -193,6 +232,7 @@ */ public static void pollUiThread( final Runnable criteria, long maxTimeoutMs, long checkIntervalMs) { + assert !ThreadUtils.runningOnUiThread(); pollInstrumentationThread(() -> { AtomicReference<Throwable> throwableRef = new AtomicReference<>(); ThreadUtils.runOnUiThreadBlocking(() -> { @@ -283,6 +323,63 @@ pollUiThread(criteria, null); } + /** + * Checks whether the given Runnable completes without exception at a given interval on the UI + * thread, until either the Runnable successfully completes, or the maxTimeoutMs number of ms + * has elapsed. + * This call will nest the Looper in order to wait for the Runnable to complete. + * + * @param criteria The Runnable that will be attempted. + * @param maxTimeoutMs The maximum number of ms that this check will be performed for + * before timeout. + * @param checkIntervalMs The number of ms between checks. + * + * @see #pollInstrumentationThread(Runnable) + */ + public static void pollUiThreadNested( + Runnable criteria, long maxTimeoutMs, long checkIntervalMs) { + pollThreadInternal(criteria, maxTimeoutMs, checkIntervalMs, true); + } + + /** + * Checks whether the given Runnable is satisfied polling at a given interval on the UI + * thread, until either the criteria is satisfied, or the maxTimeoutMs number of ms has elapsed. + * This call will nest the Looper in order to wait for the Criteria to be satisfied. + * + * @param criteria The Callable<Boolean> that will be checked. + * @param maxTimeoutMs The maximum number of ms that this check will be performed for + * before timeout. + * @param checkIntervalMs The number of ms between checks. + * + * @see #pollInstrumentationThread(Criteria) + */ + public static void pollUiThreadNested( + final Callable<Boolean> criteria, long maxTimeoutMs, long checkIntervalMs) { + pollUiThreadNested(toNotSatisfiedRunnable(criteria, null), maxTimeoutMs, checkIntervalMs); + } + + /** + * Checks whether the given Runnable completes without exception at the default interval on + * the UI thread. This call will nest the Looper in order to wait for the Runnable to complete. + * @param criteria The Runnable that will be attempted. + * + * @see #pollInstrumentationThread(Runnable) + */ + public static void pollUiThreadNested(final Runnable criteria) { + pollUiThreadNested(criteria, DEFAULT_MAX_TIME_TO_POLL, DEFAULT_POLLING_INTERVAL); + } + + /** + * Checks whether the given Callable<Boolean> is satisfied polling at a default interval on the + * UI thread. This call will nest the Looper in order to wait for the Criteria to be satisfied. + * @param criteria The Callable<Boolean> that will be checked. + * + * @see #pollInstrumentationThread(Criteria) + */ + public static void pollUiThreadNested(final Callable<Boolean> criteria) { + pollUiThreadNested(toNotSatisfiedRunnable(criteria, null)); + } + private static Runnable toNotSatisfiedRunnable( Callable<Boolean> criteria, String failureReason) { return () -> {
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index e31ab1c7..ac9260776 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -1917,6 +1917,12 @@ return "pageLoadComplete" == result; } +void RemoveWebContentsReceiverSet(WebContents* web_contents, + const std::string& interface_name) { + static_cast<content::WebContentsImpl*>(web_contents) + ->RemoveReceiverSetForTesting(interface_name); +} + void EnableAccessibilityForWebContents(WebContents* web_contents) { WebContentsImpl* web_contents_impl = static_cast<WebContentsImpl*>(web_contents);
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 65b9d15..a4164d5 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -885,6 +885,11 @@ // message is handled properly. bool WaitForRenderFrameReady(RenderFrameHost* rfh) WARN_UNUSED_RESULT; +// Removes the interface from the associated interface receiver sets attached to +// the WebContents. +void RemoveWebContentsReceiverSet(WebContents* web_contents, + const std::string& interface_name); + // Enable accessibility support for all of the frames in this WebContents void EnableAccessibilityForWebContents(WebContents* web_contents);
diff --git a/content/public/test/fake_remote_frame.cc b/content/public/test/fake_remote_frame.cc index 5578783..d4d61765 100644 --- a/content/public/test/fake_remote_frame.cc +++ b/content/public/test/fake_remote_frame.cc
@@ -19,7 +19,7 @@ base::Unretained(this))); } -void FakeRemoteFrame::WillEnterFullscreen() {} +void FakeRemoteFrame::WillEnterFullscreen(blink::mojom::FullscreenOptionsPtr) {} void FakeRemoteFrame::AddReplicatedContentSecurityPolicies( std::vector<network::mojom::ContentSecurityPolicyHeaderPtr> headers) {}
diff --git a/content/public/test/fake_remote_frame.h b/content/public/test/fake_remote_frame.h index c73ca8f..d886ef9a 100644 --- a/content/public/test/fake_remote_frame.h +++ b/content/public/test/fake_remote_frame.h
@@ -10,6 +10,7 @@ #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/mojom/frame/frame.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/intrinsic_sizing_info.mojom.h" #include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" #include "third_party/blink/public/mojom/scroll/scroll_into_view_params.mojom.h" @@ -38,7 +39,7 @@ void Init(blink::AssociatedInterfaceProvider* provider); // blink::mojom::RemoteFrame overrides: - void WillEnterFullscreen() override; + void WillEnterFullscreen(blink::mojom::FullscreenOptionsPtr) override; void AddReplicatedContentSecurityPolicies( std::vector<network::mojom::ContentSecurityPolicyHeaderPtr> headers) override;
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index 2c4a1cb..cd2c44d7d 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -60,6 +60,7 @@ has_connection_(false), browser_context_(browser_context), prev_routing_id_(0), + shutdown_requested_(false), fast_shutdown_started_(false), deletion_callback_called_(false), is_for_guests_only_(false), @@ -202,9 +203,14 @@ } bool MockRenderProcessHost::Shutdown(int exit_code) { + shutdown_requested_ = true; return true; } +bool MockRenderProcessHost::ShutdownRequested() { + return shutdown_requested_; +} + bool MockRenderProcessHost::FastShutdownIfPossible(size_t page_count, bool skip_unload_handlers) { if (GetActiveViewCount() != page_count)
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index 12410c2..2cfa389 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -101,6 +101,7 @@ StoragePartition* GetStoragePartition() override; virtual void AddWord(const base::string16& word); bool Shutdown(int exit_code) override; + bool ShutdownRequested() override; bool FastShutdownIfPossible(size_t page_count, bool skip_unload_handlers) override; bool FastShutdownStarted() override; @@ -269,6 +270,7 @@ base::flat_set<PriorityClient*> priority_clients_; int prev_routing_id_; base::IDMap<IPC::Listener*> listeners_; + bool shutdown_requested_; bool fast_shutdown_started_; bool deletion_callback_called_; bool is_for_guests_only_;
diff --git a/content/public/test/referrer_unittest.cc b/content/public/test/referrer_unittest.cc index fe243d2..1ae04b42 100644 --- a/content/public/test/referrer_unittest.cc +++ b/content/public/test/referrer_unittest.cc
@@ -6,10 +6,10 @@ #include "base/test/gtest_util.h" #include "base/test/scoped_feature_list.h" -#include "content/public/common/content_features.h" #include "net/url_request/referrer_policy.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/common/loader/network_utils.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" namespace content { @@ -105,23 +105,11 @@ for (auto policy : policies) { EXPECT_EQ(Referrer::ReferrerPolicyForUrlRequest( - blink::NetToMojoReferrerPolicy(policy)), + blink::ReferrerUtils::NetToMojoReferrerPolicy(policy)), policy); } } -TEST(DefaultReferrerPolicyTest, Unconfigured) { - EXPECT_EQ(Referrer::GetDefaultReferrerPolicy(), - net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE); -} - -TEST(DefaultReferrerPolicyTest, FeatureOnly) { - base::test::ScopedFeatureList f; - f.InitAndEnableFeature(features::kReducedReferrerGranularity); - EXPECT_EQ(Referrer::GetDefaultReferrerPolicy(), - net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN); -} - TEST(DefaultReferrerPolicyTest, SetAndGetForceLegacy) { EXPECT_FALSE(content::Referrer::ShouldForceLegacyDefaultReferrerPolicy()); content::Referrer::SetForceLegacyDefaultReferrerPolicy(true); @@ -130,15 +118,15 @@ TEST(DefaultReferrerPolicyTest, ForceLegacyOnly) { content::Referrer::SetForceLegacyDefaultReferrerPolicy(true); - EXPECT_EQ(Referrer::GetDefaultReferrerPolicy(), + EXPECT_EQ(blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE); } TEST(DefaultReferrerPolicyTest, FeatureAndForceLegacy) { base::test::ScopedFeatureList f; - f.InitAndEnableFeature(features::kReducedReferrerGranularity); + f.InitAndEnableFeature(blink::features::kReducedReferrerGranularity); content::Referrer::SetForceLegacyDefaultReferrerPolicy(true); - EXPECT_EQ(Referrer::GetDefaultReferrerPolicy(), + EXPECT_EQ(blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE); }
diff --git a/content/public/test/web_ui_browsertest_util.cc b/content/public/test/web_ui_browsertest_util.cc index 56838cd..eff2b8de 100644 --- a/content/public/test/web_ui_browsertest_util.cc +++ b/content/public/test/web_ui_browsertest_util.cc
@@ -55,6 +55,7 @@ int bindings = BINDINGS_POLICY_WEB_UI; std::string child_src = "child-src 'self' chrome://web-ui-subframe/;"; bool disable_xfo = false; + bool disable_trusted_types = false; std::vector<std::string> requestable_schemes; base::Optional<std::vector<std::string>> frame_ancestors; }; @@ -86,6 +87,8 @@ } if (config.disable_xfo) data_source->DisableDenyXFrameOptions(); + if (config.disable_trusted_types) + data_source->DisableTrustedTypesCSP(); WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(), data_source); @@ -123,6 +126,8 @@ network::mojom::CSPDirectiveName::DefaultSrc, csp->default_src.value()); } + if (csp->no_trusted_types) + untrusted_data_source->DisableTrustedTypesCSP(); if (csp->no_xfo) untrusted_data_source->DisableDenyXFrameOptions(); if (csp->frame_ancestors.has_value()) { @@ -162,6 +167,10 @@ if (has_value && value == "true") config.disable_xfo = true; + has_value = net::GetValueForKeyInQuery(url, "notrustedtypes", &value); + if (has_value && value == "true") + config.disable_trusted_types = true; + has_value = net::GetValueForKeyInQuery(url, "childsrc", &value); if (has_value) config.child_src = value;
diff --git a/content/public/test/web_ui_browsertest_util.h b/content/public/test/web_ui_browsertest_util.h index 286d3af..4cd8aef 100644 --- a/content/public/test/web_ui_browsertest_util.h +++ b/content/public/test/web_ui_browsertest_util.h
@@ -22,6 +22,9 @@ base::Optional<std::string> child_src = base::nullopt; base::Optional<std::string> script_src = base::nullopt; base::Optional<std::string> default_src = base::nullopt; + // Trusted Types is enabled by default for TestUntrustedDataSource. + // Setting this to true will disable Trusted Types. + bool no_trusted_types = false; bool no_xfo = false; base::Optional<std::vector<std::string>> frame_ancestors = base::nullopt; };
diff --git a/content/renderer/drop_data_builder.cc b/content/renderer/drop_data_builder.cc index 28d9d77..8f41472 100644 --- a/content/renderer/drop_data_builder.cc +++ b/content/renderer/drop_data_builder.cc
@@ -24,7 +24,7 @@ // static DropData DropDataBuilder::Build(const WebDragData& drag_data) { DropData result; - result.referrer_policy = network::mojom::ReferrerPolicy::kDefault; + result.referrer_policy = drag_data.ReferrerPolicy(); for (const WebDragData::Item& item : drag_data.Items()) { switch (item.storage_type) {
diff --git a/content/renderer/loader/navigation_body_loader.cc b/content/renderer/loader/navigation_body_loader.cc index 230a8c0..f092eea 100644 --- a/content/renderer/loader/navigation_body_loader.cc +++ b/content/renderer/loader/navigation_body_loader.cc
@@ -10,7 +10,7 @@ #include "content/renderer/loader/web_url_loader_impl.h" #include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/mojom/url_response_head.mojom.h" -#include "third_party/blink/public/common/loader/network_utils.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/platform/web_code_cache_loader.h" #include "third_party/blink/public/web/web_navigation_params.h" @@ -68,7 +68,8 @@ redirect.new_referrer = blink::WebString::FromUTF8(redirect_info.new_referrer); redirect.new_referrer_policy = - blink::NetToMojoReferrerPolicy(redirect_info.new_referrer_policy); + blink::ReferrerUtils::NetToMojoReferrerPolicy( + redirect_info.new_referrer_policy); redirect.new_http_method = blink::WebString::FromLatin1(redirect_info.new_method); url = redirect_info.new_url;
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc index e0c5d36..bd673d0c 100644 --- a/content/renderer/loader/resource_dispatcher.cc +++ b/content/renderer/loader/resource_dispatcher.cc
@@ -45,6 +45,7 @@ #include "services/network/public/mojom/fetch_api.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/blink/public/common/client_hints/client_hints.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/common/loader/resource_type_util.h" #include "third_party/blink/public/common/loader/throttling_url_loader.h" #include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" @@ -63,7 +64,8 @@ } void CheckSchemeForReferrerPolicy(const network::ResourceRequest& request) { - if ((request.referrer_policy == Referrer::GetDefaultReferrerPolicy() || + if ((request.referrer_policy == + blink::ReferrerUtils::GetDefaultNetReferrerPolicy() || request.referrer_policy == net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE) && request.referrer.SchemeIsCryptographic() &&
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc index 44c74d5..8f0b418f 100644 --- a/content/renderer/loader/resource_dispatcher_unittest.cc +++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -38,6 +38,7 @@ #include "services/network/public/mojom/url_response_head.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "url/gurl.h" @@ -120,7 +121,8 @@ request->url = GURL(kTestPageUrl); request->site_for_cookies = net::SiteForCookies::FromUrl(GURL(kTestPageUrl)); - request->referrer_policy = Referrer::GetDefaultReferrerPolicy(); + request->referrer_policy = + blink::ReferrerUtils::GetDefaultNetReferrerPolicy(); request->resource_type = static_cast<int>(blink::mojom::ResourceType::kSubResource); request->priority = net::LOW;
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index c9c8f0c..de5614c5 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -65,8 +65,8 @@ #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/loader/mime_sniffing_throttle.h" -#include "third_party/blink/public/common/loader/network_utils.h" #include "third_party/blink/public/common/loader/previews_state.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/common/loader/resource_type_util.h" #include "third_party/blink/public/common/mime_util/mime_util.h" #include "third_party/blink/public/common/security/security_style.h" @@ -739,7 +739,8 @@ return client_->WillFollowRedirect( url_, redirect_info.new_site_for_cookies, WebString::FromUTF8(redirect_info.new_referrer), - blink::NetToMojoReferrerPolicy(redirect_info.new_referrer_policy), + blink::ReferrerUtils::NetToMojoReferrerPolicy( + redirect_info.new_referrer_policy), WebString::FromUTF8(redirect_info.new_method), response, report_raw_headers_, removed_headers); }
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index da72b11..62f6c5f 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -1089,7 +1089,7 @@ // // AVOID: prefer to use an origin/frame/worker-specific factory (e.g. via // content::RenderFrameImpl::FrameURLLoaderFactory::CreateURLLoader). See -// also https://crbug.com/1098938. +// also https://crbug.com/1114822. // // It is invalid to call this in an incomplete env where // RenderThreadImpl::current() returns nullptr (e.g. in some tests).
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 5f6bb67..0a1647b 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -1025,7 +1025,7 @@ // Returns a mostly empty bundle, with a fallback that uses a process-wide, // direct-network factory. // - // TODO(lukasza): https://crbug.com/1098938: Remove once the fallback is no + // TODO(lukasza): https://crbug.com/1114822: Remove once the fallback is no // longer needed. scoped_refptr<ChildURLLoaderFactoryBundle> GetLoaderFactoryBundleFallback();
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index c0f9e9b6..49619a9b 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -662,7 +662,6 @@ settings->SetAvailableHoverTypes(prefs.available_hover_types); settings->SetPrimaryHoverType( static_cast<blink::HoverType>(prefs.primary_hover_type)); - settings->SetEnableTouchAdjustment(prefs.touch_adjustment_enabled); settings->SetBarrelButtonForDragEnabled(prefs.barrel_button_for_drag_enabled); settings->SetEditingBehavior(
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 6a138ec..0c637e3b 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -1574,8 +1574,7 @@ webwidget_mouse_lock_target_.get()); } -void RenderWidget::StartDragging(network::mojom::ReferrerPolicy policy, - const WebDragData& data, +void RenderWidget::StartDragging(const WebDragData& data, WebDragOperationsMask mask, const SkBitmap& drag_image, const gfx::Point& web_image_offset) { @@ -1583,7 +1582,6 @@ 0); ConvertViewportToWindow(&offset_in_window); DropData drop_data(DropDataBuilder::Build(data)); - drop_data.referrer_policy = policy; gfx::Vector2d image_offset(offset_in_window.x, offset_in_window.y); Send(new DragHostMsg_StartDragging(routing_id(), drop_data, mask, drag_image, image_offset, possible_drag_event_info_));
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 8966a97..49d12393 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -46,7 +46,6 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "ppapi/buildflags/buildflags.h" -#include "services/network/public/mojom/referrer_policy.mojom.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/widget/screen_info.h" #include "third_party/blink/public/platform/viewport_intersection_state.h" @@ -285,8 +284,7 @@ bool request_unadjusted_movement) override; void RequestPointerUnlock() override; bool IsPointerLocked() override; - void StartDragging(network::mojom::ReferrerPolicy policy, - const blink::WebDragData& data, + void StartDragging(const blink::WebDragData& data, blink::WebDragOperationsMask mask, const SkBitmap& drag_image, const gfx::Point& image_offset) override;
diff --git a/content/shell/renderer/web_test/web_frame_test_proxy.cc b/content/shell/renderer/web_test/web_frame_test_proxy.cc index 51e32e2..86adcc9 100644 --- a/content/shell/renderer/web_test/web_frame_test_proxy.cc +++ b/content/shell/renderer/web_test/web_frame_test_proxy.cc
@@ -18,7 +18,7 @@ #include "content/shell/renderer/web_test/test_runner.h" #include "content/shell/renderer/web_test/web_view_test_proxy.h" #include "content/shell/renderer/web_test/web_widget_test_proxy.h" -#include "third_party/blink/public/common/loader/network_utils.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_plugin_params.h" #include "third_party/blink/public/web/web_testing_support.h" @@ -447,8 +447,8 @@ if (test_runner()->ClearReferrer()) { request.SetReferrerString(blink::WebString()); - request.SetReferrerPolicy(blink::NetToMojoReferrerPolicy( - content::Referrer::GetDefaultReferrerPolicy())); + request.SetReferrerPolicy(blink::ReferrerUtils::NetToMojoReferrerPolicy( + blink::ReferrerUtils::GetDefaultNetReferrerPolicy())); } std::string host = url.host();
diff --git a/content/shell/renderer/web_test/web_widget_test_proxy.cc b/content/shell/renderer/web_test/web_widget_test_proxy.cc index 71e8873..e8ff21e 100644 --- a/content/shell/renderer/web_test/web_widget_test_proxy.cc +++ b/content/shell/renderer/web_test/web_widget_test_proxy.cc
@@ -123,8 +123,7 @@ return event_sender_.IsPointerLocked(); } -void WebWidgetTestProxy::StartDragging(network::mojom::ReferrerPolicy policy, - const blink::WebDragData& data, +void WebWidgetTestProxy::StartDragging(const blink::WebDragData& data, blink::WebDragOperationsMask mask, const SkBitmap& drag_image, const gfx::Point& image_offset) {
diff --git a/content/shell/renderer/web_test/web_widget_test_proxy.h b/content/shell/renderer/web_test/web_widget_test_proxy.h index ad66a4a..9f2b83d 100644 --- a/content/shell/renderer/web_test/web_widget_test_proxy.h +++ b/content/shell/renderer/web_test/web_widget_test_proxy.h
@@ -72,8 +72,7 @@ bool request_unadjusted_movement) override; void RequestPointerUnlock() override; bool IsPointerLocked() override; - void StartDragging(network::mojom::ReferrerPolicy policy, - const blink::WebDragData& data, + void StartDragging(const blink::WebDragData& data, blink::WebDragOperationsMask mask, const SkBitmap& drag_image, const gfx::Point& image_offset) override;
diff --git a/content/test/gpu/gpu_tests/gpu_integration_test.py b/content/test/gpu/gpu_tests/gpu_integration_test.py index df80f54..1646910f 100644 --- a/content/test/gpu/gpu_tests/gpu_integration_test.py +++ b/content/test/gpu/gpu_tests/gpu_integration_test.py
@@ -286,14 +286,7 @@ if ResultType.Failure in expected_results: logging.warning('%s was expected to fail, but passed.\n', test_name) else: - # TODO(https://crbug.com/1061298): Remove this special case once we've - # determined whether the test is only failing because of the expected - # crash check. - if ((test_name == 'Pixel_Video_Context_Loss_VP9' - or test_name == 'Pixel_Video_Context_Loss_MP4') - and sys.platform == 'win32'): - pass - elif not actual_and_expected_crashes_match: + if not actual_and_expected_crashes_match: raise RuntimeError('Actual and expected crashes did not match') @staticmethod
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 7f438d86..6dff383 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -762,6 +762,9 @@ # Linux / OpenGL / NVIDIA failures crbug.com/angleproject/4555 [ linux opengl passthrough nvidia ] conformance/misc/type-conversion-test.html [ Skip ] +# Linux GTX 1660 +crbug.com/1115314 [ linux nvidia-0x2184 opengl passthrough ] deqp/functional/gles3/fbocompleteness.html [ Failure ] + # Linux AMD only. # It looks like AMD shader compiler rejects many valid ES3 semantics. crbug.com/766776 [ linux amd ] conformance2/attribs/gl-vertex-attrib-normalized-int.html [ Failure ]
diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc index 1c229fb..1962a12 100644 --- a/content/test/test_web_contents.cc +++ b/content/test/test_web_contents.cc
@@ -409,21 +409,18 @@ mojo::PendingAssociatedReceiver<blink::mojom::WidgetHost> blink_widget_host, mojo::PendingAssociatedRemote<blink::mojom::Widget> blink_widget) {} -void TestWebContents::ShowCreatedWindow(int process_id, +void TestWebContents::ShowCreatedWindow(RenderFrameHost* opener, int route_id, WindowOpenDisposition disposition, const gfx::Rect& initial_rect, - bool user_gesture) { -} + bool user_gesture) {} void TestWebContents::ShowCreatedWidget(int process_id, int route_id, - const gfx::Rect& initial_rect) { -} + const gfx::Rect& initial_rect) {} void TestWebContents::ShowCreatedFullscreenWidget(int process_id, - int route_id) { -} + int route_id) {} void TestWebContents::SaveFrameWithHeaders( const GURL& url,
diff --git a/content/test/test_web_contents.h b/content/test/test_web_contents.h index e4e874c..8c9e311 100644 --- a/content/test/test_web_contents.h +++ b/content/test/test_web_contents.h
@@ -198,7 +198,7 @@ blink_widget_host, mojo::PendingAssociatedRemote<blink::mojom::Widget> blink_widget) override; - void ShowCreatedWindow(int process_id, + void ShowCreatedWindow(RenderFrameHost* opener, int route_id, WindowOpenDisposition disposition, const gfx::Rect& initial_rect,
diff --git a/device/bluetooth/dbus/bluez_dbus_manager.cc b/device/bluetooth/dbus/bluez_dbus_manager.cc index 8f25b78..f50c910d 100644 --- a/device/bluetooth/dbus/bluez_dbus_manager.cc +++ b/device/bluetooth/dbus/bluez_dbus_manager.cc
@@ -15,6 +15,7 @@ #include "base/system/sys_info.h" #include "base/threading/thread.h" #include "build/build_config.h" +#include "chromeos/constants/chromeos_features.h" #include "dbus/bus.h" #include "dbus/dbus_statistics.h" #include "dbus/message.h" @@ -202,8 +203,6 @@ bluetooth_service_name); client_bundle_->bluetooth_agent_manager_client()->Init( GetSystemBus(), bluetooth_service_name); - client_bundle_->bluetooth_battery_client()->Init(GetSystemBus(), - bluetooth_service_name); client_bundle_->bluetooth_device_client()->Init(GetSystemBus(), bluetooth_service_name); client_bundle_->bluetooth_gatt_characteristic_client()->Init( @@ -226,6 +225,14 @@ GetSystemBus(), bluetooth_object_manager::kBluetoothObjectManagerServiceName); +#if defined(OS_CHROMEOS) + if (base::FeatureList::IsEnabled( + chromeos::features::kShowBluetoothDeviceBattery)) { + client_bundle_->bluetooth_battery_client()->Init(GetSystemBus(), + bluetooth_service_name); + } +#endif + if (!alternate_bus_) return;
diff --git a/docs/chromeos_build_instructions.md b/docs/chromeos_build_instructions.md index 6874a1e..ad4c9a0 100644 --- a/docs/chromeos_build_instructions.md +++ b/docs/chromeos_build_instructions.md
@@ -1,25 +1,27 @@ -# Chrome OS Build Instructions (Chromium OS on Linux) +# Chrome OS Build Instructions -Chromium on Chromium OS uses Linux Chromium as a base, but adds a large number -of features to the code. For example, the login UI, window manager and system UI -are part of the Chromium code base and built into the chrome binary. +Chrome for Chromium OS can be built in a couple different ways. After following +the [initial setup](#common-setup), you'll need to choose one of the following +build configurations: -Fortunately, most Chromium changes that affect Chromium OS can be built and -tested on a Linux workstation. This build is called "linux-chromeos". In this -configuration most system services (like the power manager, bluetooth daemon, -etc.) are stubbed out. The entire system UI runs in a single X11 window on your -desktop. +- If you're interested in testing Chrome OS code in Chrome, but not interactions + with Chrome OS services, you can build for + [linux-chromeos](#Chromium-OS-on-Linux-linux_chromeos) using just a Linux + workstation. +- Otherwise, Chrome's full integration can be covered by building for a real + Chrome OS device or VM using [Simple Chrome](#Chromium-OS-Device-Simple-Chrome). + +[TOC] + +## Common setup First, follow the [normal Linux build instructions](https://chromium.googlesource.com/chromium/src/+/master/docs/linux/build_instructions.md) as usual to get a Chromium checkout. -## Updating your gclient config - -Chromium OS builds of Chromium require some additional build dependencies which -can be synced by adding `'chromeos'` to the `target_os` list in your `.gclient` -configuration. This file is located one level up from your Chromium checkout's -`src`. +You'll also need to add `'chromeos'` to the `target_os` list in your `.gclient` +configuration, which will fetch the additional build dependencies required for +CrOS. This file is located one level up from your Chromium checkout's `src`. If you don't already have a `target_os` line present, simply add this to the end of the `.gclient` file: @@ -34,7 +36,20 @@ Once your `.gclient` file is updated, you will need to run `gclient sync` once before proceeding with the rest of these instructions. -## Building and running Chromium with Chromium OS UI on your local machine +## Chromium OS on Linux (linux-chromeos) + +Chromium on Chromium OS uses Linux Chromium as a base, but adds a large number +of Chrome OS-specific features to the code. For example, the login UI, window +manager and system UI are part of the Chromium code base and built into the +chrome binary. + +Fortunately, most Chromium changes that affect Chromium OS can be built and +tested on a Linux workstation. This build is called "linux-chromeos". In this +configuration most system services (like the power manager, bluetooth daemon, +etc.) are stubbed out. The entire system UI runs in a single X11 window on your +desktop. + +### Building and running Chromium with Chromium OS UI on your local machine Run the following in your chromium checkout: @@ -68,7 +83,7 @@ You can also build and run test targets like `unit_tests`, `browser_tests`, etc. -## Flags +### Flags Some useful flags: @@ -90,7 +105,7 @@ http://localhost:9222 * `--use-system-clipboard`: Integrate clipboard with the host X11 system. -## Login notes +### Login notes By default this build signs in with a stub user. To specify a real user: @@ -107,7 +122,7 @@ Signing in as a specific user is useful for debugging features like sync that require a logged in user. -## Graphics notes +### Graphics notes The Chromium OS build requires a functioning GL so if you plan on testing it through Chromium Remote Desktop you might face drawing @@ -119,7 +134,65 @@ To more closely match the UI used on devices, you can install fonts used by Chrome OS, such as Roboto, on your Linux distro. -## Compile Chromium for a Chromium OS device +## Chromium OS Device (Simple Chrome) -See [Building Chromium for a Chromium OS device](https://chromium.googlesource.com/chromiumos/docs/+/master/simple_chrome_workflow.md) -for information about building and testing Chromium for Chromium OS. +This configuration allows you to build a fully functional Chrome for a real +Chrome OS device or VM. Since Chrome OS uses a different toolchain for each +device model, you'll first need to know the name of the model (or "board") you +want to build for. For most boards, `amd64-generic` and `arm-generic` will +produce a functional binary, though it won't be optimized and may be missing +functionality. + +### Additional gclient setup + +Each board has its own toolchain and misc. build dependencies. To fetch these, +list the board under the `"cros_boards"` gclient custom var. If you were using +the `amd64-generic` board, your `.gclient` file would look like: +``` +solutions = [ + { + "url": "https://chromium.googlesource.com/chromium/src.git", + "name": "src", + "custom_deps": {}, + "custom_vars" : { + "cros_boards": "amd64-generic", + }, + }, +] +target_os = ["chromeos"] +``` +Once your .gclient file is updated, you will need to run `gclient sync` again +to fetch the toolchain. + +NOTE: + - If you'd like a VM image additionally downloaded for the board, add it to the + `"cros_boards_with_qemu_images"` gclient custom var. That var downloads the + SDK along with a VM image. `cros_boards` downloads only the SDK. + - If you'd like to fetch multiple boards, add a `:` between each board in the + gclient var. For example: `"cros_boards": "amd64-generic:arm-generic"`. + +### Building for the board + +After the needed toolchain has been downloaded for your ${BOARD}, a build dir +will have been conveniently created for you at `out_$BOARD/Release`, which can +then be used to build Chrome. For the `amd64-generic` board, this would +look like: + + $ gn gen out_amd64-generic/Release + $ autoninja -C out_$BOARD/Release chrome + +Or if you prefer to use your own build dir, simply add the following line to the +top of your GN args: `import("//build/args/chromeos/amd64-generic.gni")`. eg: + + $ gn gen out/Default --args='import("//build/args/chromeos/amd64-generic.gni")' + $ autoninja -C out/Default chrome + +That will produce a Chrome OS build of Chrome very similar to what is shipped +for that device. You can also supply additional args or even overwrite ones +supplied in the imported .gni file after the `import()` line. + +### Additional notes + +For more information (like copying the locally-built Chrome to a device, or +running Tast tests), consult Simple Chrome's +[full documentation](https://chromium.googlesource.com/chromiumos/docs/+/master/simple_chrome_workflow.md).
diff --git a/docs/enterprise/description_guidelines.md b/docs/enterprise/description_guidelines.md index 9db153ba..575dbdb 100644 --- a/docs/enterprise/description_guidelines.md +++ b/docs/enterprise/description_guidelines.md
@@ -1,11 +1,12 @@ To ensure consistency in policy descriptions, the following is a mapping of how various product names and the like should be referenced. -Chrome: <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> -Chrome OS: <ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph> -Linux: <ph name="LINUX_OS_NAME">Linux</ph> -Internet Explorer: <ph name="IE_PRODUCT_NAME">Internet® Explorer®</ph> -Google Cast: <ph name="PRODUCT_NAME">Google Cast</ph> -Google Drive: <ph name="GOOGLE_DRIVE_NAME">Google Drive</ph> -Windows: <ph name="MS_WIN_NAME">Microsoft® Windows®</ph> -Microsoft ActiveDirectory: <ph name="MS_AD_NAME">Microsoft® Active Directory®</ph> +* Chrome: `<ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>` +* Chrome OS: `<ph name="PRODUCT_OS_NAME">$2<ex>Google Chrome OS</ex></ph>` +* Linux: `<ph name="LINUX_OS_NAME">Linux</ph>` +* Internet Explorer: `<ph name="IE_PRODUCT_NAME">Internet® Explorer®</ph>` +* Google Cast: `<ph name="PRODUCT_NAME">Google Cast</ph>` +* Google Drive: `<ph name="GOOGLE_DRIVE_NAME">Google Drive</ph>` +* macOS: `<ph name="MAC_OS_NAME">macOS</ph>` +* Windows: `<ph name="MS_WIN_NAME">Microsoft® Windows®</ph>` +* Microsoft ActiveDirectory: `<ph name="MS_AD_NAME">Microsoft® Active Directory®</ph>`
diff --git a/docs/infra/new_builder.md b/docs/infra/new_builder.md index c74ef1b..c5fa278 100644 --- a/docs/infra/new_builder.md +++ b/docs/infra/new_builder.md
@@ -218,7 +218,8 @@ set of consoles. Its configuration includes the definitions of those consoles. -Chromium's milo Starlark configuration is [here][25]. +Chromium's milo Starlark configuration is intermixed with the +[builder definitions][23]. Chromium's generated milo configuration is [here][10]. Milo's configuration schema is [here][9]. @@ -374,6 +375,5 @@ [20]: https://chromium.googlesource.com/infra/luci/luci-py/+/master/appengine/swarming/proto/bots.proto [21]: https://chromium.googlesource.com/chromium/tools/build/+/master/scripts/slave/recipe_modules/chromium_tests/trybots.py [22]: /infra/config/main.star -[23]: /infra/config/buckets +[23]: /infra/config/subprojects/chromium [24]: /infra/config/lib/builders.star -[25]: /infra/config/consoles
diff --git a/docs/security/compromised-renderers.md b/docs/security/compromised-renderers.md index 434d711..ffee9902 100644 --- a/docs/security/compromised-renderers.md +++ b/docs/security/compromised-renderers.md
@@ -387,7 +387,7 @@ - `request_initiator_site_lock` may be missing in unlocked renderer processes on Android (for example affecting protections of CORB, CORP, Sec-Fetch-Site and in the future SameSite cookies and Origin - protections). See also https://crbug.com/1098938. + protections). See also https://crbug.com/1114906. ## Renderer processes hosting DevTools frontend
diff --git a/docs/speed/benchmark/harnesses/loading.md b/docs/speed/benchmark/harnesses/loading.md index f7677d5..5ff31926 100644 --- a/docs/speed/benchmark/harnesses/loading.md +++ b/docs/speed/benchmark/harnesses/loading.md
@@ -18,11 +18,27 @@ benchmarks which are run continuously on the perf waterfall, this benchmark is triggered on-demand only. -# Running the tests remotely +## Running the tests remotely If you're just trying to gauge whether your change has caused a loading -regression, you can either run `loading.desktop` and `loading.mobile` through -[perf try job](https://chromium.googlesource.com/chromium/src/+/master/docs/speed/perf_trybots.md) or you can run `loading.cluster_telemetry` through +regression, you can run the loading benchmarks through perf try job or through +Cluster Telemetry service. You can specify a Gerrit patch for them and compare +the results with and without the patch applied. + +### Using Perf Try Bots +[Perf Try Bots](https://chromium.googlesource.com/chromium/src/+/master/docs/speed/perf_trybots.md) +lets you run only single story of `loading.desktop` or `loading.mobile`, because +an entire loading benchmark is too large to run as a perf try job. You should +only set the `Story` field, and leave the `Story Tags` field blank. Invalid +combinations of `Story` and `Story Tags` will result in "zero Histograms" result +page. + +See +[Understanding the loading test cases](#understanding-the-loading-test-cases) +for story name conventions. + +### Using Cluster Telemetry Service +You can run `loading.cluster_telemetry` (top 10k pages) through [Cluster Telemetry service](https://ct.skia.org/) (Cluster Telemetry is for Googler only).
diff --git a/docs/threading_and_tasks.md b/docs/threading_and_tasks.md index a7df61e2..8107734 100644 --- a/docs/threading_and_tasks.md +++ b/docs/threading_and_tasks.md
@@ -655,7 +655,7 @@ } // Returns the latest thread-safe number of incomplete work items. -void NumIncompleteWorkItems(); +void NumIncompleteWorkItems(size_t worker_count); base::PostJob(FROM_HERE, {}, base::BindRepeating(&WorkerTask),
diff --git a/gin/v8_platform.cc b/gin/v8_platform.cc index bf6a1c9..7094260 100644 --- a/gin/v8_platform.cc +++ b/gin/v8_platform.cc
@@ -498,17 +498,19 @@ task_traits = kBlockingTaskTraits; break; } - auto handle = base::PostJob( - FROM_HERE, task_traits, - base::BindRepeating( - [](v8::JobTask* job_task, base::JobDelegate* delegate) { - JobDelegateImpl delegate_impl(delegate); - job_task->Run(&delegate_impl); - }, - base::Unretained(job_task.get())), - base::BindRepeating( - [](v8::JobTask* job_task) { return job_task->GetMaxConcurrency(); }, - base::Unretained(job_task.get()))); + auto handle = + base::PostJob(FROM_HERE, task_traits, + base::BindRepeating( + [](v8::JobTask* job_task, base::JobDelegate* delegate) { + JobDelegateImpl delegate_impl(delegate); + job_task->Run(&delegate_impl); + }, + base::Unretained(job_task.get())), + base::BindRepeating( + [](v8::JobTask* job_task, size_t /*worker_count*/) { + return job_task->GetMaxConcurrency(); + }, + base::Unretained(job_task.get()))); return std::make_unique<JobHandleImpl>(std::move(handle), std::move(job_task));
diff --git a/gpu/config/BUILD.gn b/gpu/config/BUILD.gn index bac4500a6..27823155 100644 --- a/gpu/config/BUILD.gn +++ b/gpu/config/BUILD.gn
@@ -235,7 +235,7 @@ # External code should depend on ":config_java" instead. visibility = [ ":*" ] sources = [ "gpu_switches.cc" ] - template = "android/java/src/org/chromium/gpu/GpuSwitches.java.tmpl" + template = "android/java/src/org/chromium/gpu/config/GpuSwitches.java.tmpl" } android_library("config_java") {
diff --git a/gpu/config/android/java/src/org/chromium/gpu/GpuSwitches.java.tmpl b/gpu/config/android/java/src/org/chromium/gpu/config/GpuSwitches.java.tmpl similarity index 100% rename from gpu/config/android/java/src/org/chromium/gpu/GpuSwitches.java.tmpl rename to gpu/config/android/java/src/org/chromium/gpu/config/GpuSwitches.java.tmpl
diff --git a/gpu/config/software_rendering_list.json b/gpu/config/software_rendering_list.json index f0464417..1df09bc 100644 --- a/gpu/config/software_rendering_list.json +++ b/gpu/config/software_rendering_list.json
@@ -336,22 +336,6 @@ ] }, { - "id": 48, - "description": "Accelerated video decode is unavailable on Linux", - "cr_bugs": [137247, 1032907], - "os": { - "type": "linux" - }, - "exceptions": [ - { - "machine_model_name": ["Chromecast"] - } - ], - "features": [ - "accelerated_video_decode" - ] - }, - { "id": 50, "description": "Disable VMware software renderer on older Mesa", "cr_bugs": [145531, 332596, 571899, 629434],
diff --git a/headless/lib/browser/headless_print_manager.cc b/headless/lib/browser/headless_print_manager.cc index d524f7b7..d66fe896 100644 --- a/headless/lib/browser/headless_print_manager.cc +++ b/headless/lib/browser/headless_print_manager.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "components/printing/browser/print_manager_utils.h" +#include "components/printing/common/print.mojom.h" #include "components/printing/common/print_messages.h" #include "content/public/browser/render_view_host.h" #include "printing/print_job_constants.h" @@ -267,9 +268,9 @@ void HeadlessPrintManager::OnDidPrintDocument( content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPrintDocument_Params& params, + const printing::mojom::DidPrintDocumentParams& params, std::unique_ptr<DelayedFrameDispatchHelper> helper) { - auto& content = params.content; + auto& content = *params.content; if (!content.metafile_data_region.IsValid()) { ReleaseJob(INVALID_MEMORY_HANDLE); return;
diff --git a/headless/lib/browser/headless_print_manager.h b/headless/lib/browser/headless_print_manager.h index bdd5fae..998db62da 100644 --- a/headless/lib/browser/headless_print_manager.h +++ b/headless/lib/browser/headless_print_manager.h
@@ -11,12 +11,12 @@ #include "base/memory/ref_counted_memory.h" #include "components/printing/browser/print_manager.h" +#include "components/printing/common/print.mojom-forward.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents_user_data.h" #include "headless/public/headless_export.h" #include "printing/print_settings.h" -struct PrintHostMsg_DidPrintDocument_Params; struct PrintHostMsg_ScriptedPrint_Params; struct PrintMsg_PrintPages_Params; @@ -100,7 +100,7 @@ // printing::PrintManager: void OnDidPrintDocument( content::RenderFrameHost* render_frame_host, - const PrintHostMsg_DidPrintDocument_Params& params, + const printing::mojom::DidPrintDocumentParams& params, std::unique_ptr<DelayedFrameDispatchHelper> helper) override; void OnGetDefaultPrintSettings(content::RenderFrameHost* render_frame_host, IPC::Message* reply_msg) override;
diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg index e95bafd..844abfa 100644 --- a/infra/config/generated/commit-queue.cfg +++ b/infra/config/generated/commit-queue.cfg
@@ -176,6 +176,7 @@ builders { name: "chromium/try/android-binary-size" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -184,6 +185,7 @@ location_regexp: ".+/[+]/components/grpc_support/.+" location_regexp: ".+/[+]/build/android/.+" location_regexp: ".+/[+]/build/config/android/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" location_regexp_exclude: ".+/[+]/components/cronet/ios/.+" } @@ -198,11 +200,13 @@ builders { name: "chromium/try/android-lollipop-arm-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try/android-marshmallow-arm64-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -213,6 +217,7 @@ name: "chromium/try/android-marshmallow-x86-rel" experiment_percentage: 5 location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -251,6 +256,7 @@ location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" location_regexp: ".+/[+]/third_party/arcore-android-sdk/.+" location_regexp: ".+/[+]/third_party/arcore-android-sdk-client/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -336,6 +342,7 @@ builders { name: "chromium/try/android_compile_dbg" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -348,6 +355,7 @@ location_regexp: ".+/[+]/sandbox/linux/system_headers/.+" location_regexp: ".+/[+]/sandbox/linux/tests/.+" location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -360,11 +368,13 @@ location_regexp: ".+/[+]/sandbox/linux/system_headers/.+" location_regexp: ".+/[+]/sandbox/linux/tests/.+" location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try/android_cronet" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -392,6 +402,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -401,6 +412,7 @@ builders { name: "chromium/try/cast_shell_android" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -410,6 +422,7 @@ builders { name: "chromium/try/cast_shell_linux" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -420,11 +433,13 @@ name: "chromium/try/chromeos-amd64-generic-dbg" location_regexp: ".+/[+]/content/gpu/.+" location_regexp: ".+/[+]/media/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try/chromeos-amd64-generic-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -434,6 +449,7 @@ builders { name: "chromium/try/chromeos-arm-generic-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -445,6 +461,7 @@ location_regexp: ".+/[+]/build/chromeos/.+" location_regexp: ".+/[+]/build/config/chromeos/.*" location_regexp: ".+/[+]/chromeos/CHROMEOS_LKGM" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -454,6 +471,7 @@ builders { name: "chromium/try/closure_compilation" location_regexp: ".+/[+]/third_party/closure_compiler/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -467,6 +485,7 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -480,6 +499,7 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -501,6 +521,7 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -514,6 +535,7 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -523,12 +545,14 @@ builders { name: "chromium/try/fuchsia-arm64-cast" location_regexp: ".+/[+]/chromecast/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try/fuchsia-compile-x64-dbg" experiment_percentage: 50 location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -554,16 +578,19 @@ builders { name: "chromium/try/fuchsia-x64-cast" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try/fuchsia_arm64" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try/fuchsia_x64" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -829,12 +856,14 @@ builders { name: "chromium/try/ios-simulator" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try/ios-simulator-code-coverage" experiment_percentage: 3 location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -846,6 +875,7 @@ location_regexp: ".+/[+]/components/cronet/.+" location_regexp: ".+/[+]/components/grpc_support/.+" location_regexp: ".+/[+]/ios/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" location_regexp_exclude: ".+/[+]/components/cronet/android/.+" } @@ -856,6 +886,7 @@ builders { name: "chromium/try/ios-simulator-full-configs" location_regexp: ".+/[+]/ios/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -924,11 +955,13 @@ location_regexp: ".+/[+]/third_party/blink/renderer/core/paint/.+" location_regexp: ".+/[+]/third_party/blink/renderer/core/svg/.+" location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try/linux-chromeos-compile-dbg" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -939,6 +972,7 @@ name: "chromium/try/linux-chromeos-rel" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -964,6 +998,7 @@ builders { name: "chromium/try/linux-lacros-compile-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -981,6 +1016,7 @@ builders { name: "chromium/try/linux-libfuzzer-asan-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -990,6 +1026,7 @@ builders { name: "chromium/try/linux-ozone-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1000,11 +1037,13 @@ location_regexp: ".+/[+]/components/tracing/.+" location_regexp: ".+/[+]/content/browser/tracing/.+" location_regexp: ".+/[+]/services/tracing/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try/linux-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1074,6 +1113,7 @@ builders { name: "chromium/try/linux_chromium_asan_rel_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1103,6 +1143,7 @@ builders { name: "chromium/try/linux_chromium_compile_dbg_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1112,6 +1153,7 @@ builders { name: "chromium/try/linux_chromium_dbg_ng" location_regexp: ".+/[+]/build/.*check_gn_headers.*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1121,6 +1163,7 @@ builders { name: "chromium/try/linux_chromium_tsan_rel_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1133,6 +1176,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/core/svg/.+" location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" location_regexp: ".+/[+]/third_party/blink/web_tests/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1145,6 +1189,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" location_regexp: ".+/[+]/third_party/blink/web_tests/FlagExpectations/disable-layout-ng" location_regexp: ".+/[+]/third_party/blink/web_tests/flag-specific/disable-layout-ng/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1170,6 +1215,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1180,6 +1226,7 @@ name: "chromium/try/linux_vr" location_regexp: ".+/[+]/chrome/browser/vr/.+" location_regexp: ".+/[+]/content/browser/xr/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1194,6 +1241,7 @@ name: "chromium/try/mac-coverage-rel" experiment_percentage: 3 location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1207,6 +1255,7 @@ builders { name: "chromium/try/mac-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1260,6 +1309,7 @@ builders { name: "chromium/try/mac_chromium_compile_dbg_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1286,6 +1336,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1340,6 +1391,7 @@ name: "chromium/try/win-libfuzzer-asan-rel" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1386,6 +1438,7 @@ name: "chromium/try/win10_chromium_x64_rel_ng" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1403,6 +1456,7 @@ builders { name: "chromium/try/win7-rel" location_regexp: ".+/[+]/sandbox/win/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1413,6 +1467,7 @@ name: "chromium/try/win_chromium_compile_dbg_ng" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1449,6 +1504,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1523,6 +1579,7 @@ builders { name: "chromium/try-m84/android-binary-size" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1531,17 +1588,20 @@ location_regexp: ".+/[+]/components/grpc_support/.+" location_regexp: ".+/[+]/build/android/.+" location_regexp: ".+/[+]/build/config/android/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" location_regexp_exclude: ".+/[+]/components/cronet/ios/.+" } builders { name: "chromium/try-m84/android-lollipop-arm-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/android-marshmallow-arm64-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1554,6 +1614,7 @@ location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" location_regexp: ".+/[+]/third_party/arcore-android-sdk/.+" location_regexp: ".+/[+]/third_party/arcore-android-sdk-client/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1563,6 +1624,7 @@ builders { name: "chromium/try-m84/android_compile_dbg" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1575,6 +1637,7 @@ location_regexp: ".+/[+]/sandbox/linux/system_headers/.+" location_regexp: ".+/[+]/sandbox/linux/tests/.+" location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1587,11 +1650,13 @@ location_regexp: ".+/[+]/sandbox/linux/system_headers/.+" location_regexp: ".+/[+]/sandbox/linux/tests/.+" location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/android_cronet" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1611,32 +1676,38 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/cast_shell_android" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/cast_shell_linux" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/chromeos-amd64-generic-dbg" location_regexp: ".+/[+]/content/gpu/.+" location_regexp: ".+/[+]/media/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/chromeos-amd64-generic-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/chromeos-arm-generic-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1646,6 +1717,7 @@ builders { name: "chromium/try-m84/closure_compilation" location_regexp: ".+/[+]/third_party/closure_compiler/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1659,6 +1731,7 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1672,6 +1745,7 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1685,6 +1759,7 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1698,31 +1773,37 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/fuchsia-arm64-cast" location_regexp: ".+/[+]/chromecast/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/fuchsia-x64-cast" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/fuchsia_arm64" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/fuchsia_x64" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/ios-simulator" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1730,12 +1811,14 @@ location_regexp: ".+/[+]/components/cronet/.+" location_regexp: ".+/[+]/components/grpc_support/.+" location_regexp: ".+/[+]/ios/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" location_regexp_exclude: ".+/[+]/components/cronet/android/.+" } builders { name: "chromium/try-m84/ios-simulator-full-configs" location_regexp: ".+/[+]/ios/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1744,52 +1827,62 @@ location_regexp: ".+/[+]/third_party/blink/renderer/core/paint/.+" location_regexp: ".+/[+]/third_party/blink/renderer/core/svg/.+" location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/linux-chromeos-compile-dbg" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/linux-chromeos-rel" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/linux-libfuzzer-asan-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/linux-ozone-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/linux-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/linux_chromium_asan_rel_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/linux_chromium_compile_dbg_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/linux_chromium_dbg_ng" location_regexp: ".+/[+]/build/.*check_gn_headers.*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/linux_chromium_tsan_rel_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1798,6 +1891,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/core/svg/.+" location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" location_regexp: ".+/[+]/third_party/blink/web_tests/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1810,6 +1904,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" location_regexp: ".+/[+]/third_party/blink/web_tests/FlagExpectations/disable-layout-ng" location_regexp: ".+/[+]/third_party/blink/web_tests/flag-specific/disable-layout-ng/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1827,22 +1922,26 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/linux_vr" location_regexp: ".+/[+]/chrome/browser/vr/.+" location_regexp: ".+/[+]/content/browser/xr/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/mac-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/mac_chromium_compile_dbg_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1861,24 +1960,28 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/win-libfuzzer-asan-rel" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/win10_chromium_x64_rel_ng" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m84/win_chromium_compile_dbg_ng" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1899,6 +2002,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } retry_config { @@ -1965,6 +2069,7 @@ builders { name: "chromium/try-m85/android-binary-size" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -1973,17 +2078,20 @@ location_regexp: ".+/[+]/components/grpc_support/.+" location_regexp: ".+/[+]/build/android/.+" location_regexp: ".+/[+]/build/config/android/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" location_regexp_exclude: ".+/[+]/components/cronet/ios/.+" } builders { name: "chromium/try-m85/android-lollipop-arm-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/android-marshmallow-arm64-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2008,6 +2116,7 @@ location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" location_regexp: ".+/[+]/third_party/arcore-android-sdk/.+" location_regexp: ".+/[+]/third_party/arcore-android-sdk-client/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2017,6 +2126,7 @@ builders { name: "chromium/try-m85/android_compile_dbg" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2029,6 +2139,7 @@ location_regexp: ".+/[+]/sandbox/linux/system_headers/.+" location_regexp: ".+/[+]/sandbox/linux/tests/.+" location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2041,11 +2152,13 @@ location_regexp: ".+/[+]/sandbox/linux/system_headers/.+" location_regexp: ".+/[+]/sandbox/linux/tests/.+" location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/android_cronet" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2065,32 +2178,38 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/cast_shell_android" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/cast_shell_linux" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/chromeos-amd64-generic-dbg" location_regexp: ".+/[+]/content/gpu/.+" location_regexp: ".+/[+]/media/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/chromeos-amd64-generic-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/chromeos-arm-generic-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2100,6 +2219,7 @@ builders { name: "chromium/try-m85/closure_compilation" location_regexp: ".+/[+]/third_party/closure_compiler/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2113,6 +2233,7 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2126,6 +2247,7 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2139,6 +2261,7 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2152,11 +2275,13 @@ location_regexp: ".+/[+]/third_party/dawn/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/features.gni" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/fuchsia-arm64-cast" location_regexp: ".+/[+]/chromecast/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2166,22 +2291,26 @@ builders { name: "chromium/try-m85/fuchsia-x64-cast" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/fuchsia_arm64" experiment_percentage: 50 location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/fuchsia_x64" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/ios-simulator" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2189,12 +2318,14 @@ location_regexp: ".+/[+]/components/cronet/.+" location_regexp: ".+/[+]/components/grpc_support/.+" location_regexp: ".+/[+]/ios/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" location_regexp_exclude: ".+/[+]/components/cronet/android/.+" } builders { name: "chromium/try-m85/ios-simulator-full-configs" location_regexp: ".+/[+]/ios/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2203,22 +2334,26 @@ location_regexp: ".+/[+]/third_party/blink/renderer/core/paint/.+" location_regexp: ".+/[+]/third_party/blink/renderer/core/svg/.+" location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/linux-chromeos-compile-dbg" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/linux-chromeos-rel" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/linux-libfuzzer-asan-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2228,31 +2363,37 @@ builders { name: "chromium/try-m85/linux-ozone-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/linux-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/linux_chromium_asan_rel_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/linux_chromium_compile_dbg_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/linux_chromium_dbg_ng" location_regexp: ".+/[+]/build/.*check_gn_headers.*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/linux_chromium_tsan_rel_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2261,6 +2402,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/core/svg/.+" location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" location_regexp: ".+/[+]/third_party/blink/web_tests/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2273,6 +2415,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" location_regexp: ".+/[+]/third_party/blink/web_tests/FlagExpectations/disable-layout-ng" location_regexp: ".+/[+]/third_party/blink/web_tests/flag-specific/disable-layout-ng/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2290,22 +2433,26 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/linux_vr" location_regexp: ".+/[+]/chrome/browser/vr/.+" location_regexp: ".+/[+]/content/browser/xr/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/mac-rel" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/mac_chromium_compile_dbg_ng" location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2324,24 +2471,28 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/win-libfuzzer-asan-rel" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/win10_chromium_x64_rel_ng" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { name: "chromium/try-m85/win_chromium_compile_dbg_ng" cancel_stale: NO location_regexp: ".*" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } builders { @@ -2362,6 +2513,7 @@ location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" location_regexp: ".+/[+]/tools/clang/scripts/update.py" location_regexp: ".+/[+]/ui/gl/.+" + location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } retry_config {
diff --git a/infra/config/generated/realms.cfg b/infra/config/generated/realms.cfg index 36ed79d8..d3c0a94 100644 --- a/infra/config/generated/realms.cfg +++ b/infra/config/generated/realms.cfg
@@ -150,6 +150,10 @@ role: "role/buildbucket.reader" principals: "group:all" } + bindings { + role: "role/resultdb.invocationCreator" + principals: "group:project-chromium-tryjob-access" + } } realms { name: "try"
diff --git a/infra/config/generators/cq-builders-md.star b/infra/config/generators/cq-builders-md.star index 75b2864..410bb13 100644 --- a/infra/config/generators/cq-builders-md.star +++ b/infra/config/generators/cq-builders-md.star
@@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -load("//lib/try.star", "INFRA_CONFIG_LOCATION_REGEXP") +load("//lib/try.star", "DEFAULT_EXCLUDE_REGEXPS") _MD_HEADER = """\ <!-- Auto-generated by lucicfg (via cq-builders-md.star). --> @@ -70,7 +70,7 @@ location_regexp_exclude = [ r for r in builder.location_regexp_exclude - if r != INFRA_CONFIG_LOCATION_REGEXP + if r not in DEFAULT_EXCLUDE_REGEXPS ] location_regexp = builder.location_regexp if list(location_regexp) == [".*"] and not location_regexp_exclude:
diff --git a/infra/config/lib/try.star b/infra/config/lib/try.star index c839d84..3d0e16ff 100644 --- a/infra/config/lib/try.star +++ b/infra/config/lib/try.star
@@ -22,7 +22,12 @@ load("./builders.star", "builders") load("./args.star", "args") -INFRA_CONFIG_LOCATION_REGEXP = ".+/[+]/infra/config/.+" +DEFAULT_EXCLUDE_REGEXPS = [ + # Contains documentation that doesn't affect the outputs + ".+/[+]/docs/.+", + # Contains configuration files that aren't active until after committed + ".+/[+]/infra/config/.+", +] defaults = args.defaults( extends = builders.defaults, @@ -160,22 +165,24 @@ location_regexp = None, location_regexp_exclude = None, cancel_stale = None, - run_on_infra_config_changes = False): + add_default_excludes = True): """Specifies the details of a tryjob verifier. See https://chromium.googlesource.com/infra/luci/luci-go/+/refs/heads/master/lucicfg/doc/README.md#luci.cq_tryjob_verifier for details on the most of the arguments. Arguments: - run_on_infra_changes - A bool indicating whether the try job should be run - for changes against //infra/config. + add_default_excludes - A bool indicating whether to add exclude regexps + for certain directories that would have no impact when building chromium + with the patch applied (docs, config files that don't take effect until + landing, etc., see DEFAULT_EXCLUDE_REGEXPS). Returns: A struct that can be passed to the `tryjob` argument of `try_.builder` to enable the builder for CQ. """ - if not run_on_infra_config_changes: - location_regexp_exclude = [INFRA_CONFIG_LOCATION_REGEXP] + (location_regexp_exclude or []) + if add_default_excludes: + location_regexp_exclude = DEFAULT_EXCLUDE_REGEXPS + (location_regexp_exclude or []) return struct( disable_reuse = disable_reuse, experiment_percentage = experiment_percentage,
diff --git a/infra/config/main.star b/infra/config/main.star index d99746e..d4e0113 100755 --- a/infra/config/main.star +++ b/infra/config/main.star
@@ -108,6 +108,10 @@ roles = "role/buildbucket.reader", groups = "all", ), + luci.binding( + roles = "role/resultdb.invocationCreator", + groups = "project-chromium-tryjob-access", + ), # Other roles are inherited from @root which grants them to group:all. ], )
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index fff037b..48ac6d9 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -345,7 +345,7 @@ }, tryjob = try_.job( disable_reuse = True, - run_on_infra_config_changes = True, + add_default_excludes = False, ), )
diff --git a/infra/config/subprojects/chromium/versioned/m84/buckets/try.star b/infra/config/subprojects/chromium/versioned/m84/buckets/try.star index c28987e..0560edc 100644 --- a/infra/config/subprojects/chromium/versioned/m84/buckets/try.star +++ b/infra/config/subprojects/chromium/versioned/m84/buckets/try.star
@@ -306,7 +306,7 @@ }, tryjob = try_.job( disable_reuse = True, - run_on_infra_config_changes = True, + add_default_excludes = False, ), )
diff --git a/infra/config/subprojects/chromium/versioned/m85/buckets/try.star b/infra/config/subprojects/chromium/versioned/m85/buckets/try.star index a065e2b9..63daa824b 100644 --- a/infra/config/subprojects/chromium/versioned/m85/buckets/try.star +++ b/infra/config/subprojects/chromium/versioned/m85/buckets/try.star
@@ -311,7 +311,7 @@ }, tryjob = try_.job( disable_reuse = True, - run_on_infra_config_changes = True, + add_default_excludes = False, ), )
diff --git a/ios/build/bots/scripts/xcode_log_parser.py b/ios/build/bots/scripts/xcode_log_parser.py index 33a45368..c9ccbe0 100644 --- a/ios/build/bots/scripts/xcode_log_parser.py +++ b/ios/build/bots/scripts/xcode_log_parser.py
@@ -15,6 +15,11 @@ import test_runner +# Some system errors are reported as failed tests in Xcode test result log in +# Xcode 12, e.g. test app crash in xctest parallel testing. This are reported +# as 'BUILD_INTERRUPTED' in failed test log of the attempt and will be removed +# if all tests pass in re-attempts. +SYSTEM_ERROR_TEST_NAME_SUFFIXES = ['encountered an error'] LOGGER = logging.getLogger(__name__) @@ -49,7 +54,7 @@ `[TestClass/TestMethod]` Returns: - Test case id in format TestClass_TestMethod. + Test case id in format TestClass/TestMethod. """ return test_case.replace('[', '').replace(']', '').replace( '-', '').replace(' ', '/') @@ -175,6 +180,10 @@ continue for test in test_suite['subtests']['_values']: test_name = test['identifier']['_value'] + if any( + test_name.endswith(suffix) + for suffix in SYSTEM_ERROR_TEST_NAME_SUFFIXES): + test_name = 'BUILD_INTERRUPTED' if test['testStatus']['_value'] == 'Success': results['passed'].append(test_name) else:
diff --git a/ios/chrome/app/startup/chrome_app_startup_parameters.h b/ios/chrome/app/startup/chrome_app_startup_parameters.h index 9643ae1..ae10c1c 100644 --- a/ios/chrome/app/startup/chrome_app_startup_parameters.h +++ b/ios/chrome/app/startup/chrome_app_startup_parameters.h
@@ -38,10 +38,6 @@ MOBILE_SESSION_CALLER_APP_COUNT, }; -// UserDefaults key that saves the last time an HTTP(S) link was sent and opened -// by the app. -extern NSString* const kLastHTTPURLOpenTime; - @interface ChromeAppStartupParameters : AppStartupParameters - (instancetype)initWithExternalURL:(const GURL&)externalURL
diff --git a/ios/chrome/app/startup/chrome_app_startup_parameters.mm b/ios/chrome/app/startup/chrome_app_startup_parameters.mm index 5a78dbd..44a1bf7 100644 --- a/ios/chrome/app/startup/chrome_app_startup_parameters.mm +++ b/ios/chrome/app/startup/chrome_app_startup_parameters.mm
@@ -78,8 +78,6 @@ } // namespace -NSString* const kLastHTTPURLOpenTime = @"lastHTTPURLOpenTime"; - @implementation ChromeAppStartupParameters { NSString* _secureSourceApp; NSString* _declaredSourceApp;
diff --git a/ios/chrome/browser/policy/BUILD.gn b/ios/chrome/browser/policy/BUILD.gn index fca8a07..6e4c866 100644 --- a/ios/chrome/browser/policy/BUILD.gn +++ b/ios/chrome/browser/policy/BUILD.gn
@@ -129,7 +129,10 @@ source_set("unit_tests") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true - sources = [ "policy_unittest.mm" ] + sources = [ + "browser_dm_token_storage_ios_unittest.mm", + "policy_unittest.mm", + ] deps = [ ":policy", ":test_resources",
diff --git a/ios/chrome/browser/policy/browser_dm_token_storage_ios.h b/ios/chrome/browser/policy/browser_dm_token_storage_ios.h index a3db721..1ace781 100644 --- a/ios/chrome/browser/policy/browser_dm_token_storage_ios.h +++ b/ios/chrome/browser/policy/browser_dm_token_storage_ios.h
@@ -38,6 +38,12 @@ scoped_refptr<base::TaskRunner> SaveDMTokenTaskRunner() override; scoped_refptr<base::TaskRunner> task_runner_; + + FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageIOSTest, InitClientId); + FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageIOSTest, InitEnrollmentToken); + FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageIOSTest, StoreAndLoadDMToken); + FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageIOSTest, + InitDMTokenWithoutDirectory); }; } // namespace policy
diff --git a/ios/chrome/browser/policy/browser_dm_token_storage_ios_unittest.mm b/ios/chrome/browser/policy/browser_dm_token_storage_ios_unittest.mm new file mode 100644 index 0000000..3faa434b --- /dev/null +++ b/ios/chrome/browser/policy/browser_dm_token_storage_ios_unittest.mm
@@ -0,0 +1,147 @@ +// 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 "ios/chrome/browser/policy/browser_dm_token_storage_ios.h" + +#import <Foundation/Foundation.h> + +#include "base/base64url.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/hash/sha1.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#include "base/strings/sys_string_conversions.h" +#include "base/task_runner_util.h" +#include "base/test/scoped_path_override.h" +#include "base/test/task_environment.h" +#import "components/policy/core/common/policy_loader_ios_constants.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace policy { + +namespace { + +const char kDMToken[] = "fake-dm-token"; +const char kDmTokenBaseDir[] = + FILE_PATH_LITERAL("Google/Chrome Cloud Enrollment/"); +const char kEnrollmentToken[] = "fake-enrollment-token"; +const char kEnrollmentTokenPolicyName[] = "CloudManagementEnrollmentToken"; + +} // namespace + +class BrowserDMTokenStorageIOSTest : public PlatformTest { + private: + base::test::TaskEnvironment task_environment_; +}; + +class TestStoreDMTokenDelegate { + public: + TestStoreDMTokenDelegate() : called_(false), success_(true) {} + ~TestStoreDMTokenDelegate() {} + + void OnDMTokenStored(bool success) { + run_loop_.Quit(); + called_ = true; + success_ = success; + } + + bool WasCalled() { + bool was_called = called_; + called_ = false; + return was_called; + } + + bool success() { return success_; } + + void Wait() { run_loop_.Run(); } + + private: + bool called_; + bool success_; + base::RunLoop run_loop_; +}; + +TEST_F(BrowserDMTokenStorageIOSTest, InitClientId) { + BrowserDMTokenStorageIOS storage; + EXPECT_FALSE(storage.InitClientId().empty()); +} + +TEST_F(BrowserDMTokenStorageIOSTest, InitEnrollmentToken) { + BrowserDMTokenStorageIOS storage; + EXPECT_TRUE(storage.InitEnrollmentToken().empty()); + + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + NSDictionary* testing_policies = @{ + base::SysUTF8ToNSString(kEnrollmentTokenPolicyName) : + base::SysUTF8ToNSString(kEnrollmentToken) + }; + NSDictionary* registration_defaults = + @{kPolicyLoaderIOSConfigurationKey : testing_policies}; + [defaults registerDefaults:registration_defaults]; + + EXPECT_EQ(kEnrollmentToken, storage.InitEnrollmentToken()); +} + +TEST_F(BrowserDMTokenStorageIOSTest, StoreAndLoadDMToken) { + std::unique_ptr<base::ScopedPathOverride> path_override; + base::ScopedTempDir fake_app_data_dir; + + ASSERT_TRUE(fake_app_data_dir.CreateUniqueTempDir()); + path_override.reset(new base::ScopedPathOverride( + base::DIR_APP_DATA, fake_app_data_dir.GetPath())); + + TestStoreDMTokenDelegate callback_delegate; + BrowserDMTokenStorageIOS storage_delegate; + auto task = storage_delegate.SaveDMTokenTask(kDMToken, + storage_delegate.InitClientId()); + auto reply = base::BindOnce(&TestStoreDMTokenDelegate::OnDMTokenStored, + base::Unretained(&callback_delegate)); + base::PostTaskAndReplyWithResult( + storage_delegate.SaveDMTokenTaskRunner().get(), FROM_HERE, + std::move(task), std::move(reply)); + + callback_delegate.Wait(); + ASSERT_TRUE(callback_delegate.success()); + + base::FilePath app_data_dir_path; + ASSERT_TRUE(base::PathService::Get(base::DIR_APP_DATA, &app_data_dir_path)); + base::FilePath dm_token_dir_path = app_data_dir_path.Append(kDmTokenBaseDir); + + std::string filename; + base::Base64UrlEncode(base::SHA1HashString(storage_delegate.InitClientId()), + base::Base64UrlEncodePolicy::OMIT_PADDING, &filename); + + base::FilePath dm_token_file_path = dm_token_dir_path.Append(filename); + + std::string dm_token; + ASSERT_TRUE(base::ReadFileToString(dm_token_file_path, &dm_token)); + EXPECT_EQ(kDMToken, dm_token); + EXPECT_EQ(kDMToken, storage_delegate.InitDMToken()); +} + +TEST_F(BrowserDMTokenStorageIOSTest, InitDMTokenWithoutDirectory) { + std::unique_ptr<base::ScopedPathOverride> path_override; + base::ScopedTempDir fake_app_data_dir; + + ASSERT_TRUE(fake_app_data_dir.CreateUniqueTempDir()); + path_override.reset(new base::ScopedPathOverride( + base::DIR_APP_DATA, fake_app_data_dir.GetPath())); + + TestStoreDMTokenDelegate delegate; + BrowserDMTokenStorageIOS storage; + + base::FilePath dm_token_dir_path = + fake_app_data_dir.GetPath().Append(kDmTokenBaseDir); + + EXPECT_EQ(std::string(), storage.InitDMToken()); + EXPECT_FALSE(base::PathExists(dm_token_dir_path)); +} + +} // namespace policy
diff --git a/ios/chrome/browser/safe_browsing/BUILD.gn b/ios/chrome/browser/safe_browsing/BUILD.gn index 45452191..73d5d3ac 100644 --- a/ios/chrome/browser/safe_browsing/BUILD.gn +++ b/ios/chrome/browser/safe_browsing/BUILD.gn
@@ -58,6 +58,7 @@ "//ios/chrome/browser/sync", "//ios/components/security_interstitials", "//ios/net", + "//ios/web/common:user_agent", "//ios/web/public", "//ios/web/public/init", "//mojo/public/cpp/bindings",
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm b/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm index ee1ae18..c91a2333 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_service_impl.mm
@@ -22,8 +22,10 @@ #import "ios/chrome/browser/safe_browsing/real_time_url_lookup_service_factory.h" #import "ios/chrome/browser/safe_browsing/url_checker_delegate_impl.h" #import "ios/net/cookies/system_cookie_store.h" +#import "ios/web/common/user_agent.h" #include "ios/web/public/thread/web_task_traits.h" #include "ios/web/public/thread/web_thread.h" +#import "ios/web/public/web_client.h" #import "ios/web/public/web_state.h" #include "net/cookies/cookie_store.h" #include "net/url_request/url_request_context.h" @@ -242,6 +244,8 @@ /*system_cookie_store=*/nullptr, net::NetLog::Get()); builder.SetCookieStore(std::move(cookie_store)); + builder.set_user_agent( + web::GetWebClient()->GetUserAgent(web::UserAgentType::MOBILE)); url_request_context_ = builder.Build(); }
diff --git a/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm b/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm index 132daac..e8e2175 100644 --- a/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm +++ b/ios/chrome/browser/safe_browsing/safe_browsing_service_unittest.mm
@@ -417,6 +417,32 @@ run_loop5.Run(); } +// Verfies that http requests sent by SafeBrowsingServiceImpl's network context +// have a non-empty User-Agent header. +TEST_F(SafeBrowsingServiceTest, NonEmptyUserAgent) { + net::EmbeddedTestServer server(net::EmbeddedTestServer::TYPE_HTTPS); + net::test_server::RegisterDefaultHandlers(&server); + ASSERT_TRUE(server.Start()); + std::unique_ptr<network::ResourceRequest> resource_request = + std::make_unique<network::ResourceRequest>(); + + // Ask the server to echo the User-Agent header and verify that the echoed + // value is non-empty. + resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = server.GetURL("/echoheader?User-Agent"); + std::unique_ptr<network::SimpleURLLoader> url_loader = + network::SimpleURLLoader::Create(std::move(resource_request), + TRAFFIC_ANNOTATION_FOR_TESTS); + base::RunLoop run_loop; + url_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + safe_browsing_service_->GetURLLoaderFactory().get(), + base::BindLambdaForTesting([&](std::unique_ptr<std::string> body) { + EXPECT_FALSE(body->empty()); + run_loop.Quit(); + })); + run_loop.Run(); +} + using SafeBrowsingServiceInitializationTest = PlatformTest; // Verifies that GetURLLoaderFactory() has a non-null return value when called
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm index fa401e89..e22026e 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/fallback_coordinator_egtest.mm
@@ -451,7 +451,8 @@ } // Tests that the manual fallback view is present in incognito. -- (void)testIncognitoManualFallbackMenu { +// Disabled due to flakiness. See crbug.com/1115321. +- (void)DISABLED_testIncognitoManualFallbackMenu { // Add the profile to use for verification. [AutofillAppInterface saveExampleProfile]; @@ -560,7 +561,8 @@ } // Tests that the manual fallback view is not duplicated after incognito. -- (void)testReturningFromIncognitoDoesNotDuplicatesManualFallbackMenu { +// Disabled due to flakiness. See crbug.com/1115282. +- (void)DISABLED_testReturningFromIncognitoDoesNotDuplicatesManualFallbackMenu { // Add the profile to use for verification. [AutofillAppInterface saveExampleProfile];
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 7812447..cd4caa5 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -2995,7 +2995,9 @@ if (isLink) { base::RecordAction( base::UserMetricsAction("MobileWebContextMenuLinkImpression")); - if (link.SchemeIs(url::kJavaScriptScheme)) { + // Only show the "Open" item for Javascript coming from the main frame since + // it can't be executed on a child frame. + if (link.SchemeIs(url::kJavaScriptScheme) && params.is_main_frame) { // Open title = l10n_util::GetNSStringWithFixup(IDS_IOS_CONTENT_CONTEXT_OPEN); action = ^{
diff --git a/ios/chrome/browser/ui/whats_new/default_browser_utils.h b/ios/chrome/browser/ui/whats_new/default_browser_utils.h index c85c0ac..c692327 100644 --- a/ios/chrome/browser/ui/whats_new/default_browser_utils.h +++ b/ios/chrome/browser/ui/whats_new/default_browser_utils.h
@@ -5,10 +5,20 @@ #ifndef IOS_CHROME_BROWSER_UI_WHATS_NEW_DEFAULT_BROWSER_UTILS_H_ #define IOS_CHROME_BROWSER_UI_WHATS_NEW_DEFAULT_BROWSER_UTILS_H_ +#import <UIKit/UIKit.h> + +// UserDefaults key that saves the last time an HTTP(S) link was sent and opened +// by the app. +extern NSString* const kLastHTTPURLOpenTime; + // Logs the timestamp of user activity that is deemed to be an indication of // a user that would likely benefit from having Chrome set as their default // browser. Before logging the current activity, this method will also clear all // past expired logs that have happened too far in the past. void LogLikelyInterestedDefaultBrowserUserActivity(); +// Returns True if the last URL open is within the time threshold that would +// indicate Chrome is likely still the default browser. Returns False otherwise. +bool IsChromeLikelyDefaultBrowser(); + #endif // IOS_CHROME_BROWSER_UI_WHATS_NEW_DEFAULT_BROWSER_UTILS_H_
diff --git a/ios/chrome/browser/ui/whats_new/default_browser_utils.mm b/ios/chrome/browser/ui/whats_new/default_browser_utils.mm index 4ca2621..e1afa64 100644 --- a/ios/chrome/browser/ui/whats_new/default_browser_utils.mm +++ b/ios/chrome/browser/ui/whats_new/default_browser_utils.mm
@@ -16,8 +16,13 @@ // Time threshold before activity timestamps should be removed. Currently set to // seven days. const NSTimeInterval kUserActivityTimestampExpiration = 7 * 24 * 60 * 60; +// Time threshold for the last URL open before no URL opens likely indicates +// Chrome is no longer the default browser. +const NSTimeInterval kLatestURLOpenForDefaultBrowser = 7 * 24 * 60 * 60; } +NSString* const kLastHTTPURLOpenTime = @"lastHTTPURLOpenTime"; + void LogLikelyInterestedDefaultBrowserUserActivity() { NSMutableArray<NSDate*>* pastUserEvents = [[[NSUserDefaults standardUserDefaults] @@ -42,3 +47,18 @@ [[NSUserDefaults standardUserDefaults] setObject:pastUserEvents forKey:kLastSignificantUserEvent]; } + +bool IsChromeLikelyDefaultBrowser() { + NSDate* lastURLOpen = + [[NSUserDefaults standardUserDefaults] objectForKey:kLastHTTPURLOpenTime]; + if (!lastURLOpen) { + return false; + } + + NSDate* sevenDaysAgoDate = + [NSDate dateWithTimeIntervalSinceNow:-kLatestURLOpenForDefaultBrowser]; + if ([lastURLOpen laterDate:sevenDaysAgoDate] == sevenDaysAgoDate) { + return false; + } + return true; +}
diff --git a/ios/web/public/ui/context_menu_params.h b/ios/web/public/ui/context_menu_params.h index 9533e71..3415c5b 100644 --- a/ios/web/public/ui/context_menu_params.h +++ b/ios/web/public/ui/context_menu_params.h
@@ -19,6 +19,9 @@ ContextMenuParams(const ContextMenuParams& other); ~ContextMenuParams(); + // Whether or not the context menu was triggered from the main frame. + bool is_main_frame; + // The title of the menu. NSString* menu_title;
diff --git a/ios/web/web_state/context_menu_params.mm b/ios/web/web_state/context_menu_params.mm index 2d0300cf..9b77893 100644 --- a/ios/web/web_state/context_menu_params.mm +++ b/ios/web/web_state/context_menu_params.mm
@@ -11,7 +11,9 @@ namespace web { ContextMenuParams::ContextMenuParams() - : referrer_policy(ReferrerPolicyDefault), location(CGPointZero) {} + : is_main_frame(true), + referrer_policy(ReferrerPolicyDefault), + location(CGPointZero) {} ContextMenuParams::ContextMenuParams(const ContextMenuParams& other) = default;
diff --git a/ios/web/web_state/context_menu_params_utils_unittest.mm b/ios/web/web_state/context_menu_params_utils_unittest.mm index 059ed26..b7cf411 100644 --- a/ios/web/web_state/context_menu_params_utils_unittest.mm +++ b/ios/web/web_state/context_menu_params_utils_unittest.mm
@@ -41,6 +41,7 @@ // Tests the empty contructor. TEST_F(ContextMenuParamsUtilsTest, EmptyParams) { web::ContextMenuParams params; + EXPECT_TRUE(params.is_main_frame); EXPECT_EQ(params.menu_title, nil); EXPECT_FALSE(params.link_url.is_valid()); EXPECT_FALSE(params.src_url.is_valid()); @@ -60,6 +61,7 @@ kContextMenuElementInnerText : @(kLinkText), }); + EXPECT_TRUE(params.is_main_frame); EXPECT_NSEQ(params.menu_title, @(kTitle)); EXPECT_EQ(params.link_url, GURL(kLinkUrl)); EXPECT_EQ(params.src_url, GURL(kSrcUrl));
diff --git a/ios/web/web_state/ui/crw_context_menu_controller.mm b/ios/web/web_state/ui/crw_context_menu_controller.mm index 198d678..c11b31af 100644 --- a/ios/web/web_state/ui/crw_context_menu_controller.mm +++ b/ios/web/web_state/ui/crw_context_menu_controller.mm
@@ -415,6 +415,7 @@ _contextMenuInfoForLastTouch.dom_element); params.view = _webView; params.location = _contextMenuInfoForLastTouch.location; + params.is_main_frame = _contextMenuInfoForLastTouch.is_main_frame; [_delegate webView:_webView handleContextMenu:params]; }
diff --git a/ios/web/web_state/web_state_delegate_bridge_unittest.mm b/ios/web/web_state/web_state_delegate_bridge_unittest.mm index f5af0987..89f1cb19 100644 --- a/ios/web/web_state/web_state_delegate_bridge_unittest.mm +++ b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
@@ -109,6 +109,7 @@ TEST_F(WebStateDelegateBridgeTest, HandleContextMenu) { EXPECT_EQ(nil, [delegate_ contextMenuParams]); web::ContextMenuParams context_menu_params; + context_menu_params.is_main_frame = false; context_menu_params.menu_title = [@"Menu title" copy]; context_menu_params.link_url = GURL("http://www.url.com"); context_menu_params.src_url = GURL("http://www.url.com/image.jpeg"); @@ -119,6 +120,7 @@ web::ContextMenuParams* result_params = [delegate_ contextMenuParams]; EXPECT_NE(nullptr, result_params); EXPECT_EQ(context_menu_params.menu_title, result_params->menu_title); + EXPECT_EQ(context_menu_params.is_main_frame, result_params->is_main_frame); EXPECT_EQ(context_menu_params.link_url, result_params->link_url); EXPECT_EQ(context_menu_params.src_url, result_params->src_url); EXPECT_EQ(context_menu_params.referrer_policy,
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index cd79bde..325a678 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn
@@ -384,6 +384,7 @@ sources += [ "user_input_monitor_linux.cc" ] deps += [ "//ui/events:events_base", + "//ui/events/devices/x11", "//ui/gfx/x", ] } else if (is_mac) {
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 124c37c..15b1bdd6 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -636,6 +636,11 @@ #endif // defined(OS_WIN) +#if defined(OS_MAC) +const base::Feature MEDIA_EXPORT kVideoToolboxVp9Decoding{ + "VideoToolboxVp9Decoding", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif // defined(OS_MAC) + std::string GetEffectiveAutoplayPolicy(const base::CommandLine& command_line) { // Return the autoplay policy set in the command line, if any. if (command_line.HasSwitch(switches::kAutoplayPolicy))
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 905240b7..e898c23 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -214,6 +214,10 @@ MEDIA_EXPORT extern const base::Feature kMediaFoundationVP8Decoding; #endif // defined(OS_WIN) +#if defined(OS_MAC) +MEDIA_EXPORT extern const base::Feature kVideoToolboxVp9Decoding; +#endif + // Based on a |command_line| and the current platform, returns the effective // autoplay policy. In other words, it will take into account the default policy // if none is specified via the command line and options passed for testing.
diff --git a/media/base/status_codes.h b/media/base/status_codes.h index a2eb4108..87ee61e 100644 --- a/media/base/status_codes.h +++ b/media/base/status_codes.h
@@ -101,6 +101,20 @@ kEncoderInitializationError = 0x00000607, kEncoderFailedFlush = 0x00000608, + // VaapiVideoDecoder: 0x07 + kVaapiBadContext = 0x00000701, + kVaapiNoBuffer = 0x00000702, + kVaapiNoBufferHandle = 0x00000703, + kVaapiNoPixmap = 0x00000704, + kVaapiNoImage = 0x00000705, + kVaapiNoSurface = 0x00000706, + kVaapiFailedToInitializeImage = 0x00000707, + kVaapiFailedToBindTexture = 0x00000708, + kVaapiFailedToBindImage = 0x00000709, + kVaapiUnsupportedFormat = 0x0000070A, + kVaapiFailedToExportImage = 0x0000070B, + kVaapiBadImageSize = 0x0000070C, + // Special codes kGenericErrorPleaseRemove = 0x79999999, kCodeOnlyForTesting = std::numeric_limits<StatusCodeType>::max(),
diff --git a/media/base/user_input_monitor_linux.cc b/media/base/user_input_monitor_linux.cc index 7cd7cd51..2484b834 100644 --- a/media/base/user_input_monitor_linux.cc +++ b/media/base/user_input_monitor_linux.cc
@@ -21,9 +21,11 @@ #include "base/task/current_thread.h" #include "media/base/keyboard_event_counter.h" #include "third_party/skia/include/core/SkPoint.h" +#include "ui/events/devices/x11/xinput_util.h" #include "ui/events/keycodes/keyboard_code_conversion_x.h" #include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_types.h" +#include "ui/gfx/x/xinput.h" namespace media { namespace { @@ -32,26 +34,27 @@ // UserInputMonitorLinux since it needs to be deleted on the IO thread. class UserInputMonitorLinuxCore : public base::SupportsWeakPtr<UserInputMonitorLinuxCore>, - public base::CurrentThread::DestructionObserver { + public base::CurrentThread::DestructionObserver, + public x11::Connection::Delegate { public: explicit UserInputMonitorLinuxCore( const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner); ~UserInputMonitorLinuxCore() override; - // DestructionObserver overrides. + // base::CurrentThread::DestructionObserver: void WillDestroyCurrentMessageLoop() override; + // x11::Connection::Delegate: + bool ShouldContinueStream() const override; + void DispatchXEvent(x11::Event* event) override; + uint32_t GetKeyPressCount() const; void StartMonitor(); void StartMonitorWithMapping(base::WritableSharedMemoryMapping mapping); void StopMonitor(); private: - void OnXEvent(); - - // Processes key events. - void ProcessXEvent(xEvent* event); - static void ProcessReply(XPointer self, XRecordInterceptData* data); + void OnConnectionData(); scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; @@ -62,10 +65,7 @@ // The following members should only be accessed on the IO thread. // std::unique_ptr<base::FileDescriptorWatcher::Controller> watch_controller_; - Display* x_control_display_; - Display* x_record_display_; - XRecordRange* x_record_range_; - XRecordContext x_record_context_; + std::unique_ptr<x11::Connection> connection_; KeyboardEventCounter counter_; DISALLOW_COPY_AND_ASSIGN(UserInputMonitorLinuxCore); @@ -95,17 +95,10 @@ UserInputMonitorLinuxCore::UserInputMonitorLinuxCore( const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) - : io_task_runner_(io_task_runner), - x_control_display_(nullptr), - x_record_display_(nullptr), - x_record_range_(nullptr), - x_record_context_(0) {} + : io_task_runner_(io_task_runner) {} UserInputMonitorLinuxCore::~UserInputMonitorLinuxCore() { - DCHECK(!x_control_display_); - DCHECK(!x_record_display_); - DCHECK(!x_record_range_); - DCHECK(!x_record_context_); + DCHECK(!connection_); } void UserInputMonitorLinuxCore::WillDestroyCurrentMessageLoop() { @@ -113,6 +106,32 @@ StopMonitor(); } +bool UserInputMonitorLinuxCore::ShouldContinueStream() const { + return true; +} + +void UserInputMonitorLinuxCore::DispatchXEvent(x11::Event* event) { + DCHECK(io_task_runner_->BelongsToCurrentThread()); + + auto* raw = event->As<x11::Input::RawDeviceEvent>(); + DCHECK(raw); + DCHECK(raw->opcode == x11::Input::RawDeviceEvent::RawKeyPress || + raw->opcode == x11::Input::RawDeviceEvent::RawKeyRelease); + + ui::EventType type = raw->opcode == x11::Input::RawDeviceEvent::RawKeyPress + ? ui::ET_KEY_PRESSED + : ui::ET_KEY_RELEASED; + + auto key_sym = connection_->KeycodeToKeysym(raw->detail, 0); + ui::KeyboardCode key_code = + ui::KeyboardCodeFromXKeysym(static_cast<uint32_t>(key_sym)); + counter_.OnKeyboardEvent(type, key_code); + + // Update count value in shared memory. + if (key_press_count_mapping_) + WriteKeyPressMonitorCount(*key_press_count_mapping_, GetKeyPressCount()); +} + uint32_t UserInputMonitorLinuxCore::GetKeyPressCount() const { return counter_.GetKeyPressCount(); } @@ -120,74 +139,39 @@ void UserInputMonitorLinuxCore::StartMonitor() { DCHECK(io_task_runner_->BelongsToCurrentThread()); - if (!x_control_display_ || !x_record_display_) { - // TODO(jamiewalch): We should pass the display in. - if (auto* x_display = gfx::GetXDisplay()) { - if (!x_control_display_) - x_control_display_ = gfx::CloneXDisplay(x_display); - - if (!x_record_display_) - x_record_display_ = gfx::CloneXDisplay(x_display); - } - - if (!x_control_display_ || !x_record_display_) { - LOG(ERROR) << "Couldn't open X display"; + if (!connection_) { + // TODO(jamiewalch): We should pass the connection in. + if (auto* connection = x11::Connection::Get()) { + connection_ = x11::Connection::Get()->Clone(); + } else { + LOG(ERROR) << "Couldn't open X connection"; StopMonitor(); return; } } - int xr_opcode, xr_event, xr_error; - if (!XQueryExtension(x_control_display_, "RECORD", &xr_opcode, &xr_event, - &xr_error)) { - LOG(ERROR) << "X Record extension not available."; + if (!connection_->xinput().present()) { + LOG(ERROR) << "X Input extension not available."; StopMonitor(); return; } + // Let the server know the client XInput version. + connection_->xinput().XIQueryVersion( + {x11::Input::major_version, x11::Input::minor_version}); - if (!x_record_range_) - x_record_range_ = XRecordAllocRange(); + x11::Input::XIEventMask mask; + ui::SetXinputMask(&mask, x11::Input::RawDeviceEvent::RawKeyPress); + ui::SetXinputMask(&mask, x11::Input::RawDeviceEvent::RawKeyRelease); + connection_->xinput().XISelectEvents( + {connection_->default_root(), + {{x11::Input::DeviceId::AllMaster, {mask}}}}); + connection_->Flush(); - if (!x_record_range_) { - LOG(ERROR) << "XRecordAllocRange failed."; - StopMonitor(); - return; - } - - x_record_range_->device_events.first = x11::KeyEvent::Press; - x_record_range_->device_events.last = x11::KeyEvent::Release; - - if (x_record_context_) { - XRecordDisableContext(x_control_display_, x_record_context_); - XFlush(x_control_display_); - XRecordFreeContext(x_record_display_, x_record_context_); - x_record_context_ = 0; - } - int number_of_ranges = 1; - - XRecordClientSpec client_spec = XRecordAllClients; - x_record_context_ = - XRecordCreateContext(x_record_display_, 0, &client_spec, 1, - &x_record_range_, number_of_ranges); - if (!x_record_context_) { - LOG(ERROR) << "XRecordCreateContext failed."; - StopMonitor(); - return; - } - - if (!XRecordEnableContextAsync(x_record_display_, x_record_context_, - &UserInputMonitorLinuxCore::ProcessReply, - reinterpret_cast<XPointer>(this))) { - LOG(ERROR) << "XRecordEnableContextAsync failed."; - StopMonitor(); - return; - } - - // Register OnXEvent() to be called every time there is something to read - // from |x_record_display_|. + // Register OnConnectionData() to be called every time there is something to + // read from |connection_|. watch_controller_ = base::FileDescriptorWatcher::WatchReadable( - ConnectionNumber(x_record_display_), - base::BindRepeating(&UserInputMonitorLinuxCore::OnXEvent, + ConnectionNumber(connection_->display()), + base::BindRepeating(&UserInputMonitorLinuxCore::OnConnectionData, base::Unretained(this))); // Start observing message loop destruction if we start monitoring the first @@ -195,7 +179,7 @@ base::CurrentThread::Get()->AddDestructionObserver(this); // Fetch pending events if any. - OnXEvent(); + OnConnectionData(); } void UserInputMonitorLinuxCore::StartMonitorWithMapping( @@ -208,72 +192,17 @@ void UserInputMonitorLinuxCore::StopMonitor() { DCHECK(io_task_runner_->BelongsToCurrentThread()); - if (x_record_range_) { - XFree(x_record_range_); - x_record_range_ = nullptr; - } - - // Context must be disabled via the control channel because we can't send - // any X protocol traffic over the data channel while it's recording. - if (x_record_context_) { - XRecordDisableContext(x_control_display_, x_record_context_); - XFlush(x_control_display_); - XRecordFreeContext(x_record_display_, x_record_context_); - x_record_context_ = 0; - - watch_controller_.reset(); - } - if (x_record_display_) { - XCloseDisplay(x_record_display_); - x_record_display_ = nullptr; - } - if (x_control_display_) { - XCloseDisplay(x_control_display_); - x_control_display_ = nullptr; - } - + watch_controller_.reset(); + connection_.reset(); key_press_count_mapping_.reset(); // Stop observing message loop destruction if no event is being monitored. base::CurrentThread::Get()->RemoveDestructionObserver(this); } -void UserInputMonitorLinuxCore::OnXEvent() { +void UserInputMonitorLinuxCore::OnConnectionData() { DCHECK(io_task_runner_->BelongsToCurrentThread()); - XEvent event; - // Fetch pending events if any. - while (XPending(x_record_display_)) { - XNextEvent(x_record_display_, &event); - } -} - -void UserInputMonitorLinuxCore::ProcessXEvent(xEvent* event) { - DCHECK(io_task_runner_->BelongsToCurrentThread()); - DCHECK(event->u.u.type == x11::KeyEvent::Release || - event->u.u.type == x11::KeyEvent::Press); - - ui::EventType type = (event->u.u.type == x11::KeyEvent::Press) - ? ui::ET_KEY_PRESSED - : ui::ET_KEY_RELEASED; - - KeySym key_sym = - XkbKeycodeToKeysym(x_control_display_, event->u.u.detail, 0, 0); - ui::KeyboardCode key_code = ui::KeyboardCodeFromXKeysym(key_sym); - counter_.OnKeyboardEvent(type, key_code); - - // Update count value in shared memory. - if (key_press_count_mapping_) - WriteKeyPressMonitorCount(*key_press_count_mapping_, GetKeyPressCount()); -} - -// static -void UserInputMonitorLinuxCore::ProcessReply(XPointer self, - XRecordInterceptData* data) { - if (data->category == XRecordFromServer) { - xEvent* event = reinterpret_cast<xEvent*>(data->data); - reinterpret_cast<UserInputMonitorLinuxCore*>(self)->ProcessXEvent(event); - } - XRecordFreeData(data); + connection_->Dispatch(this); } //
diff --git a/media/cast/sender/congestion_control.cc b/media/cast/sender/congestion_control.cc index fb89ee0..9385627 100644 --- a/media/cast/sender/congestion_control.cc +++ b/media/cast/sender/congestion_control.cc
@@ -209,15 +209,15 @@ double AdaptiveCongestionControl::CalculateSafeBitrate() { DCHECK(!frame_stats_.empty()); - const double transmit_time = - (GetFrameStats(last_checkpoint_frame_)->ack_time - - frame_stats_.front().enqueue_time - dead_time_in_history_) - .InSecondsF(); + base::TimeDelta transmit_time = + GetFrameStats(last_checkpoint_frame_)->ack_time - + frame_stats_.front().enqueue_time - dead_time_in_history_; - if (acked_bits_in_history_ == 0 || transmit_time <= 0.0) { + if (acked_bits_in_history_ == 0 || transmit_time <= base::TimeDelta()) { return min_bitrate_configured_; } - return acked_bits_in_history_ / std::max(transmit_time, 1E-3); + transmit_time = std::max(transmit_time, base::TimeDelta::FromMilliseconds(1)); + return acked_bits_in_history_ / transmit_time.InSecondsF(); } AdaptiveCongestionControl::FrameStats* AdaptiveCongestionControl::GetFrameStats(
diff --git a/media/cast/test/simulator.cc b/media/cast/test/simulator.cc index 18683c54..bd91344 100644 --- a/media/cast/test/simulator.cc +++ b/media/cast/test/simulator.cc
@@ -529,12 +529,15 @@ // Subtract fraction of dropped frames from |elapsed_time| before estimating // the average encoded bitrate. const base::TimeDelta elapsed_time_undropped = - total_video_frames <= 0 ? base::TimeDelta() : - (elapsed_time * (total_video_frames - dropped_video_frames) / - total_video_frames); + total_video_frames <= 0 + ? base::TimeDelta() + : (elapsed_time * (total_video_frames - dropped_video_frames) / + total_video_frames); + constexpr double kKilobitsPerByte = 8.0 / 1000; const double avg_encoded_bitrate = - elapsed_time_undropped <= base::TimeDelta() ? 0 : - 8.0 * encoded_size / elapsed_time_undropped.InSecondsF() / 1000; + elapsed_time_undropped <= base::TimeDelta() + ? 0 + : encoded_size * kKilobitsPerByte * elapsed_time_undropped.ToHz(); double avg_target_bitrate = !encoded_video_frames ? 0 : target_bitrate / encoded_video_frames / 1000;
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index b955f6e..8e73fce 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc
@@ -1222,11 +1222,8 @@ return 0; } - // Do math in floating point as we'd overflow an int64_t if the filesize was - // larger than ~1073GB. - double bytes = filesize_in_bytes; - double duration_us = duration.InMicroseconds(); - return base::ClampRound(bytes * 8000000.0 / duration_us); + // Don't multiply by 8 first; it will overflow if (filesize_in_bytes >= 2^60). + return base::ClampRound(filesize_in_bytes * duration.ToHz() * 8); } void FFmpegDemuxer::OnOpenContextDone(bool result) {
diff --git a/media/filters/video_cadence_estimator_unittest.cc b/media/filters/video_cadence_estimator_unittest.cc index c2a4e7f..f914a23 100644 --- a/media/filters/video_cadence_estimator_unittest.cc +++ b/media/filters/video_cadence_estimator_unittest.cc
@@ -400,7 +400,7 @@ estimator.UpdateCadenceEstimate(new_render_interval, frame_duration, base::TimeDelta(), base::TimeDelta())) << "render interval: " << new_render_interval - << " hz: " << (1e6 / new_render_interval.InMicrosecondsF()); + << " hz: " << new_render_interval.ToHz(); } EXPECT_TRUE(estimator.UpdateCadenceEstimate(
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index 9ed9a35..319207c 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -459,6 +459,7 @@ sources = [ "video_encode_accelerator_unittest.cc" ] if (use_x11) { deps += [ "//ui/gfx/x" ] + public_configs = [ "//build/config/linux/libva" ] } if (use_ozone) { deps += [ "//ui/ozone" ]
diff --git a/media/gpu/android/codec_image.cc b/media/gpu/android/codec_image.cc index ca4d0ed..00e047b8 100644 --- a/media/gpu/android/codec_image.cc +++ b/media/gpu/android/codec_image.cc
@@ -186,11 +186,11 @@ return output_buffer_renderer_->RenderToFrontBuffer(); } -bool CodecImage::RenderToTextureOwnerBackBuffer(BlockingMode blocking_mode) { +bool CodecImage::RenderToTextureOwnerBackBuffer() { if (!output_buffer_renderer_) return false; - return output_buffer_renderer_->RenderToTextureOwnerBackBuffer(blocking_mode); + return output_buffer_renderer_->RenderToTextureOwnerBackBuffer(); } bool CodecImage::RenderToTextureOwnerFrontBuffer(BindingsMode bindings_mode) {
diff --git a/media/gpu/android/codec_image.h b/media/gpu/android/codec_image.h index 1a16dda..d71cda8f 100644 --- a/media/gpu/android/codec_image.h +++ b/media/gpu/android/codec_image.h
@@ -31,8 +31,6 @@ class MEDIA_GPU_EXPORT CodecImage : public gpu::StreamTextureSharedImageInterface { public: - using BlockingMode = CodecOutputBufferRenderer::BlockingMode; - // Callback to notify that a codec image is now unused in the sense of not // being out for display. This lets us signal interested folks once a video // frame is destroyed and the sync token clears, so that that CodecImage may @@ -134,11 +132,9 @@ // Renders this image to the back buffer of its texture owner. Only valid if // is_texture_owner_backed(). Returns true if the buffer is in the back // buffer. Returns false if the buffer was invalidated. - // |blocking_mode| indicates whether this should (a) wait for any previously - // pending rendered frame before rendering this one, or (b) fail if a wait - // is required. - bool RenderToTextureOwnerBackBuffer( - BlockingMode blocking_mode = BlockingMode::kAllowBlocking); + // RenderToTextureOwnerBackBuffer() will not block if there is any previously + // pending frame and will return false in this case. + bool RenderToTextureOwnerBackBuffer(); // Release any codec buffer without rendering, if we have one. virtual void ReleaseCodecBuffer();
diff --git a/media/gpu/android/codec_output_buffer_renderer.cc b/media/gpu/android/codec_output_buffer_renderer.cc index 57f32ea..ed08fb6 100644 --- a/media/gpu/android/codec_output_buffer_renderer.cc +++ b/media/gpu/android/codec_output_buffer_renderer.cc
@@ -7,6 +7,7 @@ #include "base/android/scoped_hardware_buffer_fence_sync.h" #include "base/bind_helpers.h" +#include "base/optional.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/texture_manager.h" #include "ui/gl/gl_context.h" @@ -37,6 +38,19 @@ return scoped_current; } +class ScopedRestoreTextureBinding { + public: + ScopedRestoreTextureBinding() { + glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id_); + } + ~ScopedRestoreTextureBinding() { + glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id_); + } + + private: + GLint bound_service_id_; +}; + } // namespace CodecOutputBufferRenderer::CodecOutputBufferRenderer( @@ -49,8 +63,7 @@ CodecOutputBufferRenderer::~CodecOutputBufferRenderer() = default; -bool CodecOutputBufferRenderer::RenderToTextureOwnerBackBuffer( - BlockingMode blocking_mode) { +bool CodecOutputBufferRenderer::RenderToTextureOwnerBackBuffer() { DCHECK_NE(phase_, Phase::kInFrontBuffer); if (phase_ == Phase::kInBackBuffer) return true; @@ -65,12 +78,10 @@ if (!codec_buffer_wait_coordinator_) return false; - // Wait for a previous frame available so we don't confuse it with the one - // we're about to release. + // Don't render frame if one is already pending. + // RenderToTextureOwnerFrontBuffer will wait before calling this. if (codec_buffer_wait_coordinator_->IsExpectingFrameAvailable()) { - if (blocking_mode == BlockingMode::kForbidBlocking) - return false; - codec_buffer_wait_coordinator_->WaitForFrameAvailable(); + return false; } if (!output_buffer_->ReleaseToSurface()) { phase_ = Phase::kInvalidated; @@ -98,32 +109,45 @@ if (phase_ == Phase::kInvalidated) return false; + std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current = + MakeCurrentIfNeeded( + codec_buffer_wait_coordinator_->texture_owner().get()); + // If updating the image will implicitly update the texture bindings then + // restore if requested or the update needed a context switch. + base::Optional<ScopedRestoreTextureBinding> scoped_restore_texture; + if (codec_buffer_wait_coordinator_->texture_owner() + ->binds_texture_on_update() && + (bindings_mode == BindingsMode::kRestoreIfBound || + !!scoped_make_current)) { + scoped_restore_texture.emplace(); + } + // Render it to the back buffer if it's not already there. - if (!RenderToTextureOwnerBackBuffer()) - return false; + if (phase_ != Phase::kInBackBuffer) { + // Wait for a previous frame available so we don't confuse it with the one + // we're about to render. + if (codec_buffer_wait_coordinator_->IsExpectingFrameAvailable()) { + codec_buffer_wait_coordinator_->WaitForFrameAvailable(); + + // We must call update tex image if we did get OnFrameAvailable, otherwise + // we will stop receiving callbacks (see https://crbug.com/c/1113203) + codec_buffer_wait_coordinator_->texture_owner()->UpdateTexImage(); + } + if (!RenderToTextureOwnerBackBuffer()) { + // RenderTotextureOwnerBackBuffer can fail now only if ReleaseToSurface + // failed. + DCHECK(phase_ == Phase::kInvalidated); + return false; + } + } // The image is now in the back buffer, so promote it to the front buffer. phase_ = Phase::kInFrontBuffer; if (codec_buffer_wait_coordinator_->IsExpectingFrameAvailable()) codec_buffer_wait_coordinator_->WaitForFrameAvailable(); - std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current = - MakeCurrentIfNeeded( - codec_buffer_wait_coordinator_->texture_owner().get()); - // If updating the image will implicitly update the texture bindings then - // restore if requested or the update needed a context switch. - bool should_restore_bindings = - codec_buffer_wait_coordinator_->texture_owner() - ->binds_texture_on_update() && - (bindings_mode == BindingsMode::kRestoreIfBound || !!scoped_make_current); - - GLint bound_service_id = 0; - if (should_restore_bindings) - glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &bound_service_id); codec_buffer_wait_coordinator_->texture_owner()->UpdateTexImage(); EnsureBoundIfNeeded(bindings_mode); - if (should_restore_bindings) - glBindTexture(GL_TEXTURE_EXTERNAL_OES, bound_service_id); return true; }
diff --git a/media/gpu/android/codec_output_buffer_renderer.h b/media/gpu/android/codec_output_buffer_renderer.h index 9984ba6c..d809960a 100644 --- a/media/gpu/android/codec_output_buffer_renderer.h +++ b/media/gpu/android/codec_output_buffer_renderer.h
@@ -22,8 +22,6 @@ class MEDIA_GPU_EXPORT CodecOutputBufferRenderer { public: using BindingsMode = gpu::StreamTextureSharedImageInterface::BindingsMode; - // Whether RenderToTextureOwnerBackBuffer may block or not. - enum class BlockingMode { kForbidBlocking, kAllowBlocking }; CodecOutputBufferRenderer( std::unique_ptr<CodecOutputBuffer> output_buffer, @@ -52,11 +50,9 @@ // Renders this image to the back buffer of its texture owner. Only valid if // is_texture_owner_backed(). Returns true if the buffer is in the back // buffer. Returns false if the buffer was invalidated. - // |blocking_mode| indicates whether this should (a) wait for any previously - // pending rendered frame before rendering this one, or (b) fail if a wait - // is required. - bool RenderToTextureOwnerBackBuffer( - BlockingMode blocking_mode = BlockingMode::kAllowBlocking); + // RenderToTextureOwnerBackBuffer() will not block if there is any previously + // pending frame and will return false in this case. + bool RenderToTextureOwnerBackBuffer(); // Whether the codec buffer has been rendered to the front buffer. bool was_rendered_to_front_buffer() const {
diff --git a/media/gpu/android/maybe_render_early_manager.h b/media/gpu/android/maybe_render_early_manager.h index 1e06d8de..de26f8e2 100644 --- a/media/gpu/android/maybe_render_early_manager.h +++ b/media/gpu/android/maybe_render_early_manager.h
@@ -90,8 +90,7 @@ // Try to render to the back buffer, but don't wait for any previous frame. // While this does make it more likely that we'll have to wait the next time // we draw, it does prevent us from waiting on frames we don't plan to draw. - images[back_buffer_index]->RenderToTextureOwnerBackBuffer( - CodecImage::BlockingMode::kForbidBlocking); + images[back_buffer_index]->RenderToTextureOwnerBackBuffer(); } }
diff --git a/media/gpu/android/maybe_render_early_manager_unittest.cc b/media/gpu/android/maybe_render_early_manager_unittest.cc index 9d830b9..66df21a 100644 --- a/media/gpu/android/maybe_render_early_manager_unittest.cc +++ b/media/gpu/android/maybe_render_early_manager_unittest.cc
@@ -35,20 +35,17 @@ } if (expectation == kRenderToBackBuffer) { - EXPECT_CALL(*this, RenderToTextureOwnerBackBuffer( - CodecImage::BlockingMode::kForbidBlocking)) + EXPECT_CALL(*this, RenderToTextureOwnerBackBuffer()) .WillOnce(Return(phase != kInvalidated)); } else { - EXPECT_CALL(*this, RenderToTextureOwnerBackBuffer( - CodecImage::BlockingMode::kForbidBlocking)) - .Times(0); + EXPECT_CALL(*this, RenderToTextureOwnerBackBuffer()).Times(0); } } MOCK_METHOD0(was_rendered_to_front_buffer, bool()); MOCK_METHOD0(is_texture_owner_backed, bool()); MOCK_METHOD0(RenderToFrontBuffer, bool()); - MOCK_METHOD1(RenderToTextureOwnerBackBuffer, bool(CodecImage::BlockingMode)); + MOCK_METHOD0(RenderToTextureOwnerBackBuffer, bool()); }; class MaybeRenderEarlyTest : public testing::Test {
diff --git a/media/gpu/mac/BUILD.gn b/media/gpu/mac/BUILD.gn index b0f318f..8a4010a 100644 --- a/media/gpu/mac/BUILD.gn +++ b/media/gpu/mac/BUILD.gn
@@ -13,6 +13,12 @@ import("//build/config/mac/mac_sdk.gni") +generate_stubs("vt_beta_stubs") { + extra_header = "vt_beta_stubs_header.fragment" + sigs = [ "vt_beta.sig" ] + output_name = "vt_beta_stubs" +} + source_set("mac") { defines = [ "MEDIA_GPU_IMPLEMENTATION" ] visibility = [ "//media/gpu" ] @@ -35,6 +41,7 @@ "VideoToolbox.framework", ] deps = [ + ":vt_beta_stubs", "//base", "//components/crash/core/common:crash_key", "//gpu/ipc/service",
diff --git a/media/gpu/mac/vt_beta.h b/media/gpu/mac/vt_beta.h new file mode 100644 index 0000000..b5a46a2 --- /dev/null +++ b/media/gpu/mac/vt_beta.h
@@ -0,0 +1,19 @@ +// 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 MEDIA_GPU_MAC_VT_BETA_H_ +#define MEDIA_GPU_MAC_VT_BETA_H_ + +// Dynamic library loader. +#include "media/gpu/mac/vt_beta_stubs.h" + +// CoreMedia and VideoToolbox types. +#include "media/gpu/mac/vt_beta_stubs_header.fragment" + +// CoreMedia and VideoToolbox functions. +extern "C" { +#include "media/gpu/mac/vt_beta.sig" +} // extern "C" + +#endif // MEDIA_GPU_MAC_VT_BETA_H_
diff --git a/media/gpu/mac/vt_beta.sig b/media/gpu/mac/vt_beta.sig new file mode 100644 index 0000000..aa18e93 --- /dev/null +++ b/media/gpu/mac/vt_beta.sig
@@ -0,0 +1,6 @@ +// 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. + +// This function isn't available until we're using the macOS 11.0 SDK. +void VTRegisterSupplementalVideoDecoderIfAvailable(CMVideoCodecType codecType);
diff --git a/media/gpu/mac/vt_beta_stubs_header.fragment b/media/gpu/mac/vt_beta_stubs_header.fragment new file mode 100644 index 0000000..87928ab --- /dev/null +++ b/media/gpu/mac/vt_beta_stubs_header.fragment
@@ -0,0 +1,5 @@ +// 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 <CoreMedia/CoreMedia.h>
diff --git a/media/gpu/mac/vt_config_util.mm b/media/gpu/mac/vt_config_util.mm index 590bdf1..2a72f649 100644 --- a/media/gpu/mac/vt_config_util.mm +++ b/media/gpu/mac/vt_config_util.mm
@@ -40,6 +40,7 @@ switch (primary_id) { case media::VideoColorSpace::PrimaryID::BT709: case media::VideoColorSpace::PrimaryID::UNSPECIFIED: // Assume BT.709. + case media::VideoColorSpace::PrimaryID::INVALID: // Assume BT.709. return kCMFormatDescriptionColorPrimaries_ITU_R_709_2; case media::VideoColorSpace::PrimaryID::BT2020: @@ -100,6 +101,7 @@ case media::VideoColorSpace::TransferID::SMPTE170M: case media::VideoColorSpace::TransferID::BT709: case media::VideoColorSpace::TransferID::UNSPECIFIED: // Assume BT.709. + case media::VideoColorSpace::TransferID::INVALID: // Assume BT.709. return kCMFormatDescriptionTransferFunction_ITU_R_709_2; case media::VideoColorSpace::TransferID::BT2020_10: @@ -145,6 +147,7 @@ switch (matrix_id) { case media::VideoColorSpace::MatrixID::BT709: case media::VideoColorSpace::MatrixID::UNSPECIFIED: // Assume BT.709. + case media::VideoColorSpace::MatrixID::INVALID: // Assume BT.709. return kCMFormatDescriptionYCbCrMatrix_ITU_R_709_2; case media::VideoColorSpace::MatrixID::BT2020_NCL:
diff --git a/media/gpu/mac/vt_video_decode_accelerator_mac.cc b/media/gpu/mac/vt_video_decode_accelerator_mac.cc index 752c358..62cc62d51 100644 --- a/media/gpu/mac/vt_video_decode_accelerator_mac.cc +++ b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
@@ -19,8 +19,10 @@ #include "base/logging.h" #include "base/mac/mac_logging.h" #include "base/mac/mac_util.h" +#include "base/mac/sdk_forward_declarations.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" +#include "base/no_destructor.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" @@ -34,6 +36,8 @@ #include "components/crash/core/common/crash_key.h" #include "media/base/limits.h" #include "media/base/media_switches.h" +#include "media/filters/vp9_parser.h" +#include "media/gpu/mac/vt_beta_stubs.h" #include "media/gpu/mac/vt_config_util.h" #include "ui/gfx/geometry/rect.h" #include "ui/gl/gl_context.h" @@ -62,6 +66,9 @@ H264PROFILE_BASELINE, H264PROFILE_EXTENDED, H264PROFILE_MAIN, H264PROFILE_HIGH, + // These are only supported on macOS 11+. + VP9PROFILE_PROFILE0, VP9PROFILE_PROFILE2, + // TODO(sandersd): Hi10p fails during // CMVideoFormatDescriptionCreateFromH264ParameterSets with // kCMFormatDescriptionError_InvalidParameter. @@ -108,15 +115,15 @@ // Build an |image_config| dictionary for VideoToolbox initialization. base::ScopedCFTypeRef<CFMutableDictionaryRef> BuildImageConfig( - CMVideoDimensions coded_dimensions) { + CMVideoDimensions coded_dimensions, + bool is_hbd) { base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config; // Note that 4:2:0 textures cannot be used directly as RGBA in OpenGL, but are // lower power than 4:2:2 when composited directly by CoreAnimation. - // - // TODO(crbug.com/1103432): Based on other > 8-bit codecs, we'll likely need - // to add kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange here. - int32_t pixel_format = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; + int32_t pixel_format = is_hbd + ? kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange + : kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange; #define CFINT(i) CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i) base::ScopedCFTypeRef<CFNumberRef> cf_pixel_format(CFINT(pixel_format)); base::ScopedCFTypeRef<CFNumberRef> cf_width(CFINT(coded_dimensions.width)); @@ -176,11 +183,35 @@ return format; } +base::ScopedCFTypeRef<CMFormatDescriptionRef> CreateVideoFormatVP9( + media::VideoColorSpace color_space, + media::VideoCodecProfile profile, + base::Optional<media::HDRMetadata> hdr_metadata, + const gfx::Size& coded_size) { + base::ScopedCFTypeRef<CFMutableDictionaryRef> format_config( + CreateFormatExtensions(kCMVideoCodecType_VP9, profile, color_space, + hdr_metadata)); + + base::ScopedCFTypeRef<CMFormatDescriptionRef> format; + if (!format_config) { + DLOG(ERROR) << "Failed to configure vp9 decoder."; + return format; + } + + OSStatus status = CMVideoFormatDescriptionCreate( + kCFAllocatorDefault, kCMVideoCodecType_VP9, coded_size.width(), + coded_size.height(), format_config, format.InitializeInto()); + OSSTATUS_DLOG_IF(WARNING, status != noErr, status) + << "CMVideoFormatDescriptionCreate()"; + return format; +} + // Create a VTDecompressionSession using the provided |format|. If // |require_hardware| is true, the session will only use the hardware decoder. bool CreateVideoToolboxSession( const CMFormatDescriptionRef format, bool require_hardware, + bool is_hbd, const VTDecompressionOutputCallbackRecord* callback, base::ScopedCFTypeRef<VTDecompressionSessionRef>* session, gfx::Size* configured_size) { @@ -211,7 +242,7 @@ CMVideoDimensions visible_dimensions = {visible_rect.size.width, visible_rect.size.height}; base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config( - BuildImageConfig(visible_dimensions)); + BuildImageConfig(visible_dimensions, is_hbd)); if (!image_config) { DLOG(ERROR) << "Failed to create decoder image configuration"; return false; @@ -254,7 +285,8 @@ const std::vector<uint8_t> pps_normal = {0x68, 0xe9, 0x7b, 0xcb}; if (!CreateVideoToolboxSession( CreateVideoFormatH264(sps_normal, std::vector<uint8_t>(), pps_normal), - /*require_hardware=*/true, &callback, &session, &configured_size)) { + /*require_hardware=*/true, /*is_hbd=*/false, &callback, &session, + &configured_size)) { DVLOG(1) << "Hardware H264 decoding with VideoToolbox is not supported"; return false; } @@ -269,11 +301,41 @@ const std::vector<uint8_t> pps_small = {0x68, 0xe9, 0x79, 0x72, 0xc0}; if (!CreateVideoToolboxSession( CreateVideoFormatH264(sps_small, std::vector<uint8_t>(), pps_small), - /*require_hardware=*/false, &callback, &session, &configured_size)) { + /*require_hardware=*/false, /*is_hbd=*/false, &callback, &session, + &configured_size)) { DVLOG(1) << "Software H264 decoding with VideoToolbox is not supported"; return false; } + session.reset(); + + if (base::mac::IsAtLeastOS11()) { + // Until our target sdk version is 11.0 we need to dynamically link the + // VTRegisterSupplementalVideoDecoderIfAvailable() symbol in. + media_gpu_mac::StubPathMap paths; + paths[media_gpu_mac::kModuleVt_beta].push_back(FILE_PATH_LITERAL( + "/System/Library/Frameworks/VideoToolbox.framework/VideoToolbox")); + if (!media_gpu_mac::InitializeStubs(paths)) + return true; // VP9 support is optional. + +// __builtin_available doesn't work for 11.0 yet; https://crbug.com/1115294 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + VTRegisterSupplementalVideoDecoderIfAvailable(kCMVideoCodecType_VP9); +#pragma clang diagnostic pop + + // Create a VP9 decoding session. + if (!CreateVideoToolboxSession( + CreateVideoFormatVP9(VideoColorSpace::REC709(), VP9PROFILE_PROFILE0, + base::nullopt, gfx::Size(720, 480)), + /*require_hardware=*/true, /*is_hbd=*/false, &callback, &session, + &configured_size)) { + DVLOG(1) << "Hardware VP9 decoding with VideoToolbox is not supported"; + + // We don't return false here since VP9 support is optional. + } + } + return true; } @@ -315,14 +377,80 @@ vda->Output(source_frame_refcon, status, image_buffer); } +void ReleaseDecoderBuffer(void* refcon, + void* doomed_memory_block, + size_t size_in_bytes) { + if (refcon) + static_cast<DecoderBuffer*>(refcon)->Release(); +} + } // namespace +// Detects coded size and color space changes. Also indicates when a frame won't +// generate any output. +class VP9ConfigChangeDetector { + public: + VP9ConfigChangeDetector() : parser_(false) {} + ~VP9ConfigChangeDetector() = default; + + void DetectConfig(const uint8_t* stream, unsigned int size) { + parser_.SetStream(stream, size, nullptr); + config_changed_ = false; + + Vp9FrameHeader fhdr; + gfx::Size allocate_size; + std::unique_ptr<DecryptConfig> null_config; + while (parser_.ParseNextFrame(&fhdr, &allocate_size, &null_config) == + Vp9Parser::kOk) { + color_space_ = fhdr.GetColorSpace(); + show_frame_ = fhdr.show_frame; + + gfx::Size new_size(fhdr.frame_width, fhdr.frame_height); + if (!size_.IsEmpty() && !pending_config_changed_ && !config_changed_ && + size_ != new_size) { + pending_config_changed_ = true; + DVLOG(1) << "Configuration changed from " << size_.ToString() << " to " + << new_size.ToString(); + } + size_ = new_size; + + // Resolution changes can happen on any frame technically, so wait for a + // keyframe before signaling the config change. + if (fhdr.IsKeyframe() && pending_config_changed_) { + config_changed_ = true; + pending_config_changed_ = false; + } + } + if (pending_config_changed_) + DVLOG(1) << "Deferring config change until next keyframe..."; + } + + gfx::Size GetCodedSize(const gfx::Size& container_coded_size) const { + return size_.IsEmpty() ? container_coded_size : size_; + } + + VideoColorSpace GetColorSpace(const VideoColorSpace& container_cs) const { + return container_cs.IsSpecified() ? container_cs : color_space_; + } + + bool show_frame() const { return show_frame_; } + bool config_changed() const { return config_changed_; } + + private: + gfx::Size size_; + bool config_changed_ = false; + bool pending_config_changed_ = false; + bool show_frame_ = false; + VideoColorSpace color_space_; + Vp9Parser parser_; +}; + bool InitializeVideoToolbox() { // InitializeVideoToolbox() is called only from the GPU process main thread: // once for sandbox warmup, and then once each time a VTVideoDecodeAccelerator // is initialized. This ensures that everything is loaded whether or not the // sandbox is enabled. - static bool succeeded = InitializeVideoToolboxInternal(); + static const bool succeeded = InitializeVideoToolboxInternal(); return succeeded; } @@ -470,8 +598,12 @@ return false; } - if (std::find(std::begin(kSupportedProfiles), std::end(kSupportedProfiles), - config.profile) == std::end(kSupportedProfiles)) { + static const base::NoDestructor<VideoDecodeAccelerator::SupportedProfiles> + kActualSupportedProfiles(GetSupportedProfiles()); + if (std::find_if(kActualSupportedProfiles->begin(), + kActualSupportedProfiles->end(), [config](const auto& p) { + return p.profile == config.profile; + }) == kActualSupportedProfiles->end()) { DVLOG(2) << "Unsupported profile"; return false; } @@ -482,6 +614,22 @@ } client_ = client; + config_ = config; + + switch (config.profile) { + case H264PROFILE_BASELINE: + case H264PROFILE_EXTENDED: + case H264PROFILE_MAIN: + case H264PROFILE_HIGH: + codec_ = kCodecH264; + break; + case VP9PROFILE_PROFILE0: + case VP9PROFILE_PROFILE2: + codec_ = kCodecVP9; + break; + default: + NOTREACHED() << "Unsupported profile."; + }; // Spawn a thread to handle parsing and calling VideoToolbox. // TODO(sandersd): This should probably use a base::ThreadPool thread instead. @@ -514,7 +662,21 @@ DVLOG(2) << __func__; DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); - auto format = CreateVideoFormatH264(active_sps_, active_spsext_, active_pps_); + base::ScopedCFTypeRef<CMFormatDescriptionRef> format; + switch (codec_) { + case kCodecH264: + format = CreateVideoFormatH264(active_sps_, active_spsext_, active_pps_); + break; + case kCodecVP9: + format = CreateVideoFormatVP9( + cc_detector_->GetColorSpace(config_.container_color_space), + config_.profile, config_.hdr_metadata, + cc_detector_->GetCodedSize(config_.initial_expected_coded_size)); + break; + default: + NOTREACHED() << "Unsupported codec."; + } + if (!format) { NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); return false; @@ -533,8 +695,10 @@ session_.reset(); // Note: We can always require hardware once Flash and PPAPI are gone. - const bool require_hardware = false; - if (!CreateVideoToolboxSession(format_, require_hardware, &callback_, + const bool require_hardware = config_.profile == VP9PROFILE_PROFILE0 || + config_.profile == VP9PROFILE_PROFILE2; + const bool is_hbd = config_.profile == VP9PROFILE_PROFILE2; + if (!CreateVideoToolboxSession(format_, require_hardware, is_hbd, &callback_, &session_, &configured_size_)) { NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); return false; @@ -559,6 +723,97 @@ return true; } +void VTVideoDecodeAccelerator::DecodeTaskVp9( + scoped_refptr<DecoderBuffer> buffer, + Frame* frame) { + DVLOG(2) << __func__ << ": bit_stream=" << frame->bitstream_id + << ", buffer=" << buffer->AsHumanReadableString(); + DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); + + if (!cc_detector_) + cc_detector_ = std::make_unique<VP9ConfigChangeDetector>(); + cc_detector_->DetectConfig(buffer->data(), buffer->data_size()); + + if (!session_ || cc_detector_->config_changed()) { + // ConfigureDecoder() calls NotifyError() on failure. + if (!ConfigureDecoder()) + return; + } + + // Now that the configuration is up to date, copy it into the frame. + frame->image_size = configured_size_; + + // The created CMBlockBuffer owns a ref on DecoderBuffer to avoid a copy. + CMBlockBufferCustomBlockSource source = {0}; + source.refCon = buffer.get(); + source.FreeBlock = &ReleaseDecoderBuffer; + + // Create a memory-backed CMBlockBuffer for the translated data. + base::ScopedCFTypeRef<CMBlockBufferRef> data; + OSStatus status = CMBlockBufferCreateWithMemoryBlock( + kCFAllocatorDefault, + static_cast<void*>(buffer->writable_data()), // &memory_block + buffer->data_size(), // block_length + kCFAllocatorDefault, // block_allocator + &source, // &custom_block_source + 0, // offset_to_data + buffer->data_size(), // data_length + 0, // flags + data.InitializeInto()); + if (status) { + NOTIFY_STATUS("CMBlockBufferCreateWithMemoryBlock()", status, + SFT_PLATFORM_ERROR); + return; + } + + // Buffer creation was successful so add ref to |buffer| for CMBlockBuffer. + buffer->AddRef(); + + const size_t buffer_size = buffer->data_size(); + + // Package the data in a CMSampleBuffer. + base::ScopedCFTypeRef<CMSampleBufferRef> sample; + status = CMSampleBufferCreateReady(kCFAllocatorDefault, + data, // data_buffer + format_, // format_description + 1, // num_samples + 0, // num_sample_timing_entries + nullptr, // &sample_timing_array + 1, // num_sample_size_entries + &buffer_size, // &sample_size_array + sample.InitializeInto()); + if (status) { + NOTIFY_STATUS("CMSampleBufferCreate()", status, SFT_PLATFORM_ERROR); + return; + } + + // Send the frame for decoding. + // Asynchronous Decompression allows for parallel submission of frames + // (without it, DecodeFrame() does not return until the frame has been + // decoded). We don't enable Temporal Processing because we are not passing + // timestamps anyway. + VTDecodeFrameFlags decode_flags = + kVTDecodeFrame_EnableAsynchronousDecompression; + status = VTDecompressionSessionDecodeFrame( + session_, + sample, // sample_buffer + decode_flags, // decode_flags + reinterpret_cast<void*>(frame), // source_frame_refcon + nullptr); // &info_flags_out + if (status) { + NOTIFY_STATUS("VTDecompressionSessionDecodeFrame()", status, + SFT_DECODE_ERROR); + return; + } + + // No image will be produced for this frame, so mark it as done. + if (!cc_detector_->show_frame()) { + gpu_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&VTVideoDecodeAccelerator::DecodeDone, + weak_this_, frame)); + } +} + void VTVideoDecodeAccelerator::DecodeTask(scoped_refptr<DecoderBuffer> buffer, Frame* frame) { DVLOG(2) << __func__ << "(" << frame->bitstream_id << ")"; @@ -971,10 +1226,18 @@ Frame* frame = new Frame(bitstream_id); pending_frames_[bitstream_id] = base::WrapUnique(frame); - decoder_thread_.task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&VTVideoDecodeAccelerator::DecodeTask, - base::Unretained(this), std::move(buffer), frame)); + + if (codec_ == kCodecVP9) { + decoder_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&VTVideoDecodeAccelerator::DecodeTaskVp9, + base::Unretained(this), std::move(buffer), frame)); + } else { + decoder_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&VTVideoDecodeAccelerator::DecodeTask, + base::Unretained(this), std::move(buffer), frame)); + } } void VTVideoDecodeAccelerator::AssignPictureBuffers( @@ -1032,6 +1295,14 @@ DCHECK(gpu_task_runner_->BelongsToCurrentThread()); switch (state_) { case STATE_DECODING: + if (codec_ != kCodecH264) { + while (state_ == STATE_DECODING) { + if (!ProcessOutputQueue() && !ProcessTaskQueue()) + break; + } + return; + } + // TODO(sandersd): Batch where possible. while (state_ == STATE_DECODING) { if (!ProcessReorderQueue() && !ProcessTaskQueue()) @@ -1067,6 +1338,19 @@ Task& task = task_queue_.front(); switch (task.type) { case TASK_FRAME: { + if (codec_ == kCodecVP9) { + // Once we've reached our maximum output queue size, defer end of + // bitstream buffer signals to avoid piling up too many frames. + if (output_queue_.size() >= limits::kMaxVideoFrames) + return false; + + assigned_bitstream_ids_.erase(task.frame->bitstream_id); + client_->NotifyEndOfBitstreamBuffer(task.frame->bitstream_id); + output_queue_.push_back(std::move(task.frame)); + task_queue_.pop(); + return true; + } + bool reorder_queue_has_space = reorder_queue_.size() < kMaxReorderQueueSize; bool reorder_queue_flush_needed = @@ -1086,7 +1370,8 @@ case TASK_FLUSH: DCHECK_EQ(task.type, pending_flush_tasks_.front()); - if (reorder_queue_.size() == 0) { + if ((codec_ == kCodecH264 && reorder_queue_.size() == 0) || + (codec_ == kCodecVP9 && output_queue_.empty())) { DVLOG(1) << "Flush complete"; pending_flush_tasks_.pop(); client_->NotifyFlushDone(); @@ -1097,7 +1382,8 @@ case TASK_RESET: DCHECK_EQ(task.type, pending_flush_tasks_.front()); - if (reorder_queue_.size() == 0) { + if ((codec_ == kCodecH264 && reorder_queue_.size() == 0) || + (codec_ == kCodecVP9 && output_queue_.empty())) { DVLOG(1) << "Reset complete"; waiting_for_idr_ = true; pending_flush_tasks_.pop(); @@ -1142,6 +1428,21 @@ return false; } +bool VTVideoDecodeAccelerator::ProcessOutputQueue() { + DCHECK(gpu_task_runner_->BelongsToCurrentThread()); + DCHECK_EQ(state_, STATE_DECODING); + + if (output_queue_.empty()) + return false; + + if (ProcessFrame(*output_queue_.front())) { + output_queue_.pop_front(); + return true; + } + + return false; +} + bool VTVideoDecodeAccelerator::ProcessFrame(const Frame& frame) { DVLOG(3) << __func__ << "(" << frame.bitstream_id << ")"; DCHECK(gpu_task_runner_->BelongsToCurrentThread()); @@ -1204,7 +1505,9 @@ if (!gl_image->InitializeWithCVPixelBuffer( frame.image.get(), gfx::GenericSharedMemoryId(g_cv_pixel_buffer_ids.GetNext()), - gfx::BufferFormat::YUV_420_BIPLANAR)) { + config_.profile == VP9PROFILE_PROFILE2 + ? gfx::BufferFormat::P010 + : gfx::BufferFormat::YUV_420_BIPLANAR)) { NOTIFY_STATUS("Failed to initialize GLImageIOSurface", PLATFORM_FAILURE, SFT_PLATFORM_ERROR); } @@ -1334,6 +1637,25 @@ return profiles; for (const auto& supported_profile : kSupportedProfiles) { + if (supported_profile == VP9PROFILE_PROFILE0 || + supported_profile == VP9PROFILE_PROFILE2) { + if (!base::mac::IsAtLeastOS11()) + continue; + if (!base::FeatureList::IsEnabled(kVideoToolboxVp9Decoding)) + continue; + if (__builtin_available(macOS 10.13, *)) { + if ((supported_profile == VP9PROFILE_PROFILE0 || + supported_profile == VP9PROFILE_PROFILE2) && + !VTIsHardwareDecodeSupported(kCMVideoCodecType_VP9)) { + continue; + } + + // Success! We have VP9 hardware decoding support. + } else { + continue; + } + } + SupportedProfile profile; profile.profile = supported_profile; profile.min_resolution.SetSize(16, 16);
diff --git a/media/gpu/mac/vt_video_decode_accelerator_mac.h b/media/gpu/mac/vt_video_decode_accelerator_mac.h index a1c3036..eda859a5c 100644 --- a/media/gpu/mac/vt_video_decode_accelerator_mac.h +++ b/media/gpu/mac/vt_video_decode_accelerator_mac.h
@@ -29,6 +29,7 @@ #include "ui/gl/gl_image_io_surface.h" namespace media { +class VP9ConfigChangeDetector; // Preload VideoToolbox libraries, needed for sandbox warmup. MEDIA_GPU_EXPORT bool InitializeVideoToolbox(); @@ -162,6 +163,7 @@ // |frame| is owned by |pending_frames_|. void DecodeTask(scoped_refptr<DecoderBuffer> buffer, Frame* frame); + void DecodeTaskVp9(scoped_refptr<DecoderBuffer> buffer, Frame* frame); void DecodeDone(Frame* frame); // @@ -188,6 +190,7 @@ // These methods returns true if a task was completed, false otherwise. bool ProcessTaskQueue(); bool ProcessReorderQueue(); + bool ProcessOutputQueue(); bool ProcessFrame(const Frame& frame); bool SendFrame(const Frame& frame); @@ -213,6 +216,12 @@ FrameOrder> reorder_queue_; + // Queue of decoded frames in presentation order. Used by codecs which don't + // require reordering (VP9 only at the moment). + std::deque<std::unique_ptr<Frame>> output_queue_; + + std::unique_ptr<VP9ConfigChangeDetector> cc_detector_; + // Size of assigned picture buffers. gfx::Size picture_size_; @@ -258,6 +267,9 @@ std::vector<uint8_t> configured_spsext_; std::vector<uint8_t> configured_pps_; + Config config_; + VideoCodec codec_; + // Visible rect the decoder is configured to use. gfx::Size configured_size_;
diff --git a/media/gpu/test/BUILD.gn b/media/gpu/test/BUILD.gn index 675e565..92f16e16 100644 --- a/media/gpu/test/BUILD.gn +++ b/media/gpu/test/BUILD.gn
@@ -214,7 +214,7 @@ } } -if (is_chromeos) { +if (is_chromeos || use_vaapi) { static_library("local_gpu_memory_buffer_manager") { testonly = true sources = [
diff --git a/media/gpu/vaapi/BUILD.gn b/media/gpu/vaapi/BUILD.gn index 1d372daa..a51f8237 100644 --- a/media/gpu/vaapi/BUILD.gn +++ b/media/gpu/vaapi/BUILD.gn
@@ -114,32 +114,36 @@ ] } + if (use_x11 || use_ozone || use_egl) { + sources += [ + "vaapi_picture_native_pixmap.cc", + "vaapi_picture_native_pixmap.h", + ] + } + if (use_x11) { deps += [ "//ui/gfx/x" ] sources += [ + "vaapi_picture_native_pixmap_angle.cc", + "vaapi_picture_native_pixmap_angle.h", "vaapi_picture_tfp.cc", "vaapi_picture_tfp.h", ] } - if (use_ozone || use_egl) { + if (use_ozone) { + deps += [ "//ui/ozone" ] sources += [ - "vaapi_picture_native_pixmap.cc", - "vaapi_picture_native_pixmap.h", + "vaapi_picture_native_pixmap_ozone.cc", + "vaapi_picture_native_pixmap_ozone.h", ] - if (use_ozone) { - sources += [ - "vaapi_picture_native_pixmap_ozone.cc", - "vaapi_picture_native_pixmap_ozone.h", - ] - deps += [ "//ui/ozone" ] - } - if (use_egl) { - sources += [ - "vaapi_picture_native_pixmap_egl.cc", - "vaapi_picture_native_pixmap_egl.h", - ] - } + } + + if (use_egl) { + sources += [ + "vaapi_picture_native_pixmap_egl.cc", + "vaapi_picture_native_pixmap_egl.h", + ] } }
diff --git a/media/gpu/vaapi/vaapi_picture.h b/media/gpu/vaapi/vaapi_picture.h index 0364163..8020a6b 100644 --- a/media/gpu/vaapi/vaapi_picture.h +++ b/media/gpu/vaapi/vaapi_picture.h
@@ -41,7 +41,7 @@ // Allocates a buffer of |format| to use as backing storage for this picture. // Return true on success. - virtual bool Allocate(gfx::BufferFormat format) = 0; + virtual Status Allocate(gfx::BufferFormat format) = 0; int32_t picture_buffer_id() const { return picture_buffer_id_; }
diff --git a/media/gpu/vaapi/vaapi_picture_factory.cc b/media/gpu/vaapi/vaapi_picture_factory.cc index 46d4ceee..6e5eb542 100644 --- a/media/gpu/vaapi/vaapi_picture_factory.cc +++ b/media/gpu/vaapi/vaapi_picture_factory.cc
@@ -10,6 +10,7 @@ #include "ui/gl/gl_bindings.h" #if defined(USE_X11) +#include "media/gpu/vaapi/vaapi_picture_native_pixmap_angle.h" #include "media/gpu/vaapi/vaapi_picture_tfp.h" #endif #if defined(USE_OZONE) @@ -26,6 +27,9 @@ std::make_pair(gl::kGLImplementationEGLGLES2, VaapiPictureFactory::kVaapiImplementationDrm)); #if defined(USE_X11) + vaapi_impl_pairs_.insert( + std::make_pair(gl::kGLImplementationEGLANGLE, + VaapiPictureFactory::kVaapiImplementationAngle)); if (!features::IsUsingOzonePlatform()) { vaapi_impl_pairs_.insert( std::make_pair(gl::kGLImplementationDesktopGL, @@ -151,6 +155,13 @@ service_texture_id, client_texture_id, picture_buffer.texture_target()); break; + case kVaapiImplementationAngle: + return std::make_unique<VaapiPictureNativePixmapAngle>( + std::move(vaapi_wrapper), make_context_current_cb, bind_image_cb, + picture_buffer.id(), picture_buffer.size(), visible_size, + service_texture_id, client_texture_id, + picture_buffer.texture_target()); + break; #endif // USE_X11 default:
diff --git a/media/gpu/vaapi/vaapi_picture_factory.h b/media/gpu/vaapi/vaapi_picture_factory.h index 08372fc..9bb3453 100644 --- a/media/gpu/vaapi/vaapi_picture_factory.h +++ b/media/gpu/vaapi/vaapi_picture_factory.h
@@ -24,7 +24,8 @@ enum VaapiImplementation { kVaapiImplementationNone = 0, kVaapiImplementationDrm, - kVaapiImplementationX11 + kVaapiImplementationX11, + kVaapiImplementationAngle, }; VaapiPictureFactory();
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.cc new file mode 100644 index 0000000..d46b67d --- /dev/null +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.cc
@@ -0,0 +1,68 @@ +// 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 "media/gpu/vaapi/vaapi_picture_native_pixmap_angle.h" + +#include "base/file_descriptor_posix.h" +#include "gpu/command_buffer/common/gpu_memory_buffer_support.h" +#include "media/gpu/vaapi/va_surface.h" +#include "media/gpu/vaapi/vaapi_wrapper.h" +#include "ui/gfx/linux/gbm_buffer.h" +#include "ui/gfx/linux/gpu_memory_buffer_support_x11.h" +#include "ui/gfx/linux/native_pixmap_dmabuf.h" +#include "ui/gfx/native_pixmap.h" +#include "ui/gl/gl_bindings.h" +#include "ui/gl/gl_image_native_pixmap.h" +#include "ui/gl/scoped_binders.h" + +namespace media { + +VaapiPictureNativePixmapAngle::VaapiPictureNativePixmapAngle( + scoped_refptr<VaapiWrapper> vaapi_wrapper, + const MakeGLContextCurrentCallback& make_context_current_cb, + const BindGLImageCallback& bind_image_cb, + int32_t picture_buffer_id, + const gfx::Size& visible_size, + const gfx::Size& size, + uint32_t service_texture_id, + uint32_t client_texture_id, + uint32_t texture_target) + : VaapiPictureNativePixmap(std::move(vaapi_wrapper), + make_context_current_cb, + bind_image_cb, + picture_buffer_id, + size, + visible_size, + service_texture_id, + client_texture_id, + texture_target) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // Check that they're either both 0 or both not 0 (tests will set both to 0) + DCHECK(!!service_texture_id == !!client_texture_id); +} + +VaapiPictureNativePixmapAngle::~VaapiPictureNativePixmapAngle() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (gl_image_ && make_context_current_cb_.Run()) { + gl_image_->ReleaseTexImage(texture_target_); + DCHECK_EQ(glGetError(), static_cast<GLenum>(GL_NO_ERROR)); + } +} + +Status VaapiPictureNativePixmapAngle::Allocate(gfx::BufferFormat format) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + NOTIMPLEMENTED(); + return StatusCode::kGenericErrorPleaseRemove; +} + +bool VaapiPictureNativePixmapAngle::ImportGpuMemoryBufferHandle( + gfx::BufferFormat format, + gfx::GpuMemoryBufferHandle gpu_memory_buffer_handlee) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + NOTIMPLEMENTED(); + return false; +} + +} // namespace media
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.h b/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.h new file mode 100644 index 0000000..9c8e3e0 --- /dev/null +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.h
@@ -0,0 +1,49 @@ +// 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 MEDIA_GPU_VAAPI_VAAPI_PICTURE_NATIVE_PIXMAP_ANGLE_H_ +#define MEDIA_GPU_VAAPI_VAAPI_PICTURE_NATIVE_PIXMAP_ANGLE_H_ + +#include <stdint.h> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "media/gpu/vaapi/vaapi_picture_native_pixmap.h" +#include "ui/gfx/buffer_types.h" +#include "ui/gfx/geometry/size.h" + +namespace media { + +class VaapiWrapper; + +// Implementation of VaapiPictureNativePixmap for ANGLE backends. +class VaapiPictureNativePixmapAngle : public VaapiPictureNativePixmap { + public: + VaapiPictureNativePixmapAngle( + scoped_refptr<VaapiWrapper> vaapi_wrapper, + const MakeGLContextCurrentCallback& make_context_current_cb, + const BindGLImageCallback& bind_image_cb_, + int32_t picture_buffer_id, + const gfx::Size& size, + const gfx::Size& visible_size, + uint32_t texture_id, + uint32_t client_texture_id, + uint32_t texture_target); + + ~VaapiPictureNativePixmapAngle() override; + + // VaapiPicture implementation. + Status Allocate(gfx::BufferFormat format) override; + bool ImportGpuMemoryBufferHandle( + gfx::BufferFormat format, + gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) override; + + private: + DISALLOW_COPY_AND_ASSIGN(VaapiPictureNativePixmapAngle); +}; + +} // namespace media + +#endif // MEDIA_GPU_VAAPI_VAAPI_PICTURE_NATIVE_PIXMAP_ANGLE_H_
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc index edcd25c..286878a 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc
@@ -48,7 +48,7 @@ } } -bool VaapiPictureNativePixmapEgl::Initialize( +Status VaapiPictureNativePixmapEgl::Initialize( scoped_refptr<gfx::NativePixmap> pixmap) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(pixmap); @@ -58,24 +58,24 @@ va_surface_ = vaapi_wrapper_->CreateVASurfaceForPixmap(std::move(pixmap)); if (!va_surface_) { LOG(ERROR) << "Failed creating VASurface for NativePixmap"; - return false; + return StatusCode::kVaapiNoSurface; } if (bind_image_cb_ && !bind_image_cb_.Run(client_texture_id_, texture_target_, gl_image_, true /* can_bind_to_sampler */)) { LOG(ERROR) << "Failed to bind client_texture_id"; - return false; + return StatusCode::kVaapiFailedToBindImage; } - return true; + return OkStatus(); } -bool VaapiPictureNativePixmapEgl::Allocate(gfx::BufferFormat format) { +Status VaapiPictureNativePixmapEgl::Allocate(gfx::BufferFormat format) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Export the gl texture as dmabuf. if (make_context_current_cb_ && !make_context_current_cb_.Run()) - return false; + return StatusCode::kVaapiBadContext; auto image = base::MakeRefCounted<gl::GLImageNativePixmap>(visible_size_, format); @@ -83,14 +83,14 @@ if (!image->InitializeFromTexture(texture_id_)) { DLOG(ERROR) << "Failed to initialize eglimage from texture id: " << texture_id_; - return false; + return StatusCode::kVaapiFailedToInitializeImage; } // Export the EGLImage as dmabuf. gfx::NativePixmapHandle native_pixmap_handle = image->ExportHandle(); if (!native_pixmap_handle.planes.size()) { DLOG(ERROR) << "Failed to export EGLImage as dmabuf fds"; - return false; + return StatusCode::kVaapiFailedToExportImage; } if (size_.width() > static_cast<int>(native_pixmap_handle.planes[0].stride) || @@ -98,7 +98,7 @@ DLOG(ERROR) << "EGLImage (stride=" << native_pixmap_handle.planes[0].stride << ", size=" << native_pixmap_handle.planes[0].size << "is smaller than size_=" << size_.ToString(); - return false; + return StatusCode::kVaapiBadImageSize; } // Convert NativePixmapHandle to NativePixmapDmaBuf. @@ -107,12 +107,12 @@ std::move(native_pixmap_handle))); if (!native_pixmap_dmabuf->AreDmaBufFdsValid()) { DLOG(ERROR) << "Invalid dmabuf fds"; - return false; + return StatusCode::kVaapiNoBufferHandle; } if (!image->BindTexImage(texture_target_)) { DLOG(ERROR) << "Failed to bind texture to GLImage"; - return false; + return StatusCode::kVaapiFailedToBindImage; } // The |va_surface_| created from |native_pixmap_dmabuf| shares the ownership
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h index 6b838cc3..40bd0d90 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h
@@ -40,13 +40,13 @@ ~VaapiPictureNativePixmapEgl() override; // VaapiPicture implementation. - bool Allocate(gfx::BufferFormat format) override; + Status Allocate(gfx::BufferFormat format) override; bool ImportGpuMemoryBufferHandle( gfx::BufferFormat format, gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) override; private: - bool Initialize(scoped_refptr<gfx::NativePixmap> pixmap); + Status Initialize(scoped_refptr<gfx::NativePixmap> pixmap); DISALLOW_COPY_AND_ASSIGN(VaapiPictureNativePixmapEgl); };
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc index 419e301..af93b47 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc
@@ -49,7 +49,7 @@ } } -bool VaapiPictureNativePixmapOzone::Initialize( +Status VaapiPictureNativePixmapOzone::Initialize( scoped_refptr<gfx::NativePixmap> pixmap) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(pixmap); @@ -58,16 +58,16 @@ va_surface_ = vaapi_wrapper_->CreateVASurfaceForPixmap(pixmap); if (!va_surface_) { LOG(ERROR) << "Failed creating VASurface for NativePixmap"; - return false; + return StatusCode::kVaapiNoSurface; } // ARC++ has no texture ids. if (texture_id_ == 0 && client_texture_id_ == 0) - return true; + return OkStatus(); // Import dmabuf fds into the output gl texture through EGLImage. if (make_context_current_cb_ && !make_context_current_cb_.Run()) - return false; + return StatusCode::kVaapiBadContext; gl::ScopedTextureBinder texture_binder(texture_target_, texture_id_); @@ -77,26 +77,26 @@ base::MakeRefCounted<gl::GLImageNativePixmap>(visible_size_, format); if (!image->Initialize(std::move(pixmap))) { LOG(ERROR) << "Failed to create GLImage"; - return false; + return StatusCode::kVaapiFailedToInitializeImage; } gl_image_ = image; if (!gl_image_->BindTexImage(texture_target_)) { LOG(ERROR) << "Failed to bind texture to GLImage"; - return false; + return StatusCode::kVaapiFailedToBindTexture; } if (bind_image_cb_ && !bind_image_cb_.Run(client_texture_id_, texture_target_, gl_image_, true /* can_bind_to_sampler */)) { LOG(ERROR) << "Failed to bind client_texture_id"; - return false; + return StatusCode::kVaapiFailedToBindImage; } - return true; + return OkStatus(); } -bool VaapiPictureNativePixmapOzone::Allocate(gfx::BufferFormat format) { +Status VaapiPictureNativePixmapOzone::Allocate(gfx::BufferFormat format) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ui::OzonePlatform* platform = ui::OzonePlatform::GetInstance(); @@ -105,8 +105,7 @@ gfx::kNullAcceleratedWidget, VK_NULL_HANDLE, size_, format, gfx::BufferUsage::SCANOUT_VDA_WRITE, /*framebuffer_size=*/visible_size_); if (!pixmap) { - LOG(ERROR) << "Failed allocating a pixmap"; - return false; + return StatusCode::kVaapiNoPixmap; } return Initialize(std::move(pixmap)); @@ -138,7 +137,7 @@ return false; } - return Initialize(std::move(pixmap)); + return Initialize(std::move(pixmap)).is_ok(); } } // namespace media
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h index 3abdc84b..caf3fba 100644 --- a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h +++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h
@@ -39,13 +39,13 @@ ~VaapiPictureNativePixmapOzone() override; // VaapiPicture implementation. - bool Allocate(gfx::BufferFormat format) override; + Status Allocate(gfx::BufferFormat format) override; bool ImportGpuMemoryBufferHandle( gfx::BufferFormat format, gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) override; private: - bool Initialize(scoped_refptr<gfx::NativePixmap> pixmap); + Status Initialize(scoped_refptr<gfx::NativePixmap> pixmap); DISALLOW_COPY_AND_ASSIGN(VaapiPictureNativePixmapOzone); };
diff --git a/media/gpu/vaapi/vaapi_picture_tfp.cc b/media/gpu/vaapi/vaapi_picture_tfp.cc index 37b821c..56c79cf 100644 --- a/media/gpu/vaapi/vaapi_picture_tfp.cc +++ b/media/gpu/vaapi/vaapi_picture_tfp.cc
@@ -52,36 +52,36 @@ XFreePixmap(x_display_, x_pixmap_); } -bool VaapiTFPPicture::Initialize() { +Status VaapiTFPPicture::Initialize() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(x_pixmap_); if (make_context_current_cb_ && !make_context_current_cb_.Run()) - return false; + return StatusCode::kVaapiBadContext; glx_image_ = new gl::GLImageGLX(size_, gfx::BufferFormat::BGRX_8888); if (!glx_image_->Initialize(x_pixmap_)) { // x_pixmap_ will be freed in the destructor. DLOG(ERROR) << "Failed creating a GLX Pixmap for TFP"; - return false; + return StatusCode::kVaapiNoPixmap; } gl::ScopedTextureBinder texture_binder(texture_target_, texture_id_); if (!glx_image_->BindTexImage(texture_target_)) { DLOG(ERROR) << "Failed to bind texture to glx image"; - return false; + return StatusCode::kVaapiFailedToBindTexture; } - return true; + return OkStatus(); } -bool VaapiTFPPicture::Allocate(gfx::BufferFormat format) { +Status VaapiTFPPicture::Allocate(gfx::BufferFormat format) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (format != gfx::BufferFormat::BGRX_8888 && format != gfx::BufferFormat::BGRA_8888 && format != gfx::BufferFormat::RGBX_8888) { DLOG(ERROR) << "Unsupported format"; - return false; + return StatusCode::kVaapiUnsupportedFormat; } XWindowAttributes win_attr; @@ -93,7 +93,7 @@ size_.width(), size_.height(), win_attr.depth); if (!x_pixmap_) { DLOG(ERROR) << "Failed creating an X Pixmap for TFP"; - return false; + return StatusCode::kVaapiNoPixmap; } return Initialize();
diff --git a/media/gpu/vaapi/vaapi_picture_tfp.h b/media/gpu/vaapi/vaapi_picture_tfp.h index 830cb6e..c4eb2c1 100644 --- a/media/gpu/vaapi/vaapi_picture_tfp.h +++ b/media/gpu/vaapi/vaapi_picture_tfp.h
@@ -38,14 +38,14 @@ ~VaapiTFPPicture() override; // VaapiPicture implementation. - bool Allocate(gfx::BufferFormat format) override; + Status Allocate(gfx::BufferFormat format) override; bool ImportGpuMemoryBufferHandle( gfx::BufferFormat format, gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) override; bool DownloadFromSurface(scoped_refptr<VASurface> va_surface) override; private: - bool Initialize(); + Status Initialize(); Display* x_display_;
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc index e86723a..132280d 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.cc
@@ -13,6 +13,7 @@ #include "base/bind_helpers.h" #include "base/cpu.h" #include "base/files/scoped_file.h" +#include "base/json/json_writer.h" #include "base/logging.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" @@ -27,6 +28,7 @@ #include "gpu/ipc/service/gpu_channel.h" #include "media/base/bind_to_current_loop.h" #include "media/base/format_utils.h" +#include "media/base/media_log.h" #include "media/base/unaligned_shared_memory.h" #include "media/base/video_util.h" #include "media/gpu/accelerated_video_decoder.h" @@ -90,6 +92,14 @@ } \ } while (0) +#define RETURN_AND_NOTIFY_ON_STATUS(status, ret) \ + do { \ + if (!status.is_ok()) { \ + NotifyStatus(status); \ + return ret; \ + } \ + } while (0) + class VaapiVideoDecodeAccelerator::InputBuffer { public: InputBuffer() : buffer_(nullptr) {} @@ -118,6 +128,17 @@ DISALLOW_COPY_AND_ASSIGN(InputBuffer); }; +void VaapiVideoDecodeAccelerator::NotifyStatus(Status status) { + DCHECK(!status.is_ok()); + // Send a platform notification error + NotifyError(PLATFORM_FAILURE); + + // TODO(crbug.com/1103510) there is no MediaLog here, we should change that. + std::string output_str; + base::JSONWriter::Write(MediaSerialize(status), &output_str); + DLOG(ERROR) << output_str; +} + void VaapiVideoDecodeAccelerator::NotifyError(Error error) { if (!task_runner_->BelongsToCurrentThread()) { DCHECK(decoder_thread_task_runner_->BelongsToCurrentThread()); @@ -716,9 +737,8 @@ PLATFORM_FAILURE, ); if (output_mode_ == Config::OutputMode::ALLOCATE) { - RETURN_AND_NOTIFY_ON_FAILURE( - picture->Allocate(vaapi_picture_factory_->GetBufferFormat()), - "Failed to allocate memory for a VaapiPicture", PLATFORM_FAILURE, ); + RETURN_AND_NOTIFY_ON_STATUS( + picture->Allocate(vaapi_picture_factory_->GetBufferFormat()), ); available_picture_buffers_.push_back(buffers[i].id()); VASurfaceID va_surface_id = picture->va_surface_id(); if (va_surface_id != VA_INVALID_ID)
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator.h b/media/gpu/vaapi/vaapi_video_decode_accelerator.h index 62b90c8..b47a3eee 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator.h +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator.h
@@ -111,6 +111,7 @@ // Notify the client that an error has occurred and decoding cannot continue. void NotifyError(Error error); + void NotifyStatus(Status status); // Queue a input buffer for decode. void QueueInputBuffer(scoped_refptr<DecoderBuffer> buffer,
diff --git a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc index 1eb262e..b2e67b96 100644 --- a/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc +++ b/media/gpu/vaapi/vaapi_video_decode_accelerator_unittest.cc
@@ -105,7 +105,7 @@ ~MockVaapiPicture() override = default; // VaapiPicture implementation. - bool Allocate(gfx::BufferFormat format) override { return true; } + Status Allocate(gfx::BufferFormat format) override { return OkStatus(); } bool ImportGpuMemoryBufferHandle( gfx::BufferFormat format, gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle) override {
diff --git a/media/gpu/vaapi/vaapi_video_decoder.cc b/media/gpu/vaapi/vaapi_video_decoder.cc index 5041157..39a64a5 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.cc +++ b/media/gpu/vaapi/vaapi_video_decoder.cc
@@ -158,8 +158,9 @@ profile_ = profile; color_space_ = config.color_space_info(); - if (!CreateAcceleratedVideoDecoder()) { - std::move(init_cb).Run(StatusCode::kVaapiFailedAcceleratorCreation); + auto accel_status = CreateAcceleratedVideoDecoder(); + if (!accel_status.is_ok()) { + std::move(init_cb).Run(std::move(accel_status)); return; } @@ -537,7 +538,7 @@ if (state_ == State::kChangingResolution) { // If we reset during resolution change, re-create AVD. Then the new AVD // will trigger resolution change again after reset. - if (!CreateAcceleratedVideoDecoder()) { + if (!CreateAcceleratedVideoDecoder().is_ok()) { SetState(State::kError); std::move(reset_cb).Run(); return; @@ -558,7 +559,7 @@ std::move(reset_cb))); } -bool VaapiVideoDecoder::CreateAcceleratedVideoDecoder() { +Status VaapiVideoDecoder::CreateAcceleratedVideoDecoder() { DVLOGF(2); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -583,10 +584,10 @@ decoder_.reset( new VP9Decoder(std::move(accelerator), profile_, color_space_)); } else { - VLOGF(1) << "Unsupported profile " << GetProfileName(profile_); - return false; + return Status(StatusCode::kDecoderUnsupportedProfile) + .WithData("profile", profile_); } - return true; + return OkStatus(); } void VaapiVideoDecoder::ResetDone(base::OnceClosure reset_cb) {
diff --git a/media/gpu/vaapi/vaapi_video_decoder.h b/media/gpu/vaapi/vaapi_video_decoder.h index c106a3b..bece6d3ec 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.h +++ b/media/gpu/vaapi/vaapi_video_decoder.h
@@ -22,6 +22,7 @@ #include "base/optional.h" #include "base/sequence_checker.h" #include "base/time/time.h" +#include "media/base/status.h" #include "media/base/video_codecs.h" #include "media/base/video_frame_layout.h" #include "media/gpu/chromeos/video_decoder_pipeline.h" @@ -120,7 +121,7 @@ void ResetDone(base::OnceClosure reset_cb); // Create codec-specific AcceleratedVideoDecoder and reset related variables. - bool CreateAcceleratedVideoDecoder(); + Status CreateAcceleratedVideoDecoder(); // Change the current |state_| to the specified |state|. void SetState(State state);
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index 34257d7f..c17b7b8 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -410,11 +410,18 @@ break; case gl::kGLImplementationDesktopGL: #if defined(USE_X11) - if (!features::IsUsingOzonePlatform()) + if (!features::IsUsingOzonePlatform()) { va_display_ = vaGetDisplay(gfx::GetXDisplay()); -#else - LOG(WARNING) << "VAAPI video acceleration not available without " - "DesktopGL (GLX)."; + if (!vaDisplayIsValid(va_display_)) + va_display_ = vaGetDisplayDRM(drm_fd_.get()); + } +#endif // USE_X11 + break; + case gl::kGLImplementationEGLANGLE: +#if defined(USE_X11) + va_display_ = vaGetDisplay(gfx::GetXDisplay()); + if (vaDisplayIsValid(va_display_)) + break; #endif // USE_X11 break; // Cannot infer platform from GL, try all available displays
diff --git a/mojo/public/tools/bindings/generators/cpp_tracing_support.py b/mojo/public/tools/bindings/generators/cpp_tracing_support.py new file mode 100644 index 0000000..9ce7b5de --- /dev/null +++ b/mojo/public/tools/bindings/generators/cpp_tracing_support.py
@@ -0,0 +1,389 @@ +# 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. +"""Generates C++ source code to trace mojo method parameters.""" + +from generators.cpp_util import IsNativeOnlyKind +import mojom.generate.module as mojom +from abc import ABCMeta +from abc import abstractmethod + + +class _OutputContext(object): + __metaclass__ = ABCMeta + """Represents the context in which |self.value| should be used. + + This is a base class for _ArrayItem, _DictionaryItemWithLiteralKey, and + _DictionaryItemWithCopiedKey. The distinction between _ArrayItem and + _DictionaryItemWithLiteralKey/_DictionaryItemWithCopiedKey is that + _ArrayItem has no name. The distinction between + _DictionaryItemWithLiteralKey and _DictionaryItemWithCopiedKey is whether + the name is expected to be long lived or can be temporary. + """ + + def __init__(self, value): + self.value = value + + @abstractmethod + def AddSingleValue(self, trace_type, parameter_value): + pass + + @abstractmethod + def BeginContainer(self, container_type): + pass + + def EndContainer(self, container_type): + """Return a line of C++ code to close a container on self.value. + + Args: + container_type: {string} Either 'Dictionary' or 'Array'. + + Returns: + A single line of C++ which closes a container on self.value. + """ + return '%s->End%s();' % (self.value, container_type) + + def AsValueInto(self, cpp_expression): + """Return a line of C++ code to trace a variable to self.value. + Most probably the user of this method wants to yield + |self.BeginContainer('Dictionary')| immediately before and + |self.EndContainer('Dictionary')| immediately after a call to + |AsValueInto| (see documentation of |cpp_expression::AsValueInto|). + + Args: + cpp_expression: {string} The C++ expression on which |->AsValueInto| + will be called. + + Returns: + A single line of C++ which calls |AsValueInto| on |cpp_expression| + with self.value as the parameter. + """ + return '%s->AsValueInto(%s);' % (cpp_expression, self.value) + + def TraceContainer(self, container_type, iterator_name, container_name, + loop_body): + """Generate the C++ for-loop to trace the container |container_name|. + + Args: + container_type: {string} Either 'Array' or 'Dictionary'. + iterator_name: {string} The iterator variable name to be used. + container_name: {string} The name of the variable holding the container. + loop_body: {iterable} Lines of C++ code that trace individual elements. + + Yields: + Lines of C++ for-loop to trace the container. + """ + yield self.BeginContainer(container_type) + yield 'for (const auto& %s : %s) {' % (iterator_name, container_name) + for line in loop_body: + yield ' ' + line + yield '}' + yield self.EndContainer(container_type) + + +class _ArrayItem(_OutputContext): + """Represents a |TracedValue| which expects to receive an array item (of no + name). This means that |AddSingleValue| will return a call on self.value + which is an Append and |BeginContainer| will start a container with no + name. + + Attributes: + value: {string} The name of the C++ variable of type + |base::trace_event::TracedValue*| this object represents. + """ + + def __init__(self, value): + super(_ArrayItem, self).__init__(value) + + def AddSingleValue(self, trace_type, parameter_value): + """Return a line of C++ code that will append a single value to + |self.value|. + + Args: + trace_type: {string} The type of the appended value. Can be one of: + 'Integer', 'Double', 'Boolean', 'String'. + parameter_value: {string} The C++ expression to be passed as the + appended value. + + Returns: + A single line of C++ which appends |parameter_value| to self.value. + """ + return '%s->Append%s(%s);' % (self.value, trace_type, parameter_value) + + def BeginContainer(self, container_type): + """Return a line of C++ code to open a container on self.value. + + Args: + container_type: {string} Either 'Dictionary' or 'Array'. + + Returns: + A single line of C++ which starts a container on self.value. + """ + return '%s->Begin%s();' % (self.value, container_type) + + +class _DictionaryItemWithLiteralKey(_OutputContext): + """Represents a |TracedValue| which expects to receive a dictionary item + (with a long lived name). This means that |AddSingleValue| will return a + call on self.value which is a Set and |BeginContainer| will start a + container with self.name used in a string literal. + + |base::trace_event::TracedValue| has two sets of methods -- ones with copied + name and ones with long lived name. This class corresponds to using the long + lived name. + + _DictionaryItemWithLiteralKey generates calls on + |base::trace_event::TracedValue| which do not copy the name (assume that + the used name is long lived. Thus self.name is used inside a "quoted" long + lived string. + + Attributes: + value: {string} The name of the C++ variable of type + |base::trace_event::TracedValue*| this object represents. + name: {string} The name of the mojo variable that is currently being + traced. Used inside double-quotes in method calls. + """ + + def __init__(self, name, value): + super(_DictionaryItemWithLiteralKey, self).__init__(value) + self.name = name + + def AddSingleValue(self, trace_type, parameter_value): + """Return a line of C++ code that will set a single value to |self.value|. + Uses |self.name| inside a "quoted" string. + + Args: + trace_type: {string} The type of the set value. Can be one of: + 'Integer', 'Double', 'Boolean', 'String', 'Value'. + parameter_value: {string} The C++ expression to be passed as the + set value. + + Returns: + A single line of C++ that sets |parameter_value| of name |"self.name"| + on self.value. + """ + return '%s->Set%s("%s", %s);' % (self.value, trace_type, self.name, + parameter_value) + + def BeginContainer(self, container_type): + return '%s->Begin%s("%s");' % (self.value, container_type, self.name) + + +class _DictionaryItemWithCopiedKey(_OutputContext): + """Represents a |TracedValue| which expects to receive a dictionary item + (with a name which is a temporary string). This means that + |AddSingleValue| will return a call on self.value which is an + SetXWithCopiedName and |BeginContainer| will start a container with + self.name used as a temporary string. + + |base::trace_event::TracedValue| has two sets of methods -- ones with copied + name and ones with long lived name. This class corresponds to using the + copied name. + + _DictionaryItemWithCopiedKey generates calls on + |base::trace_event::TracedValue| which do copy the name (assume that + self.name is a C++ expression evaluating to a temporary string). + + Attributes: + value: {string} The name of the C++ variable of type + |base::trace_event::TracedValue*| this object represents. + name: {string} The name of the mojo variable that is currently being + traced. Used directly (not in double quotes) in method calls. + """ + + def __init__(self, name, value): + super(_DictionaryItemWithCopiedKey, self).__init__(value) + self.name = name + + def AddSingleValue(self, trace_type, parameter_value): + """Return a line of C++ code that will set a single value to |self.value|. + Uses |self.name| directly as a parameter that is expected to be copied + (can be a temporary string). + + Args: + trace_type: {string} The type of the set value. Can be one of: + 'Integer', 'Double', 'Boolean', 'String', 'Value'. + parameter_value: {string} The C++ expression to be passed as the + set value. + + Returns: + A single line of C++ that sets |parameter_value| of name |self.name| + on self.value (with copied name). + """ + return '%s->Set%sWithCopiedName(%s, %s);' % (self.value, trace_type, + self.name, parameter_value) + + def BeginContainer(self, container_type): + return '%s->Begin%sWithCopiedName(%s);' % (self.value, container_type, + self.name) + + +def _WriteInputParamForTracingImpl(generator, kind, cpp_parameter_name, + output_context): + """Generates lines of C++ to log a parameter into TracedValue + |output_context.value|. Use |output_context.name| if |output_context| is of + inhereted type from _OutputContext. + + Args: + kind: {Kind} The kind of the parameter (corresponds to its C++ type). + cpp_parameter_name: {string} The actual C++ variable name corresponding to + the mojom parameter |parameter_name|. Can be a valid C++ expression + (e.g., dereferenced variable |"(*var)"|). + output_context: {_OutputContext} Represents the TracedValue* variable to be + written into. Possibly also holds the mojo parameter name corresponding to + |cpp_parameter_name|. + + Yields: + {string} C++ lines of code that trace a |cpp_parameter_name| into + |output_context.value|. + """ + + def _WrapIfNullable(inner_lines): + """Check if kind is nullable if so yield code to check whether it has + value. + + Args: + inner_lines: {function} Function taking single argument and returning + iterable. If kind is nullable, yield from this method with + |cpp_parameter_name+'.value()'| otherwise yield with the parameter + |cpp_parameter_name|. + + Args from the surrounding method: + kind + cpp_parameter_name + output_context.AddSingleValue + """ + if mojom.IsNullableKind(kind): + yield 'if (%s.has_value()) {' % cpp_parameter_name + for line in inner_lines(cpp_parameter_name + '.value()'): + yield ' ' + line + yield '} else {' + yield ' ' + output_context.AddSingleValue('String', '"base::nullopt"') + yield '}' + else: + # |yield from| is introduced in Python3.3. + for line in inner_lines(cpp_parameter_name): + yield line + + # TODO(crbug.com/1103623): Support more involved types. + if mojom.IsEnumKind(kind): + if generator._IsTypemappedKind(kind) or IsNativeOnlyKind(kind): + yield output_context.AddSingleValue( + 'Integer', 'static_cast<int>(%s)' % cpp_parameter_name) + else: + yield output_context.AddSingleValue( + 'String', 'base::trace_event::ValueToString(%s)' % cpp_parameter_name) + return + if mojom.IsStringKind(kind): + if generator.for_blink: + # WTF::String is nullable on its own. + yield output_context.AddSingleValue('String', + '%s.Utf8()' % cpp_parameter_name) + return + # The type might be base::Optional<std::string> or std::string. + for line in _WrapIfNullable(lambda cpp_parameter_name: [ + output_context.AddSingleValue('String', cpp_parameter_name) + ]): + yield line + return + if kind == mojom.BOOL: + yield output_context.AddSingleValue('Boolean', cpp_parameter_name) + return + # TODO(crbug.com/1103623): Make TracedValue support int64_t, then move to + # mojom.IsIntegralKind. + if kind in [mojom.INT8, mojom.UINT8, mojom.INT16, mojom.UINT16, mojom.INT32]: + # Parameter is representable as 32bit int. + yield output_context.AddSingleValue('Integer', cpp_parameter_name) + return + if kind in [mojom.UINT32, mojom.INT64, mojom.UINT64]: + yield output_context.AddSingleValue( + 'String', 'base::NumberToString(%s)' % cpp_parameter_name) + return + if mojom.IsFloatKind(kind) or mojom.IsDoubleKind(kind): + yield output_context.AddSingleValue('Double', cpp_parameter_name) + return + if (mojom.IsStructKind(kind) and not generator._IsTypemappedKind(kind) + and not IsNativeOnlyKind(kind)): + yield 'if (%s.is_null()) {' % cpp_parameter_name + yield ' ' + output_context.AddSingleValue('String', '"nullptr"') + yield '} else {' + yield ' ' + output_context.BeginContainer('Dictionary') + yield ' ' + output_context.AsValueInto(cpp_parameter_name) + yield ' ' + output_context.EndContainer('Dictionary') + yield '}' + return + + if mojom.IsArrayKind(kind): + iterator_name = 'item' + loop_body = _WriteInputParamForTracingImpl(generator=generator, + kind=kind.kind, + cpp_parameter_name=iterator_name, + output_context=_ArrayItem( + output_context.value)) + loop_generator = lambda cpp_parameter_name: output_context.TraceContainer( + container_type='Array', + iterator_name=iterator_name, + container_name=cpp_parameter_name, + loop_body=loop_body) + # Array might be a nullable kind. + for line in _WrapIfNullable(loop_generator): + yield line + return + + def _TraceEventToString(cpp_parameter_name=cpp_parameter_name, kind=kind): + return 'base::trace_event::ValueToString(%s, "<value of type %s>")' % ( + cpp_parameter_name, generator._GetCppWrapperParamType(kind)) + + if mojom.IsMapKind(kind): + iterator_name = 'item' + if generator.for_blink: + # WTF::HashMap<,> + key_access = '.key' + value_access = '.value' + else: + # base::flat_map<,> + key_access = '.first' + value_access = '.second' + loop_body = _WriteInputParamForTracingImpl( + generator=generator, + kind=kind.value_kind, + cpp_parameter_name=iterator_name + value_access, + output_context=_DictionaryItemWithCopiedKey( + value=output_context.value, + name=_TraceEventToString(cpp_parameter_name=iterator_name + + key_access, + kind=kind.key_kind))) + loop_generator = lambda cpp_parameter_name: output_context.TraceContainer( + container_type="Dictionary", + iterator_name=iterator_name, + container_name=cpp_parameter_name, + loop_body=loop_body) + # Dictionary might be a nullable kind. + for line in _WrapIfNullable(loop_generator): + yield line + return + yield output_context.AddSingleValue('String', _TraceEventToString()) + + +def WriteInputParamForTracing(generator, kind, parameter_name, + cpp_parameter_name, value): + """Generates lines of C++ to log parameter |parameter_name| into TracedValue + |value|. + + Args: + kind: {Kind} The kind of the parameter (corresponds to its C++ type). + cpp_parameter_name: {string} The actual C++ variable name corresponding to + the mojom parameter |parameter_name|. Can be a valid C++ expression + (e.g., dereferenced variable |"(*var)"|). + value: {string} The C++ |TracedValue*| variable name to be logged into. + + Yields: + {string} C++ lines of code that trace |parameter_name| into |value|. + """ + for line in _WriteInputParamForTracingImpl( + generator=generator, + kind=kind, + cpp_parameter_name=cpp_parameter_name, + output_context=_DictionaryItemWithLiteralKey(name=parameter_name, + value=value)): + yield line
diff --git a/mojo/public/tools/bindings/generators/cpp_util.py b/mojo/public/tools/bindings/generators/cpp_util.py new file mode 100644 index 0000000..b44d5d2 --- /dev/null +++ b/mojo/public/tools/bindings/generators/cpp_util.py
@@ -0,0 +1,12 @@ +# 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. +"""Implement the common methods used in mojom_cpp_generator.py and +mojom_cpp_parameter_tracing.py in order to get rid of circular dependency.""" + +import mojom.generate.module as mojom + + +def IsNativeOnlyKind(kind): + return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \ + kind.native_only
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py index 850956c..0895416 100644 --- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -7,8 +7,8 @@ import mojom.generate.generator as generator import mojom.generate.module as mojom import mojom.generate.pack as pack -from abc import ABCMeta -from abc import abstractmethod +from generators.cpp_util import IsNativeOnlyKind +from generators.cpp_tracing_support import WriteInputParamForTracing from mojom.generate.template_expander import UseJinja, UseJinjaForImportedTemplate @@ -139,11 +139,6 @@ return full_enum_name.split("::")[-1] -def IsNativeOnlyKind(kind): - return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \ - kind.native_only - - def UseCustomSerializer(kind): return mojom.IsStructKind(kind) and kind.custom_serializer @@ -670,358 +665,6 @@ GetCppPodType(constant.kind), constant.name, self._ConstantValue(constant)) - class _OutputContext(object): - __metaclass__ = ABCMeta - """Represents the context in which |self.value| should be used. - - This is a base class for _ArrayItem, _DictionaryItemWithLiteralKey, and - _DictionaryItemWithCopiedKey. The distinction between _ArrayItem and - _DictionaryItemWithLiteralKey/_DictionaryItemWithCopiedKey is that - _ArrayItem has no name. The distinction between - _DictionaryItemWithLiteralKey and _DictionaryItemWithCopiedKey is whether - the name is expected to be long lived or can be temporary. - """ - - def __init__(self, value): - self.value = value - - @abstractmethod - def AddSingleValue(self, trace_type, parameter_value): - pass - - @abstractmethod - def BeginContainer(self, container_type): - pass - - def EndContainer(self, container_type): - """Return a line of C++ code to close a container on self.value. - - Args: - container_type: {string} Either 'Dictionary' or 'Array'. - - Returns: - A single line of C++ which closes a container on self.value. - """ - return '%s->End%s();' % (self.value, container_type) - - def AsValueInto(self, cpp_expression): - """Return a line of C++ code to trace a variable to self.value. - Most probably the user of this method wants to yield - |self.BeginContainer('Dictionary')| immediately before and - |self.EndContainer('Dictionary')| immediately after a call to - |AsValueInto| (see documentation of |cpp_expression::AsValueInto|). - - Args: - cpp_expression: {string} The C++ expression on which |->AsValueInto| - will be called. - - Returns: - A single line of C++ which calls |AsValueInto| on |cpp_expression| - with self.value as the parameter. - """ - return '%s->AsValueInto(%s);' % (cpp_expression, self.value) - - def TraceContainer(self, container_type, iterator_name, container_name, - loop_body): - """Generate the C++ for-loop to trace the container |container_name|. - - Args: - container_type: {string} Either 'Array' or 'Dictionary'. - iterator_name: {string} The iterator variable name to be used. - container_name: {string} The name of the variable holding the container. - loop_body: {iterable} Lines of C++ code that trace individual elements. - - Yields: - Lines of C++ for-loop to trace the container. - """ - yield self.BeginContainer(container_type) - yield 'for (const auto& %s : %s) {' % (iterator_name, container_name) - for line in loop_body: - yield ' ' + line - yield '}' - yield self.EndContainer(container_type) - - class _ArrayItem(_OutputContext): - """Represents a |TracedValue| which expects to receive an array item (of no - name). This means that |AddSingleValue| will return a call on self.value - which is an Append and |BeginContainer| will start a container with no - name. - - Attributes: - value: {string} The name of the C++ variable of type - |base::trace_event::TracedValue*| this object represents. - """ - - def __init__(self, value): - super(Generator._ArrayItem, self).__init__(value) - - def AddSingleValue(self, trace_type, parameter_value): - """Return a line of C++ code that will append a single value to - |self.value|. - - Args: - trace_type: {string} The type of the appended value. Can be one of: - 'Integer', 'Double', 'Boolean', 'String'. - parameter_value: {string} The C++ expression to be passed as the - appended value. - - Returns: - A single line of C++ which appends |parameter_value| to self.value. - """ - return '%s->Append%s(%s);' % (self.value, trace_type, parameter_value) - - def BeginContainer(self, container_type): - """Return a line of C++ code to open a container on self.value. - - Args: - container_type: {string} Either 'Dictionary' or 'Array'. - - Returns: - A single line of C++ which starts a container on self.value. - """ - return '%s->Begin%s();' % (self.value, container_type) - - class _DictionaryItemWithLiteralKey(_OutputContext): - """Represents a |TracedValue| which expects to receive a dictionary item - (with a long lived name). This means that |AddSingleValue| will return a - call on self.value which is a Set and |BeginContainer| will start a - container with self.name used in a string literal. - - |base::trace_event::TracedValue| has two sets of methods -- ones with copied - name and ones with long lived name. This class corresponds to using the long - lived name. - - _DictionaryItemWithLiteralKey generates calls on - |base::trace_event::TracedValue| which do not copy the name (assume that - the used name is long lived. Thus self.name is used inside a "quoted" long - lived string. - - Attributes: - value: {string} The name of the C++ variable of type - |base::trace_event::TracedValue*| this object represents. - name: {string} The name of the mojo variable that is currently being - traced. Used inside double-quotes in method calls. - """ - - def __init__(self, name, value): - super(Generator._DictionaryItemWithLiteralKey, self).__init__(value) - self.name = name - - def AddSingleValue(self, trace_type, parameter_value): - """Return a line of C++ code that will set a single value to |self.value|. - Uses |self.name| inside a "quoted" string. - - Args: - trace_type: {string} The type of the set value. Can be one of: - 'Integer', 'Double', 'Boolean', 'String', 'Value'. - parameter_value: {string} The C++ expression to be passed as the - set value. - - Returns: - A single line of C++ that sets |parameter_value| of name |"self.name"| - on self.value. - """ - return '%s->Set%s("%s", %s);' % (self.value, trace_type, self.name, - parameter_value) - - def BeginContainer(self, container_type): - return '%s->Begin%s("%s");' % (self.value, container_type, self.name) - - class _DictionaryItemWithCopiedKey(_OutputContext): - """Represents a |TracedValue| which expects to receive a dictionary item - (with a name which is a temporary string). This means that - |AddSingleValue| will return a call on self.value which is an - SetXWithCopiedName and |BeginContainer| will start a container with - self.name used as a temporary string. - - |base::trace_event::TracedValue| has two sets of methods -- ones with copied - name and ones with long lived name. This class corresponds to using the - copied name. - - _DictionaryItemWithCopiedKey generates calls on - |base::trace_event::TracedValue| which do copy the name (assume that - self.name is a C++ expression evaluating to a temporary string). - - Attributes: - value: {string} The name of the C++ variable of type - |base::trace_event::TracedValue*| this object represents. - name: {string} The name of the mojo variable that is currently being - traced. Used directly (not in double quotes) in method calls. - """ - - def __init__(self, name, value): - super(Generator._DictionaryItemWithCopiedKey, self).__init__(value) - self.name = name - - def AddSingleValue(self, trace_type, parameter_value): - """Return a line of C++ code that will set a single value to |self.value|. - Uses |self.name| directly as a parameter that is expected to be copied - (can be a temporary string). - - Args: - trace_type: {string} The type of the set value. Can be one of: - 'Integer', 'Double', 'Boolean', 'String', 'Value'. - parameter_value: {string} The C++ expression to be passed as the - set value. - - Returns: - A single line of C++ that sets |parameter_value| of name |self.name| - on self.value (with copied name). - """ - return '%s->Set%sWithCopiedName(%s, %s);' % (self.value, trace_type, - self.name, parameter_value) - - def BeginContainer(self, container_type): - return '%s->Begin%sWithCopiedName(%s);' % (self.value, container_type, - self.name) - - def _WriteInputParamForTracingImpl(self, kind, cpp_parameter_name, - output_context): - """Generates lines of C++ to log a parameter into TracedValue - |output_context.value|. Use |output_context.name| if |output_context| is of - inhereted type from Generator._OutputContext. - - Args: - kind: {Kind} The kind of the parameter (corresponds to its C++ type). - cpp_parameter_name: {string} The actual C++ variable name corresponding to - the mojom parameter |parameter_name|. Can be a valid C++ expression - (e.g., dereferenced variable |"(*var)"|). - output_context: {Generator._OutputContext} Represents the TracedValue* - variable to be written into. Possibly also holds the mojo parameter name - corresponding to |cpp_parameter_name|. - - Yields: - {string} C++ lines of code that trace a |cpp_parameter_name| into - |output_context.value|. - """ - - def _WrapIfNullable(inner_lines): - """Check if kind is nullable if so yield code to check whether it has - value. - - Args: - inner_lines: {function} Function taking single argument and returning - iterable. If kind is nullable, yield from this method with - |cpp_parameter_name+'.value()'| otherwise yield with the parameter - |cpp_parameter_name|. - - Args from the surrounding method: - kind - cpp_parameter_name - output_context.AddSingleValue - """ - if mojom.IsNullableKind(kind): - yield 'if (%s.has_value()) {' % cpp_parameter_name - for line in inner_lines(cpp_parameter_name + '.value()'): - yield ' ' + line - yield '} else {' - yield ' ' + output_context.AddSingleValue('String', '"base::nullopt"') - yield '}' - else: - # |yield from| is introduced in Python3.3. - for line in inner_lines(cpp_parameter_name): - yield line - - # TODO(crbug.com/1103623): Support more involved types. - if mojom.IsEnumKind(kind): - if self._IsTypemappedKind(kind) or IsNativeOnlyKind(kind): - yield output_context.AddSingleValue( - 'Integer', 'static_cast<int>(%s)' % cpp_parameter_name) - else: - yield output_context.AddSingleValue( - 'String', - 'base::trace_event::ValueToString(%s)' % cpp_parameter_name) - return - if mojom.IsStringKind(kind): - if self.for_blink: - # WTF::String is nullable on its own. - yield output_context.AddSingleValue('String', - '%s.Utf8()' % cpp_parameter_name) - return - # The type might be base::Optional<std::string> or std::string. - for line in _WrapIfNullable(lambda cpp_parameter_name: [ - output_context.AddSingleValue('String', cpp_parameter_name) - ]): - yield line - return - if kind == mojom.BOOL: - yield output_context.AddSingleValue('Boolean', cpp_parameter_name) - return - # TODO(crbug.com/1103623): Make TracedValue support int64_t, then move to - # mojom.IsIntegralKind. - if kind in [ - mojom.INT8, mojom.UINT8, mojom.INT16, mojom.UINT16, mojom.INT32 - ]: - # Parameter is representable as 32bit int. - yield output_context.AddSingleValue('Integer', cpp_parameter_name) - return - if kind in [mojom.UINT32, mojom.INT64, mojom.UINT64]: - yield output_context.AddSingleValue( - 'String', 'base::NumberToString(%s)' % cpp_parameter_name) - return - if mojom.IsFloatKind(kind) or mojom.IsDoubleKind(kind): - yield output_context.AddSingleValue('Double', cpp_parameter_name) - return - if (mojom.IsStructKind(kind) and not self._IsTypemappedKind(kind) - and not IsNativeOnlyKind(kind)): - yield 'if (%s.is_null()) {' % cpp_parameter_name - yield ' ' + output_context.AddSingleValue('String', '"nullptr"') - yield '} else {' - yield ' ' + output_context.BeginContainer('Dictionary') - yield ' ' + output_context.AsValueInto(cpp_parameter_name) - yield ' ' + output_context.EndContainer('Dictionary') - yield '}' - return - - if mojom.IsArrayKind(kind): - iterator_name = 'item' - loop_body = self._WriteInputParamForTracingImpl( - kind=kind.kind, - cpp_parameter_name=iterator_name, - output_context=Generator._ArrayItem(output_context.value)) - loop_generator = lambda cpp_parameter_name: output_context.TraceContainer( - container_type='Array', - iterator_name=iterator_name, - container_name=cpp_parameter_name, - loop_body=loop_body) - # Array might be a nullable kind. - for line in _WrapIfNullable(loop_generator): - yield line - return - - def _TraceEventToString(cpp_parameter_name=cpp_parameter_name, kind=kind): - return 'base::trace_event::ValueToString(%s, "<value of type %s>")' % ( - cpp_parameter_name, self._GetCppWrapperParamType(kind)) - - if mojom.IsMapKind(kind): - iterator_name = 'item' - if self.for_blink: - # WTF::HashMap<,> - key_access = '.key' - value_access = '.value' - else: - # base::flat_map<,> - key_access = '.first' - value_access = '.second' - loop_body = self._WriteInputParamForTracingImpl( - kind=kind.value_kind, - cpp_parameter_name=iterator_name + value_access, - output_context=Generator._DictionaryItemWithCopiedKey( - value=output_context.value, - name=_TraceEventToString(cpp_parameter_name=iterator_name + - key_access, - kind=kind.key_kind))) - loop_generator = lambda cpp_parameter_name: output_context.TraceContainer( - container_type="Dictionary", - iterator_name=iterator_name, - container_name=cpp_parameter_name, - loop_body=loop_body) - # Dictionary might be a nullable kind. - for line in _WrapIfNullable(loop_generator): - yield line - return - yield output_context.AddSingleValue('String', _TraceEventToString()) - def _WriteInputParamForTracing(self, kind, parameter_name, cpp_parameter_name, value): """Generates lines of C++ to log parameter |parameter_name| into TracedValue @@ -1037,11 +680,11 @@ Yields: {string} C++ lines of code that trace |parameter_name| into |value|. """ - for line in self._WriteInputParamForTracingImpl( - kind=kind, - cpp_parameter_name=cpp_parameter_name, - output_context=Generator._DictionaryItemWithLiteralKey( - name=parameter_name, value=value)): + for line in WriteInputParamForTracing(generator=self, + kind=kind, + parameter_name=parameter_name, + cpp_parameter_name=cpp_parameter_name, + value=value): yield line def _GetCppWrapperType(self,
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni index c7a86ec..2bb9199 100644 --- a/mojo/public/tools/bindings/mojom.gni +++ b/mojo/public/tools/bindings/mojom.gni
@@ -93,7 +93,9 @@ mojom_generator_script = "$mojom_generator_root/mojom_bindings_generator.py" mojom_generator_sources = mojom_parser_sources + [ + "$mojom_generator_root/generators/cpp_util.py", "$mojom_generator_root/generators/mojom_cpp_generator.py", + "$mojom_generator_root/generators/cpp_tracing_support.py", "$mojom_generator_root/generators/mojom_java_generator.py", "$mojom_generator_root/generators/mojom_mojolpm_generator.py", "$mojom_generator_root/generators/mojom_js_generator.py",
diff --git a/net/BUILD.gn b/net/BUILD.gn index 1e9f449e..bc526e8e 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1013,6 +1013,8 @@ "socket/udp_server_socket.cc", "socket/udp_server_socket.h", "socket/udp_socket.h", + "socket/udp_socket_global_limits.cc", + "socket/udp_socket_global_limits.h", "socket/websocket_endpoint_lock_manager.cc", "socket/websocket_endpoint_lock_manager.h", "socket/websocket_transport_client_socket_pool.cc",
diff --git a/net/base/features.cc b/net/base/features.cc index ea8bd1f0..e840f6643 100644 --- a/net/base/features.cc +++ b/net/base/features.cc
@@ -170,5 +170,13 @@ const base::Feature kPreemptiveMobileNetworkActivation{ "PreemptiveMobileNetworkActivation", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kLimitOpenUDPSockets{"LimitOpenUDPSockets", + base::FEATURE_ENABLED_BY_DEFAULT}; + +extern const base::FeatureParam<int> kLimitOpenUDPSocketsMax( + &kLimitOpenUDPSockets, + "LimitOpenUDPSocketsMax", + 6000); + } // namespace features } // namespace net
diff --git a/net/base/features.h b/net/base/features.h index a2a94e50..54c5705a 100644 --- a/net/base/features.h +++ b/net/base/features.h
@@ -256,6 +256,16 @@ // the Wi-Fi connection. NET_EXPORT extern const base::Feature kPreemptiveMobileNetworkActivation; +// Enables a process-wide limit on "open" UDP sockets. See +// udp_socket_global_limits.h for details on what constitutes an "open" socket. +NET_EXPORT extern const base::Feature kLimitOpenUDPSockets; + +// FeatureParams associated with kLimitOpenUDPSockets. + +// Sets the maximum allowed open UDP sockets. Provisioning more sockets than +// this will result in a failure (ERR_INSUFFICIENT_RESOURCES). +NET_EXPORT extern const base::FeatureParam<int> kLimitOpenUDPSocketsMax; + } // namespace features } // namespace net
diff --git a/net/nqe/throughput_analyzer.cc b/net/nqe/throughput_analyzer.cc index b5b5a32..08a5b6dd 100644 --- a/net/nqe/throughput_analyzer.cc +++ b/net/nqe/throughput_analyzer.cc
@@ -334,8 +334,7 @@ return false; } - double downstream_kbps_double = - (bits_received * 1.0f) / duration.InMillisecondsF(); + double downstream_kbps_double = bits_received * duration.ToHz() / 1000; if (IsHangingWindow(bits_received, duration, downstream_kbps_double)) { requests_.clear();
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index 0dfb1f1..0a76b56b3 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -451,3 +451,6 @@ // If true, when server is silently closing connections due to idle timeout, // serialize the connection close packets which will be added to time wait list. QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_add_silent_idle_timeout, false) + +// If true, do not send PING if ShouldKeepConnectionAlive is false. +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_fix_on_ping_timeout, false)
diff --git a/net/socket/udp_socket_global_limits.cc b/net/socket/udp_socket_global_limits.cc new file mode 100644 index 0000000..60c1cc7 --- /dev/null +++ b/net/socket/udp_socket_global_limits.cc
@@ -0,0 +1,91 @@ +// 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 <limits> + +#include "base/atomic_ref_count.h" +#include "base/no_destructor.h" +#include "net/base/features.h" +#include "net/socket/udp_socket_global_limits.h" + +namespace net { + +namespace { + +// Threadsafe singleton for tracking the process-wide count of UDP sockets. +class GlobalUDPSocketCounts { + public: + GlobalUDPSocketCounts() : count_(0) {} + + ~GlobalUDPSocketCounts() = delete; + + static GlobalUDPSocketCounts& Get() { + static base::NoDestructor<GlobalUDPSocketCounts> singleton; + return *singleton; + } + + bool TryAcquireSocket() WARN_UNUSED_RESULT { + int previous = count_.Increment(1); + if (previous >= GetMax()) { + count_.Increment(-1); + return false; + } + + return true; + } + + int GetMax() { + if (base::FeatureList::IsEnabled(features::kLimitOpenUDPSockets)) + return features::kLimitOpenUDPSocketsMax.Get(); + + return std::numeric_limits<int>::max(); + } + + void ReleaseSocket() { count_.Increment(-1); } + + int GetCountForTesting() { return count_.SubtleRefCountForDebug(); } + + private: + base::AtomicRefCount count_; +}; + +} // namespace + +OwnedUDPSocketCount::OwnedUDPSocketCount() : OwnedUDPSocketCount(true) {} + +OwnedUDPSocketCount::OwnedUDPSocketCount(OwnedUDPSocketCount&& other) { + *this = std::move(other); +} + +OwnedUDPSocketCount& OwnedUDPSocketCount::operator=( + OwnedUDPSocketCount&& other) { + Reset(); + empty_ = other.empty_; + other.empty_ = true; + return *this; +} + +OwnedUDPSocketCount::~OwnedUDPSocketCount() { + Reset(); +} + +void OwnedUDPSocketCount::Reset() { + if (!empty_) { + GlobalUDPSocketCounts::Get().ReleaseSocket(); + empty_ = true; + } +} + +OwnedUDPSocketCount::OwnedUDPSocketCount(bool empty) : empty_(empty) {} + +OwnedUDPSocketCount TryAcquireGlobalUDPSocketCount() { + bool success = GlobalUDPSocketCounts::Get().TryAcquireSocket(); + return OwnedUDPSocketCount(!success); +} + +int GetGlobalUDPSocketCountForTesting() { + return GlobalUDPSocketCounts::Get().GetCountForTesting(); +} + +} // namespace net
diff --git a/net/socket/udp_socket_global_limits.h b/net/socket/udp_socket_global_limits.h new file mode 100644 index 0000000..55364cf4 --- /dev/null +++ b/net/socket/udp_socket_global_limits.h
@@ -0,0 +1,75 @@ +// 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 NET_SOCKET_UDP_SOCKET_GLOBAL_LIMITS_H_ +#define NET_SOCKET_UDP_SOCKET_GLOBAL_LIMITS_H_ + +#include "base/compiler_specific.h" +#include "net/base/net_errors.h" +#include "net/base/net_export.h" + +namespace net { + +// Helper class for RAII-style management of the global count of "open UDP +// sockets" [1] in the process. +// +// Keeping OwnedUDPSocketCount alive increases the global socket counter by 1. +// When it goes out of scope - or is explicitly Reset() - the reference is +// returned to the global counter. +class NET_EXPORT OwnedUDPSocketCount { + public: + // The default constructor builds an empty OwnedUDPSocketCount (does not own a + // count). + OwnedUDPSocketCount(); + + // Any count held by OwnedUDPSocketCount is transferred when moving. + OwnedUDPSocketCount(OwnedUDPSocketCount&&); + OwnedUDPSocketCount& operator=(OwnedUDPSocketCount&&); + + // This is a move-only type. + OwnedUDPSocketCount(const OwnedUDPSocketCount&) = delete; + OwnedUDPSocketCount& operator=(const OwnedUDPSocketCount&) = delete; + + ~OwnedUDPSocketCount(); + + // Returns false if this instance "owns" a socket count. In + // other words, when |empty()|, destruction of |this| will + // not change the global socket count. + bool empty() const { return empty_; } + + // Resets |this| to an empty state (|empty()| becomes true after + // calling this). If |this| was previously |!empty()|, the global + // socket count will be decremented. + void Reset(); + + private: + // Only TryAcquireGlobalUDPSocketCount() is allowed to construct a non-empty + // OwnedUDPSocketCount. + friend NET_EXPORT OwnedUDPSocketCount TryAcquireGlobalUDPSocketCount(); + explicit OwnedUDPSocketCount(bool empty); + + bool empty_; +}; + +// Attempts to increase the global "open UDP socket" [1] count. +// +// * On failure returns an OwnedUDPSocketCount that is |empty()|. This happens +// if the global socket limit has been reached. +// * On success returns an OwnedUDPSocketCount that is |!empty()|. This +// OwnedUDPSocketCount should be kept alive until the socket resource is +// released. +// +// [1] For simplicity, an "open UDP socket" is defined as a net::UDPSocket that +// successfully called Open(), and has not yet called Close(). This is +// analogous to the number of open platform socket handles, and in practice +// should also be a good proxy for the number of consumed UDP ports. +NET_EXPORT OwnedUDPSocketCount TryAcquireGlobalUDPSocketCount() + WARN_UNUSED_RESULT; + +// Returns the current count of open UDP sockets (for testing only). +NET_EXPORT int GetGlobalUDPSocketCountForTesting(); + +} // namespace net + +#endif // NET_SOCKET_UDP_SOCKET_GLOBAL_LIMITS_H_
diff --git a/net/socket/udp_socket_posix.cc b/net/socket/udp_socket_posix.cc index 6fe907e0..8369ac37 100644 --- a/net/socket/udp_socket_posix.cc +++ b/net/socket/udp_socket_posix.cc
@@ -215,6 +215,10 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_EQ(socket_, kInvalidSocket); + auto owned_socket_count = TryAcquireGlobalUDPSocketCount(); + if (owned_socket_count.empty()) + return ERR_INSUFFICIENT_RESOURCES; + addr_family_ = ConvertAddressFamily(address_family); socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, 0); if (socket_ == kInvalidSocket) @@ -231,6 +235,8 @@ } if (tag_ != SocketTag()) tag_.Apply(socket_); + + owned_socket_count_ = std::move(owned_socket_count); return OK; } @@ -292,6 +298,8 @@ void UDPSocketPosix::Close() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + owned_socket_count_.Reset(); + if (socket_ == kInvalidSocket) return;
diff --git a/net/socket/udp_socket_posix.h b/net/socket/udp_socket_posix.h index df3bf973..6b77e9c 100644 --- a/net/socket/udp_socket_posix.h +++ b/net/socket/udp_socket_posix.h
@@ -30,6 +30,7 @@ #include "net/socket/diff_serv_code_point.h" #include "net/socket/socket_descriptor.h" #include "net/socket/socket_tag.h" +#include "net/socket/udp_socket_global_limits.h" #include "net/traffic_annotation/network_traffic_annotation.h" #if defined(__ANDROID__) && defined(__aarch64__) @@ -630,6 +631,10 @@ // enable_experimental_recv_optimization() method. bool experimental_recv_optimization_enabled_; + // Manages decrementing the global open UDP socket counter when this + // UDPSocket is destroyed. + OwnedUDPSocketCount owned_socket_count_; + THREAD_CHECKER(thread_checker_); // Used for alternate writes that are posted for concurrent execution.
diff --git a/net/socket/udp_socket_unittest.cc b/net/socket/udp_socket_unittest.cc index f434e44f..c2dba54 100644 --- a/net/socket/udp_socket_unittest.cc +++ b/net/socket/udp_socket_unittest.cc
@@ -14,8 +14,12 @@ #include "base/scoped_clear_last_error.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" +#include "base/test/scoped_feature_list.h" +#include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "net/base/features.h" #include "net/base/io_buffer.h" #include "net/base/ip_address.h" #include "net/base/ip_endpoint.h" @@ -29,6 +33,7 @@ #include "net/socket/socket_test_util.h" #include "net/socket/udp_client_socket.h" #include "net/socket/udp_server_socket.h" +#include "net/socket/udp_socket_global_limits.h" #include "net/test/gtest_util.h" #include "net/test/test_with_task_environment.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" @@ -1371,4 +1376,140 @@ } #endif +// Scoped helper to override the process-wide UDP socket limit. +class OverrideUDPSocketLimit { + public: + explicit OverrideUDPSocketLimit(int new_limit) { + base::FieldTrialParams params; + params[features::kLimitOpenUDPSocketsMax.name] = + base::NumberToString(new_limit); + + scoped_feature_list_.InitAndEnableFeatureWithParameters( + features::kLimitOpenUDPSockets, params); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Tests that UDPClientSocket respects the global UDP socket limits. +TEST_F(UDPSocketTest, LimitClientSocket) { + // Reduce the global UDP limit to 2. + OverrideUDPSocketLimit set_limit(2); + + ASSERT_EQ(0, GetGlobalUDPSocketCountForTesting()); + + auto socket1 = std::make_unique<UDPClientSocket>(DatagramSocket::DEFAULT_BIND, + nullptr, NetLogSource()); + auto socket2 = std::make_unique<UDPClientSocket>(DatagramSocket::DEFAULT_BIND, + nullptr, NetLogSource()); + + // Simply constructing a UDPClientSocket does not increase the limit (no + // Connect() or Bind() has been called yet). + ASSERT_EQ(0, GetGlobalUDPSocketCountForTesting()); + + // The specific value of this address doesn't really matter, and no server + // needs to be running here. The test only needs to call Connect() and won't + // send any datagrams. + IPEndPoint server_address(IPAddress::IPv4Localhost(), 8080); + + // Successful Connect() on socket1 increases socket count. + EXPECT_THAT(socket1->Connect(server_address), IsOk()); + EXPECT_EQ(1, GetGlobalUDPSocketCountForTesting()); + + // Successful Connect() on socket2 increases socket count. + EXPECT_THAT(socket2->Connect(server_address), IsOk()); + EXPECT_EQ(2, GetGlobalUDPSocketCountForTesting()); + + // Attempting a third Connect() should fail with ERR_INSUFFICIENT_RESOURCES, + // as the limit is currently 2. + auto socket3 = std::make_unique<UDPClientSocket>(DatagramSocket::DEFAULT_BIND, + nullptr, NetLogSource()); + EXPECT_THAT(socket3->Connect(server_address), + IsError(ERR_INSUFFICIENT_RESOURCES)); + EXPECT_EQ(2, GetGlobalUDPSocketCountForTesting()); + + // Check that explicitly closing socket2 free up a count. + socket2->Close(); + EXPECT_EQ(1, GetGlobalUDPSocketCountForTesting()); + + // Since the socket was already closed, deleting it will not affect the count. + socket2.reset(); + EXPECT_EQ(1, GetGlobalUDPSocketCountForTesting()); + + // Now that the count is below limit, try to connect socket3 again. This time + // it will work. + EXPECT_THAT(socket3->Connect(server_address), IsOk()); + EXPECT_EQ(2, GetGlobalUDPSocketCountForTesting()); + + // Verify that closing the two remaining sockets brings the open count back to + // 0. + socket1.reset(); + EXPECT_EQ(1, GetGlobalUDPSocketCountForTesting()); + socket3.reset(); + EXPECT_EQ(0, GetGlobalUDPSocketCountForTesting()); +} + +// Tests that UDPSocketClient updates the global counter +// correctly when Connect() fails. +TEST_F(UDPSocketTest, LimitConnectFail) { + ASSERT_EQ(0, GetGlobalUDPSocketCountForTesting()); + + { + // Simply allocating a UDPSocket does not increase count. + UDPSocket socket(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource()); + EXPECT_EQ(0, GetGlobalUDPSocketCountForTesting()); + + // Calling Open() allocates the socket and increases the global counter. + EXPECT_THAT(socket.Open(ADDRESS_FAMILY_IPV4), IsOk()); + EXPECT_EQ(1, GetGlobalUDPSocketCountForTesting()); + + // Connect to an IPv6 address should fail since the socket was created for + // IPv4. + EXPECT_THAT(socket.Connect(net::IPEndPoint(IPAddress::IPv6Localhost(), 53)), + Not(IsOk())); + + // That Connect() failed doesn't change the global counter. + EXPECT_EQ(1, GetGlobalUDPSocketCountForTesting()); + } + + // Finally, destroying UDPSocket decrements the global counter. + EXPECT_EQ(0, GetGlobalUDPSocketCountForTesting()); +} + +// Tests allocating UDPClientSockets and Connect()ing them in parallel. +// +// This is primarily intended for coverage under TSAN, to check for races +// enforcing the global socket counter. +TEST_F(UDPSocketTest, LimitConnectMultithreaded) { + ASSERT_EQ(0, GetGlobalUDPSocketCountForTesting()); + + // Start up some threads. + std::vector<std::unique_ptr<base::Thread>> threads; + for (size_t i = 0; i < 5; ++i) { + threads.push_back(std::make_unique<base::Thread>("Worker thread")); + ASSERT_TRUE(threads.back()->Start()); + } + + // Post tasks to each of the threads. + for (const auto& thread : threads) { + thread->task_runner()->PostTask( + FROM_HERE, base::BindOnce([] { + // The specific value of this address doesn't really matter, and no + // server needs to be running here. The test only needs to call + // Connect() and won't send any datagrams. + IPEndPoint server_address(IPAddress::IPv4Localhost(), 8080); + + UDPClientSocket socket(DatagramSocket::DEFAULT_BIND, nullptr, + NetLogSource()); + EXPECT_THAT(socket.Connect(server_address), IsOk()); + })); + } + + // Complete all the tasks. + threads.clear(); + + EXPECT_EQ(0, GetGlobalUDPSocketCountForTesting()); +} + } // namespace net
diff --git a/net/socket/udp_socket_win.cc b/net/socket/udp_socket_win.cc index f58a2b4..4fec002 100644 --- a/net/socket/udp_socket_win.cc +++ b/net/socket/udp_socket_win.cc
@@ -273,6 +273,10 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_EQ(socket_, INVALID_SOCKET); + auto owned_socket_count = TryAcquireGlobalUDPSocketCount(); + if (owned_socket_count.empty()) + return ERR_INSUFFICIENT_RESOURCES; + addr_family_ = ConvertAddressFamily(address_family); socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); if (socket_ == INVALID_SOCKET) @@ -283,12 +287,16 @@ read_write_event_.Set(WSACreateEvent()); WSAEventSelect(socket_, read_write_event_.Get(), FD_READ | FD_WRITE); } + + owned_socket_count_ = std::move(owned_socket_count); return OK; } void UDPSocketWin::Close() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + owned_socket_count_.Reset(); + if (socket_ == INVALID_SOCKET) return;
diff --git a/net/socket/udp_socket_win.h b/net/socket/udp_socket_win.h index 380ff03..a11d07a 100644 --- a/net/socket/udp_socket_win.h +++ b/net/socket/udp_socket_win.h
@@ -28,6 +28,7 @@ #include "net/log/net_log_with_source.h" #include "net/socket/datagram_socket.h" #include "net/socket/diff_serv_code_point.h" +#include "net/socket/udp_socket_global_limits.h" #include "net/traffic_annotation/network_traffic_annotation.h" namespace net { @@ -485,6 +486,10 @@ // Maintains remote addresses for QWAVE qos management. std::unique_ptr<DscpManager> dscp_manager_; + // Manages decrementing the global open UDP socket counter when this + // UDPSocket is destroyed. + OwnedUDPSocketCount owned_socket_count_; + THREAD_CHECKER(thread_checker_); // Used to prevent null dereferences in OnObjectSignaled, when passing an
diff --git a/pdf/document_loader_impl.cc b/pdf/document_loader_impl.cc index f7ca11c0..e0266bc 100644 --- a/pdf/document_loader_impl.cc +++ b/pdf/document_loader_impl.cc
@@ -13,9 +13,11 @@ #include "base/bind.h" #include "base/callback.h" #include "base/check_op.h" +#include "base/feature_list.h" #include "base/notreached.h" #include "base/numerics/safe_math.h" #include "base/strings/string_util.h" +#include "pdf/pdf_features.h" #include "pdf/url_loader_wrapper.h" #include "ppapi/c/pp_errors.h" #include "ui/gfx/range/range.h" @@ -65,7 +67,10 @@ chunk_data.reset(); } -DocumentLoaderImpl::DocumentLoaderImpl(Client* client) : client_(client) {} +DocumentLoaderImpl::DocumentLoaderImpl(Client* client) + : client_(client), + partial_loading_enabled_( + base::FeatureList::IsEnabled(features::kPdfPartialLoading)) {} DocumentLoaderImpl::~DocumentLoaderImpl() = default;
diff --git a/pdf/document_loader_impl.h b/pdf/document_loader_impl.h index fe47894..2fa1d71 100644 --- a/pdf/document_loader_impl.h +++ b/pdf/document_loader_impl.h
@@ -79,7 +79,7 @@ std::unique_ptr<URLLoaderWrapper> loader_; DataStream chunk_stream_; - bool partial_loading_enabled_ = true; + bool partial_loading_enabled_; // Default determined by `kPdfPartialLoading`. bool is_partial_loader_active_ = false; static constexpr uint32_t kReadBufferSize = 256 * 1024;
diff --git a/pdf/document_loader_impl_unittest.cc b/pdf/document_loader_impl_unittest.cc index 6748217..04f70bf 100644 --- a/pdf/document_loader_impl_unittest.cc +++ b/pdf/document_loader_impl_unittest.cc
@@ -12,6 +12,8 @@ #include "base/callback.h" #include "base/check.h" +#include "base/test/scoped_feature_list.h" +#include "pdf/pdf_features.h" #include "pdf/ppapi_migration/callback.h" #include "pdf/url_loader_wrapper.h" #include "testing/gmock/include/gmock/gmock.h" @@ -265,9 +267,49 @@ } // namespace -using DocumentLoaderImplTest = ::testing::Test; +class DocumentLoaderImplTest : public testing::Test { + protected: + DocumentLoaderImplTest() { + scoped_feature_list_.InitAndEnableFeature(features::kPdfPartialLoading); + } + + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(DocumentLoaderImplTest, PartialLoadingFeatureDefault) { + scoped_feature_list_.Reset(); + scoped_feature_list_.Init(); + + // Test that partial loading is enabled when feature is defaulted. + TestClient client; + client.SetCanUsePartialLoading(); + DocumentLoaderImpl loader(&client); + loader.Init(client.CreateFullPageLoader(), "http://url.com"); + loader.RequestData(1000000, 1); + EXPECT_FALSE(loader.is_partial_loader_active()); + // Always send initial data from FullPageLoader. + client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize); + EXPECT_TRUE(loader.is_partial_loader_active()); +} + +TEST_F(DocumentLoaderImplTest, PartialLoadingFeatureDisabled) { + scoped_feature_list_.Reset(); + scoped_feature_list_.InitAndDisableFeature(features::kPdfPartialLoading); + + // Test that partial loading is disabled when feature is disabled. + TestClient client; + client.SetCanUsePartialLoading(); + DocumentLoaderImpl loader(&client); + loader.Init(client.CreateFullPageLoader(), "http://url.com"); + loader.RequestData(1000000, 1); + EXPECT_FALSE(loader.is_partial_loader_active()); + // Always send initial data from FullPageLoader. + client.full_page_loader_data()->CallReadCallback(kDefaultRequestSize); + EXPECT_FALSE(loader.is_partial_loader_active()); +} TEST_F(DocumentLoaderImplTest, PartialLoadingEnabled) { + // Test that partial loading is enabled. (Fixture enables PdfPartialLoading.) TestClient client; client.SetCanUsePartialLoading(); DocumentLoaderImpl loader(&client);
diff --git a/pdf/pdf_features.cc b/pdf/pdf_features.cc index b82f648..07782ef 100644 --- a/pdf/pdf_features.cc +++ b/pdf/pdf_features.cc
@@ -16,6 +16,10 @@ const base::Feature kPdfHonorJsContentSettings = { "PdfHonorJsContentSettings", base::FEATURE_DISABLED_BY_DEFAULT}; +// TODO(crbug.com/1064175): Remove this once partial loading is fixed. +const base::Feature kPdfPartialLoading = {"PdfPartialLoading", + base::FEATURE_ENABLED_BY_DEFAULT}; + const base::Feature kPDFViewerUpdate = {"PDFViewerUpdate", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/pdf/pdf_features.h b/pdf/pdf_features.h index b7486977..1afa17e6 100644 --- a/pdf/pdf_features.h +++ b/pdf/pdf_features.h
@@ -16,6 +16,7 @@ extern const base::Feature kAccessiblePDFForm; extern const base::Feature kAccessiblePDFHighlight; extern const base::Feature kPdfHonorJsContentSettings; +extern const base::Feature kPdfPartialLoading; extern const base::Feature kPDFViewerUpdate; extern const base::Feature kSaveEditedPDFForm; extern const base::Feature kTabAcrossPDFAnnotations;
diff --git a/printing/backend/PRESUBMIT.py b/printing/backend/PRESUBMIT.py new file mode 100644 index 0000000..303ef5d --- /dev/null +++ b/printing/backend/PRESUBMIT.py
@@ -0,0 +1,50 @@ +# 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. + +""" +Presubmit script for the printing backend. + +See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts +for more details about the presubmit API. +""" + +def _CheckForStringViewFromNullableIppApi(input_api, output_api): + """ + Looks for all affected lines in CL where one constructs either + base::StringPiece or std::string_view from any ipp*() CUPS API call. + Assumes over-broadly that all ipp*() calls can return NULL. + Returns affected lines as a list of presubmit errors. + """ + # Attempts to detect source lines like: + # * base::StringPiece foo = ippDoBar(); + # * base::StringPiece foo(ippDoBar()); + # and the same for std::string_view. + string_view_re = input_api.re.compile( + r"^.+(base::StringPiece|std::string_view)\s+\w+( = |\()ipp[A-Z].+$") + violations = input_api.canned_checks._FindNewViolationsOfRule( + lambda extension, line: + not (extension in ("cc", "h") and string_view_re.search(line)), + input_api, None) + bulleted_violations = [" * {}".format(entry) for entry in violations] + + if bulleted_violations: + return [output_api.PresubmitError( + ("Possible construction of base::StringPiece or std::string_view " + "from CUPS IPP API (that can probably return NULL):\n{}").format( + "\n".join(bulleted_violations))),] + return [] + +def _CommonChecks(input_api, output_api): + """Actual implementation of presubmits for the printing backend.""" + results = [] + results.extend(_CheckForStringViewFromNullableIppApi(input_api, output_api)) + return results + +def CheckChangeOnUpload(input_api, output_api): + """Mandatory presubmit entry point.""" + return _CommonChecks(input_api, output_api) + +def CheckChangeOnCommit(input_api, output_api): + """Mandatory presubmit entry point.""" + return _CommonChecks(input_api, output_api)
diff --git a/printing/backend/cups_ipp_helper.cc b/printing/backend/cups_ipp_helper.cc index 02ea155..ac3902b 100644 --- a/printing/backend/cups_ipp_helper.cc +++ b/printing/backend/cups_ipp_helper.cc
@@ -87,7 +87,8 @@ if (!attr) return UNKNOWN_COLOR_MODEL; - return ColorModelFromIppColor(ippGetString(attr, 0, nullptr)); + const char* const value = ippGetString(attr, 0, nullptr); + return value ? ColorModelFromIppColor(value) : UNKNOWN_COLOR_MODEL; } std::vector<ColorModel> SupportedColorModels( @@ -145,10 +146,17 @@ if (duplex_mode != mojom::DuplexMode::kUnknownDuplexMode) printer_info->duplex_modes.push_back(duplex_mode); } + ipp_attribute_t* attr = printer.GetDefaultOptionValue(kIppDuplex); - printer_info->duplex_default = - attr ? DuplexModeFromIpp(ippGetString(attr, 0, nullptr)) - : mojom::DuplexMode::kUnknownDuplexMode; + if (!attr) { + printer_info->duplex_default = mojom::DuplexMode::kUnknownDuplexMode; + return; + } + + const char* const attr_str = ippGetString(attr, 0, nullptr); + printer_info->duplex_default = attr_str + ? DuplexModeFromIpp(attr_str) + : mojom::DuplexMode::kUnknownDuplexMode; } void CopiesRange(const CupsOptionProvider& printer, @@ -241,8 +249,8 @@ if (!attr) return false; - base::StringPiece name = ippGetString(attr, 0, nullptr); - return name.compare(kCollated) == 0; + const char* const name = ippGetString(attr, 0, nullptr); + return name && !base::StringPiece(name).compare(kCollated); } #if defined(OS_CHROMEOS)
diff --git a/printing/backend/cups_ipp_helper_unittest.cc b/printing/backend/cups_ipp_helper_unittest.cc index 104f1f6..051c42ab 100644 --- a/printing/backend/cups_ipp_helper_unittest.cc +++ b/printing/backend/cups_ipp_helper_unittest.cc
@@ -38,9 +38,14 @@ return std::vector<base::StringPiece>(); std::vector<base::StringPiece> strings; - int size = ippGetCount(attr); + const int size = ippGetCount(attr); + strings.reserve(size); for (int i = 0; i < size; ++i) { - strings.emplace_back(ippGetString(attr, i, nullptr)); + const char* const value = ippGetString(attr, i, nullptr); + if (!value) { + continue; + } + strings.push_back(value); } return strings;
diff --git a/printing/backend/cups_jobs.cc b/printing/backend/cups_jobs.cc index c09871e1..a719dee 100644 --- a/printing/backend/cups_jobs.cc +++ b/printing/backend/cups_jobs.cc
@@ -7,8 +7,10 @@ #include <cups/ipp.h> #include <array> +#include <cstring> #include <map> #include <memory> +#include <string> #include "base/logging.h" #include "base/stl_util.h" @@ -244,8 +246,10 @@ std::vector<std::string>* collection) { int count = ippGetCount(attr); for (int i = 0; i < count; i++) { - base::StringPiece value = ippGetString(attr, i, nullptr); - collection->push_back(value.as_string()); + const char* const value = ippGetString(attr, i, nullptr); + if (value) { + collection->push_back(value); + } } } @@ -288,9 +292,9 @@ CupsJob* current_job = NewJob(printer_id, jobs); for (ipp_attribute_t* attr = starting_attr; attr != nullptr; attr = ippNextAttribute(response)) { - base::StringPiece attribute_name = ippGetName(attr); + const char* const attribute_name = ippGetName(attr); // Separators indicate a new job. Separators have empty names. - if (attribute_name.empty()) { + if (!attribute_name || strlen(attribute_name) == 0) { current_job = NewJob(printer_id, jobs); continue; } @@ -306,7 +310,11 @@ bool ParsePrinterInfo(ipp_t* response, PrinterInfo* printer_info) { for (ipp_attribute_t* attr = ippFirstAttribute(response); attr != nullptr; attr = ippNextAttribute(response)) { - base::StringPiece name = ippGetName(attr); + const char* const value = ippGetName(attr); + if (!value) { + continue; + } + base::StringPiece name(value); if (name == base::StringPiece(kPrinterMakeAndModel)) { DCHECK_EQ(IPP_TAG_TEXT, ippGetValueTag(attr)); const char* make_and_model_string = ippGetString(attr, 0, nullptr); @@ -421,10 +429,11 @@ for (ipp_attribute_t* attr = ippFirstAttribute(response); attr != nullptr; attr = ippNextAttribute(response)) { - base::StringPiece name = ippGetName(attr); - if (name.empty()) { + const char* const value = ippGetName(attr); + if (!value) { continue; } + base::StringPiece name(value); if (name == kPrinterState) { DCHECK_EQ(IPP_TAG_ENUM, ippGetValueTag(attr));
diff --git a/printing/backend/cups_printer.cc b/printing/backend/cups_printer.cc index 144521d..a52cd5b 100644 --- a/printing/backend/cups_printer.cc +++ b/printing/backend/cups_printer.cc
@@ -47,10 +47,12 @@ if (!attr) return values; - base::StringPiece value; int num_options = ippGetCount(attr); for (int i = 0; i < num_options; ++i) { - value = ippGetString(attr, i, nullptr); + const char* const value = ippGetString(attr, i, nullptr); + if (!value) { + continue; + } values.push_back(value); }
diff --git a/remoting/host/basic_desktop_environment.cc b/remoting/host/basic_desktop_environment.cc index 939f8f7a..af8918e 100644 --- a/remoting/host/basic_desktop_environment.cc +++ b/remoting/host/basic_desktop_environment.cc
@@ -132,7 +132,7 @@ DCHECK(caller_task_runner_->BelongsToCurrentThread()); #if defined(USE_X11) if (!features::IsUsingOzonePlatform()) - IgnoreXServerGrabs(desktop_capture_options().x_display()->display(), true); + desktop_capture_options().x_display()->IgnoreXServerGrabs(); #elif defined(OS_WIN) // The options passed to this instance are determined by a process running in // Session 0. Access to DirectX functions in Session 0 is limited so the
diff --git a/remoting/host/curtain_mode_linux.cc b/remoting/host/curtain_mode_linux.cc index cc356ab..8501177 100644 --- a/remoting/host/curtain_mode_linux.cc +++ b/remoting/host/curtain_mode_linux.cc
@@ -10,7 +10,9 @@ #include "base/single_thread_task_runner.h" #include "remoting/base/logging.h" #include "remoting/host/client_session_control.h" -#include "ui/gfx/x/x11.h" +#include "ui/gfx/x/connection.h" +#include "ui/gfx/x/xinput.h" +#include "ui/gfx/x/xproto_types.h" namespace remoting { @@ -28,8 +30,7 @@ DISALLOW_COPY_AND_ASSIGN(CurtainModeLinux); }; -CurtainModeLinux::CurtainModeLinux() { -} +CurtainModeLinux::CurtainModeLinux() = default; bool CurtainModeLinux::Activate() { // We can't curtain the session in run-time in Linux. @@ -48,60 +49,60 @@ // Try to identify a virtual session. Since there's no way to tell from the // vendor string, we check for known virtual input devices. // TODO(rmsousa): Find a similar way to determine that the *output* is secure. - Display* display = XOpenDisplay(nullptr); - int opcode, event, error; - if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) { + x11::Connection connection; + if (!connection.xinput().present()) { // If XInput is not available, assume it is not a virtual session. - LOG(ERROR) << "X Input extension not available: " << error; - XCloseDisplay(display); + LOG(ERROR) << "X Input extension not available"; return false; } - int num_devices; - XDeviceInfo* devices; + + auto devices = connection.xinput().ListInputDevices({}).Sync(); + if (!devices) { + LOG(ERROR) << "ListInputDevices failed"; + return false; + } + bool found_xvfb_mouse = false; bool found_xvfb_keyboard = false; bool found_crd_void_input = false; bool found_other_devices = false; - devices = XListInputDevices(display, &num_devices); - for (int i = 0; i < num_devices; i++) { - XDeviceInfo* device_info = &devices[i]; - if (device_info->use == IsXExtensionPointer) { - if (strcmp(device_info->name, "Xvfb mouse") == 0) { + for (size_t i = 0; i < devices->devices.size(); i++) { + const auto& device_info = devices->devices[i]; + const std::string& name = devices->names[i].name; + if (device_info.device_use == x11::Input::DeviceUse::IsXExtensionPointer) { + if (name == "Xvfb mouse") { found_xvfb_mouse = true; - } else if (strcmp(device_info->name, - "Chrome Remote Desktop Input") == 0) { + } else if (name == "Chrome Remote Desktop Input") { found_crd_void_input = true; - } else if (strcmp(device_info->name, "Virtual core XTEST pointer") != 0) { + } else if (name != "Virtual core XTEST pointer") { found_other_devices = true; - HOST_LOG << "Non-virtual mouse found: " << device_info->name; + HOST_LOG << "Non-virtual mouse found: " << name; } - } else if (device_info->use == IsXExtensionKeyboard) { - if (strcmp(device_info->name, "Xvfb keyboard") == 0) { + } else if (device_info.device_use == + x11::Input::DeviceUse::IsXExtensionKeyboard) { + if (name == "Xvfb keyboard") { found_xvfb_keyboard = true; - } else if (strcmp(device_info->name, - "Virtual core XTEST keyboard") != 0) { + } else if (name != "Virtual core XTEST keyboard") { found_other_devices = true; - HOST_LOG << "Non-virtual keyboard found: " << device_info->name; + HOST_LOG << "Non-virtual keyboard found: " << name; } - } else if (device_info->use == IsXPointer) { - if (strcmp(device_info->name, "Virtual core pointer") != 0) { + } else if (device_info.device_use == x11::Input::DeviceUse::IsXPointer) { + if (name != "Virtual core pointer") { found_other_devices = true; - HOST_LOG << "Non-virtual mouse found: " << device_info->name; + HOST_LOG << "Non-virtual mouse found: " << name; } - } else if (device_info->use == IsXKeyboard) { - if (strcmp(device_info->name, "Virtual core keyboard") != 0) { + } else if (device_info.device_use == x11::Input::DeviceUse::IsXKeyboard) { + if (name != "Virtual core keyboard") { found_other_devices = true; - HOST_LOG << "Non-virtual keyboard found: " << device_info->name; + HOST_LOG << "Non-virtual keyboard found: " << name; } } else { found_other_devices = true; - HOST_LOG << "Non-virtual device found: " << device_info->name; + HOST_LOG << "Non-virtual device found: " << name; } } - XFreeDeviceList(devices); - XCloseDisplay(display); - return ((found_xvfb_mouse && found_xvfb_keyboard) || found_crd_void_input) - && !found_other_devices; + return ((found_xvfb_mouse && found_xvfb_keyboard) || found_crd_void_input) && + !found_other_devices; } // static
diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc index 6795fbe7..024e1ea5 100644 --- a/remoting/host/heartbeat_sender.cc +++ b/remoting/host/heartbeat_sender.cc
@@ -10,7 +10,6 @@ #include <utility> #include "base/bind.h" -#include "base/hash/sha1.h" #include "base/rand_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringize_macros.h" @@ -397,7 +396,7 @@ // a Linux OS. #if defined(OS_LINUX) && !defined(OS_CHROMEOS) if (is_googler_) { - heartbeat->set_hostname_hash(base::SHA1HashString(net::GetHostName())); + heartbeat->set_hostname(net::GetHostName()); } #endif return heartbeat;
diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc index 89dc624..557a53f 100644 --- a/remoting/host/heartbeat_sender_unittest.cc +++ b/remoting/host/heartbeat_sender_unittest.cc
@@ -78,9 +78,9 @@ is_linux = true; #endif if (is_googler && is_linux) { - ASSERT_TRUE(request->has_hostname_hash()); + ASSERT_TRUE(request->has_hostname()); } else { - ASSERT_FALSE(request->has_hostname_hash()); + ASSERT_FALSE(request->has_hostname()); } }
diff --git a/remoting/host/input_injector_x11.cc b/remoting/host/input_injector_x11.cc index c24acfae..9ee1736 100644 --- a/remoting/host/input_injector_x11.cc +++ b/remoting/host/input_injector_x11.cc
@@ -30,6 +30,9 @@ #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/gfx/x/x11.h" +#include "ui/gfx/x/xinput.h" +#include "ui/gfx/x/xproto.h" +#include "ui/gfx/x/xtest.h" #if defined(OS_CHROMEOS) #include "remoting/host/chromeos/point_transformer.h" @@ -41,8 +44,8 @@ using protocol::ClipboardEvent; using protocol::KeyEvent; -using protocol::TextEvent; using protocol::MouseEvent; +using protocol::TextEvent; using protocol::TouchEvent; enum class ScrollDirection { @@ -161,7 +164,8 @@ ScrollDirection latest_tick_y_direction_ = ScrollDirection::NONE; // X11 graphics context. - Display* display_ = XOpenDisplay(nullptr); + x11::Connection connection_; + Display* display_ = connection_.display(); Window root_window_ = BadValue; // Number of buttons we support. @@ -243,7 +247,7 @@ return false; } - if (!IgnoreXServerGrabs(display_, true)) { + if (!IgnoreXServerGrabs(&connection_, true)) { LOG(ERROR) << "Server does not support XTest."; return false; } @@ -251,8 +255,7 @@ return true; } -void InputInjectorX11::Core::InjectClipboardEvent( - const ClipboardEvent& event) { +void InputInjectorX11::Core::InjectClipboardEvent(const ClipboardEvent& event) { if (!task_runner_->BelongsToCurrentThread()) { task_runner_->PostTask( FROM_HERE, base::BindOnce(&Core::InjectClipboardEvent, this, event)); @@ -291,7 +294,7 @@ return; // Key is already held down, so lift the key up to ensure this repeated // press takes effect. - XTestFakeKeyEvent(display_, keycode, x11::False, x11::CurrentTime); + connection_.xtest().FakeInput({x11::KeyEvent::Release, keycode}); } if (!IsLockKey(keycode)) { @@ -328,8 +331,9 @@ pressed_keys_.erase(keycode); } - XTestFakeKeyEvent(display_, keycode, event.pressed(), x11::CurrentTime); - XFlush(display_); + auto opcode = event.pressed() ? x11::KeyEvent::Press : x11::KeyEvent::Release; + connection_.xtest().FakeInput({opcode, keycode}); + connection_.Flush(); } void InputInjectorX11::Core::InjectTextEvent(const TextEvent& event) { @@ -342,16 +346,15 @@ // Release all keys before injecting text event. This is necessary to avoid // any interference with the currently pressed keys. E.g. if Shift is pressed // when TextEvent is received. - for (int key : pressed_keys_) { - XTestFakeKeyEvent(display_, key, x11::False, x11::CurrentTime); - } + for (int key : pressed_keys_) + connection_.xtest().FakeInput({x11::KeyEvent::Release, key}); pressed_keys_.clear(); const std::string text = event.text(); for (int32_t index = 0; index < static_cast<int32_t>(text.size()); ++index) { uint32_t code_point; - if (!base::ReadUnicodeCharacter( - text.c_str(), text.size(), &index, &code_point)) { + if (!base::ReadUnicodeCharacter(text.c_str(), text.size(), &index, + &code_point)) { continue; } character_injector_->Inject(code_point); @@ -430,8 +433,8 @@ } for (int i = 0; i < count; i++) { // Generate a button-down and a button-up to simulate a wheel click. - XTestFakeButtonEvent(display_, button, true, x11::CurrentTime); - XTestFakeButtonEvent(display_, button, false, x11::CurrentTime); + connection_.xtest().FakeInput({x11::ButtonEvent::Press, button}); + connection_.xtest().FakeInput({x11::ButtonEvent::Release, button}); } } @@ -442,14 +445,16 @@ return; } - if (event.has_delta_x() && - event.has_delta_y() && + if (event.has_delta_x() && event.has_delta_y() && (event.delta_x() != 0 || event.delta_y() != 0)) { latest_mouse_position_.set(-1, -1); VLOG(3) << "Moving mouse by " << event.delta_x() << "," << event.delta_y(); - XTestFakeRelativeMotionEvent(display_, event.delta_x(), event.delta_y(), - x11::CurrentTime); - + connection_.xtest().FakeInput({ + .type = x11::MotionNotifyEvent::opcode, + .detail = true, + .rootX = event.delta_x(), + .rootY = event.delta_y(), + }); } else if (event.has_x() && event.has_y()) { // Injecting a motion event immediately before a button release results in // a MotionNotify even if the mouse position hasn't changed, which confuses @@ -473,11 +478,15 @@ latest_mouse_position_.set(std::max(0, new_mouse_position.x()), std::max(0, new_mouse_position.y())); - VLOG(3) << "Moving mouse to " << latest_mouse_position_.x() - << "," << latest_mouse_position_.y(); - XTestFakeMotionEvent(display_, DefaultScreen(display_), - latest_mouse_position_.x(), - latest_mouse_position_.y(), x11::CurrentTime); + VLOG(3) << "Moving mouse to " << latest_mouse_position_.x() << "," + << latest_mouse_position_.y(); + connection_.xtest().FakeInput({ + .type = x11::MotionNotifyEvent::opcode, + .detail = false, + .root = connection_.default_root(), + .rootX = latest_mouse_position_.x(), + .rootY = latest_mouse_position_.y(), + }); } } @@ -489,12 +498,11 @@ return; } - VLOG(3) << "Button " << event.button() - << " received, sending " - << (event.button_down() ? "down " : "up ") - << button_number; - XTestFakeButtonEvent(display_, button_number, event.button_down(), - x11::CurrentTime); + VLOG(3) << "Button " << event.button() << " received, sending " + << (event.button_down() ? "down " : "up ") << button_number; + auto opcode = event.button_down() ? x11::ButtonEvent::Press + : x11::ButtonEvent::Release; + connection_.xtest().FakeInput({opcode, button_number}); } // remotedesktop.google.com currently sends scroll events in pixels, which @@ -576,11 +584,10 @@ int num_buttons = XGetPointerMapping(display_, nullptr, 0); std::unique_ptr<unsigned char[]> pointer_mapping( new unsigned char[num_buttons]); - num_buttons = XGetPointerMapping(display_, pointer_mapping.get(), - num_buttons); - for (int i = 0; i < kNumPointerButtons; i++) { - pointer_button_map_[i] = -1; - } + num_buttons = + XGetPointerMapping(display_, pointer_mapping.get(), num_buttons); + for (int& i : pointer_button_map_) + i = -1; for (int i = 0; i < num_buttons; i++) { // Reverse the mapping. if (pointer_mapping[i] > 0 && pointer_mapping[i] <= kNumPointerButtons) @@ -603,46 +610,48 @@ // safe to reset this mapping, as it won't affect the user's local devices. // In fact, the reason why we do this is because an old gnome-settings-daemon // may have mistakenly applied left-handed preferences to the XTEST device. - XID device_id = 0; + uint8_t device_id = 0; bool device_found = false; - int num_devices; - XDeviceInfo* devices; - devices = XListInputDevices(display_, &num_devices); - for (int i = 0; i < num_devices; i++) { - XDeviceInfo* device_info = &devices[i]; - if (device_info->use == IsXExtensionPointer && - strcmp(device_info->name, "Virtual core XTEST pointer") == 0) { - device_id = device_info->id; - device_found = true; - break; + if (auto devices = connection_.xinput().ListInputDevices({}).Sync()) { + for (size_t i = 0; i < devices->devices.size(); i++) { + const auto& device_info = devices->devices[i]; + const std::string& name = devices->names[i].name; + if (device_info.device_use == + x11::Input::DeviceUse::IsXExtensionPointer && + name == "Virtual core XTEST pointer") { + device_id = device_info.device_id; + device_found = true; + break; + } } } - XFreeDeviceList(devices); if (!device_found) { HOST_LOG << "Cannot find XTest device."; return; } - XDevice* device = XOpenDevice(display_, device_id); + auto device = connection_.xinput().OpenDevice({device_id}).Sync(); if (!device) { LOG(ERROR) << "Cannot open XTest device."; return; } - int num_device_buttons = - XGetDeviceButtonMapping(display_, device, nullptr, 0); - std::unique_ptr<unsigned char[]> button_mapping( - new unsigned char[num_buttons]); - for (int i = 0; i < num_device_buttons; i++) { - button_mapping[i] = i + 1; + if (auto mapping = + connection_.xinput().GetDeviceButtonMapping({device_id}).Sync()) { + size_t num_device_buttons = mapping->map.size(); + std::vector<uint8_t> new_mapping; + for (size_t i = 0; i < num_device_buttons; i++) + new_mapping.push_back(i + 1); + if (!connection_.xinput() + .SetDeviceButtonMapping({device_id, new_mapping}) + .Sync()) { + LOG(ERROR) << "Failed to set XTest device button mapping"; + } } - error = XSetDeviceButtonMapping(display_, device, button_mapping.get(), - num_device_buttons); - if (error != x11::Success) - LOG(ERROR) << "Failed to set XTest device button mapping: " << error; - XCloseDevice(display_, device); + connection_.xinput().CloseDevice({device_id}); + connection_.Flush(); } int InputInjectorX11::Core::MouseButtonToX11ButtonNumber( @@ -687,8 +696,8 @@ clipboard_->Start(std::move(client_clipboard)); - character_injector_.reset( - new X11CharacterInjector(std::make_unique<X11KeyboardImpl>(display_))); + character_injector_ = std::make_unique<X11CharacterInjector>( + std::make_unique<X11KeyboardImpl>(&connection_)); // Disable auto-repeat, if necessary, to avoid triggering auto-repeat // if network congestion delays the key-up event from the client. This is
diff --git a/remoting/host/input_monitor/local_hotkey_input_monitor_x11.cc b/remoting/host/input_monitor/local_hotkey_input_monitor_x11.cc index d3accbd..169f587 100644 --- a/remoting/host/input_monitor/local_hotkey_input_monitor_x11.cc +++ b/remoting/host/input_monitor/local_hotkey_input_monitor_x11.cc
@@ -18,7 +18,10 @@ #include "base/macros.h" #include "base/sequence_checker.h" #include "base/single_thread_task_runner.h" +#include "ui/events/devices/x11/xinput_util.h" +#include "ui/gfx/x/connection.h" #include "ui/gfx/x/x11.h" +#include "ui/gfx/x/xinput.h" namespace remoting { @@ -34,7 +37,8 @@ private: // The implementation resides in LocalHotkeyInputMonitorX11::Core class. - class Core : public base::RefCountedThreadSafe<Core> { + class Core : public base::RefCountedThreadSafe<Core>, + public x11::Connection::Delegate { public: Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, @@ -45,18 +49,17 @@ private: friend class base::RefCountedThreadSafe<Core>; - ~Core(); + ~Core() override; void StartOnInputThread(); void StopOnInputThread(); // Called when there are pending X events. - void OnPendingXEvents(); + void OnConnectionData(); - // Processes key events. - void ProcessXEvent(xEvent* event); - - static void ProcessReply(XPointer self, XRecordInterceptData* data); + // x11::Connection::Delegate: + bool ShouldContinueStream() const override; + void DispatchXEvent(x11::Event* event) override; // Task runner on which public methods of this class must be called. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; @@ -76,10 +79,7 @@ // True when Ctrl is pressed. bool ctrl_pressed_ = false; - Display* display_ = nullptr; - Display* x_record_display_ = nullptr; - XRecordRange* x_record_range_ = nullptr; - XRecordContext x_record_context_ = 0; + std::unique_ptr<x11::Connection> connection_; DISALLOW_COPY_AND_ASSIGN(Core); }; @@ -132,114 +132,58 @@ } LocalHotkeyInputMonitorX11::Core::~Core() { - DCHECK(!display_); - DCHECK(!x_record_display_); - DCHECK(!x_record_range_); - DCHECK(!x_record_context_); + DCHECK(!connection_); } void LocalHotkeyInputMonitorX11::Core::StartOnInputThread() { DCHECK(input_task_runner_->BelongsToCurrentThread()); - DCHECK(!display_); - DCHECK(!x_record_display_); - DCHECK(!x_record_range_); - DCHECK(!x_record_context_); + DCHECK(!connection_); - // TODO(jamiewalch): We should pass the display in. At that point, since - // XRecord needs a private connection to the X Server for its data channel - // and both channels are used from a separate thread, we'll need to duplicate - // them with something like the following: - // XOpenDisplay(DisplayString(display)); - display_ = XOpenDisplay(nullptr); - x_record_display_ = XOpenDisplay(nullptr); - if (!display_ || !x_record_display_) { - LOG(ERROR) << "Couldn't open X display"; - return; - } + // TODO(jamiewalch): We should pass the connection in. + connection_ = std::make_unique<x11::Connection>(); - int xr_opcode, xr_event, xr_error; - if (!XQueryExtension(display_, "RECORD", &xr_opcode, &xr_event, &xr_error)) { + if (!connection_->xinput().present()) { LOG(ERROR) << "X Record extension not available."; return; } + // Let the server know the client XInput version. + connection_->xinput().XIQueryVersion( + {x11::Input::major_version, x11::Input::minor_version}); - x_record_range_ = XRecordAllocRange(); - if (!x_record_range_) { - LOG(ERROR) << "XRecordAllocRange failed."; - return; - } - x_record_range_->device_events.first = x11::KeyEvent::Press; - x_record_range_->device_events.last = x11::KeyEvent::Release; - XRecordClientSpec client_spec = XRecordAllClients; + x11::Input::XIEventMask mask; + ui::SetXinputMask(&mask, x11::Input::RawDeviceEvent::RawKeyPress); + ui::SetXinputMask(&mask, x11::Input::RawDeviceEvent::RawKeyRelease); + connection_->xinput().XISelectEvents( + {connection_->default_root(), + {{x11::Input::DeviceId::AllMaster, {mask}}}}); + connection_->Flush(); - x_record_context_ = XRecordCreateContext(x_record_display_, 0, &client_spec, - 1, &x_record_range_, 1); - if (!x_record_context_) { - LOG(ERROR) << "XRecordCreateContext failed."; - return; - } - - if (!XRecordEnableContextAsync(x_record_display_, x_record_context_, - &Core::ProcessReply, - reinterpret_cast<XPointer>(this))) { - LOG(ERROR) << "XRecordEnableContextAsync failed."; - return; - } - - // Register OnPendingXEvents() to be called every time there is - // something to read from |x_record_display_|. + // Register OnConnectionData() to be called every time there is + // something to read from |connection_|. controller_ = base::FileDescriptorWatcher::WatchReadable( - ConnectionNumber(x_record_display_), - base::BindRepeating(&Core::OnPendingXEvents, base::Unretained(this))); + ConnectionNumber(connection_->display()), + base::BindRepeating(&Core::OnConnectionData, base::Unretained(this))); // Fetch pending events if any. - while (XPending(x_record_display_)) { - XEvent ev; - XNextEvent(x_record_display_, &ev); - } + OnConnectionData(); } void LocalHotkeyInputMonitorX11::Core::StopOnInputThread() { DCHECK(input_task_runner_->BelongsToCurrentThread()); - - // Context must be disabled via the control channel because we can't send - // any X protocol traffic over the data channel while it's recording. - if (x_record_context_) { - XRecordDisableContext(display_, x_record_context_); - XFlush(display_); - } - controller_.reset(); - - if (x_record_range_) { - XFree(x_record_range_); - x_record_range_ = nullptr; - } - if (x_record_context_) { - XRecordFreeContext(x_record_display_, x_record_context_); - x_record_context_ = 0; - } - if (x_record_display_) { - XCloseDisplay(x_record_display_); - x_record_display_ = nullptr; - } - if (display_) { - XCloseDisplay(display_); - display_ = nullptr; - } + connection_.reset(); } -void LocalHotkeyInputMonitorX11::Core::OnPendingXEvents() { +void LocalHotkeyInputMonitorX11::Core::OnConnectionData() { DCHECK(input_task_runner_->BelongsToCurrentThread()); - - // Fetch pending events if any. - while (XPending(x_record_display_)) { - XEvent ev; - XNextEvent(x_record_display_, &ev); - } + connection_->Dispatch(this); } -void LocalHotkeyInputMonitorX11::Core::ProcessXEvent(xEvent* event) { +bool LocalHotkeyInputMonitorX11::Core::ShouldContinueStream() const { + return true; +} + +void LocalHotkeyInputMonitorX11::Core::DispatchXEvent(x11::Event* event) { DCHECK(input_task_runner_->BelongsToCurrentThread()); // Ignore input if we've already initiated a disconnect. @@ -247,27 +191,21 @@ return; } - int key_code = event->u.u.detail; - bool down = event->u.u.type == x11::KeyEvent::Press; - KeySym key_sym = XkbKeycodeToKeysym(display_, key_code, 0, 0); - if (key_sym == XK_Control_L || key_sym == XK_Control_R) { - ctrl_pressed_ = down; - } else if (key_sym == XK_Alt_L || key_sym == XK_Alt_R) { - alt_pressed_ = down; - } else if (key_sym == XK_Escape && down && alt_pressed_ && ctrl_pressed_) { - caller_task_runner_->PostTask(FROM_HERE, std::move(disconnect_callback_)); - } -} + auto* raw = event->As<x11::Input::RawDeviceEvent>(); + DCHECK(raw); + DCHECK(raw->opcode == x11::Input::RawDeviceEvent::RawKeyPress || + raw->opcode == x11::Input::RawDeviceEvent::RawKeyRelease); -// static -void LocalHotkeyInputMonitorX11::Core::ProcessReply( - XPointer self, - XRecordInterceptData* data) { - if (data->category == XRecordFromServer) { - xEvent* event = reinterpret_cast<xEvent*>(data->data); - reinterpret_cast<Core*>(self)->ProcessXEvent(event); - } - XRecordFreeData(data); + bool down = raw->opcode == x11::Input::RawDeviceEvent::RawKeyPress; + auto key_sym = + static_cast<uint32_t>(connection_->KeycodeToKeysym(raw->detail, 0)); + + if (key_sym == XK_Control_L || key_sym == XK_Control_R) + ctrl_pressed_ = down; + else if (key_sym == XK_Alt_L || key_sym == XK_Alt_R) + alt_pressed_ = down; + else if (key_sym == XK_Escape && down && alt_pressed_ && ctrl_pressed_) + caller_task_runner_->PostTask(FROM_HERE, std::move(disconnect_callback_)); } } // namespace
diff --git a/remoting/host/input_monitor/local_mouse_input_monitor_x11.cc b/remoting/host/input_monitor/local_mouse_input_monitor_x11.cc index 332c7b0..3f1487c 100644 --- a/remoting/host/input_monitor/local_mouse_input_monitor_x11.cc +++ b/remoting/host/input_monitor/local_mouse_input_monitor_x11.cc
@@ -19,8 +19,11 @@ #include "base/sequence_checker.h" #include "base/single_thread_task_runner.h" #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" +#include "ui/events/devices/x11/xinput_util.h" #include "ui/events/event.h" #include "ui/gfx/x/x11.h" +#include "ui/gfx/x/xinput.h" +#include "ui/gfx/x/xproto.h" namespace remoting { @@ -37,7 +40,8 @@ private: // The actual implementation resides in LocalMouseInputMonitorX11::Core class. - class Core : public base::RefCountedThreadSafe<Core> { + class Core : public base::RefCountedThreadSafe<Core>, + public x11::Connection::Delegate { public: Core(scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, scoped_refptr<base::SingleThreadTaskRunner> input_task_runner, @@ -48,18 +52,17 @@ private: friend class base::RefCountedThreadSafe<Core>; - ~Core(); + ~Core() override; void StartOnInputThread(); void StopOnInputThread(); // Called when there are pending X events. - void OnPendingXEvents(); + void OnConnectionData(); - // Processes key and mouse events. - void ProcessXEvent(xEvent* event); - - static void ProcessReply(XPointer self, XRecordInterceptData* data); + // x11::Connection::Delegate: + bool ShouldContinueStream() const override; + void DispatchXEvent(x11::Event* event) override; // Task runner on which public methods of this class must be called. scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; @@ -73,10 +76,7 @@ // Controls watching X events. std::unique_ptr<base::FileDescriptorWatcher::Controller> controller_; - Display* display_ = nullptr; - Display* x_record_display_ = nullptr; - XRecordRange* x_record_range_ = nullptr; - XRecordContext x_record_context_ = 0; + std::unique_ptr<x11::Connection> connection_; DISALLOW_COPY_AND_ASSIGN(Core); }; @@ -128,133 +128,77 @@ } LocalMouseInputMonitorX11::Core::~Core() { - DCHECK(!display_); - DCHECK(!x_record_display_); - DCHECK(!x_record_range_); - DCHECK(!x_record_context_); + DCHECK(!connection_); } void LocalMouseInputMonitorX11::Core::StartOnInputThread() { DCHECK(input_task_runner_->BelongsToCurrentThread()); - DCHECK(!display_); - DCHECK(!x_record_display_); - DCHECK(!x_record_range_); - DCHECK(!x_record_context_); + DCHECK(!connection_); - // TODO(jamiewalch): We should pass the display in. At that point, since - // XRecord needs a private connection to the X Server for its data channel - // and both channels are used from a separate thread, we'll need to duplicate - // them with something like the following: - // XOpenDisplay(DisplayString(display)); - display_ = XOpenDisplay(nullptr); - x_record_display_ = XOpenDisplay(nullptr); - if (!display_ || !x_record_display_) { - LOG(ERROR) << "Couldn't open X display"; - return; - } + // TODO(jamiewalch): We should pass the connection in. + connection_ = std::make_unique<x11::Connection>(); - int xr_opcode, xr_event, xr_error; - if (!XQueryExtension(display_, "RECORD", &xr_opcode, &xr_event, &xr_error)) { + if (!connection_->xinput().present()) { LOG(ERROR) << "X Record extension not available."; return; } + // Let the server know the client XInput version. + connection_->xinput().XIQueryVersion( + {x11::Input::major_version, x11::Input::minor_version}); - x_record_range_ = XRecordAllocRange(); - if (!x_record_range_) { - LOG(ERROR) << "XRecordAllocRange failed."; - return; - } - x_record_range_->device_events.first = MotionNotify; - x_record_range_->device_events.last = MotionNotify; - XRecordClientSpec client_spec = XRecordAllClients; + x11::Input::XIEventMask mask; + ui::SetXinputMask(&mask, x11::Input::RawDeviceEvent::RawMotion); + connection_->xinput().XISelectEvents( + {connection_->default_root(), + {{x11::Input::DeviceId::AllMaster, {mask}}}}); + connection_->Flush(); - x_record_context_ = XRecordCreateContext(x_record_display_, 0, &client_spec, - 1, &x_record_range_, 1); - if (!x_record_context_) { - LOG(ERROR) << "XRecordCreateContext failed."; - return; - } - - if (!XRecordEnableContextAsync(x_record_display_, x_record_context_, - &Core::ProcessReply, - reinterpret_cast<XPointer>(this))) { - LOG(ERROR) << "XRecordEnableContextAsync failed."; - return; - } - - // Register OnPendingXEvents() to be called every time there is - // something to read from |x_record_display_|. + // Register OnConnectionData() to be called every time there is + // something to read from |connection_|. controller_ = base::FileDescriptorWatcher::WatchReadable( - ConnectionNumber(x_record_display_), - base::BindRepeating(&Core::OnPendingXEvents, base::Unretained(this))); + ConnectionNumber(connection_->display()), + base::BindRepeating(&Core::OnConnectionData, base::Unretained(this))); // Fetch pending events if any. - while (XPending(x_record_display_)) { - XEvent ev; - XNextEvent(x_record_display_, &ev); - } + OnConnectionData(); } void LocalMouseInputMonitorX11::Core::StopOnInputThread() { DCHECK(input_task_runner_->BelongsToCurrentThread()); - - // Context must be disabled via the control channel because we can't send - // any X protocol traffic over the data channel while it's recording. - if (x_record_context_) { - XRecordDisableContext(display_, x_record_context_); - XFlush(display_); - } - controller_.reset(); - - if (x_record_range_) { - XFree(x_record_range_); - x_record_range_ = nullptr; - } - if (x_record_context_) { - XRecordFreeContext(x_record_display_, x_record_context_); - x_record_context_ = 0; - } - if (x_record_display_) { - XCloseDisplay(x_record_display_); - x_record_display_ = nullptr; - } - if (display_) { - XCloseDisplay(display_); - display_ = nullptr; - } + connection_.reset(); } -void LocalMouseInputMonitorX11::Core::OnPendingXEvents() { +void LocalMouseInputMonitorX11::Core::OnConnectionData() { + DCHECK(input_task_runner_->BelongsToCurrentThread()); + connection_->Dispatch(this); +} + +bool LocalMouseInputMonitorX11::Core::ShouldContinueStream() const { + return true; +} + +void LocalMouseInputMonitorX11::Core::DispatchXEvent(x11::Event* event) { DCHECK(input_task_runner_->BelongsToCurrentThread()); - // Fetch pending events if any. - while (XPending(x_record_display_)) { - XEvent ev; - XNextEvent(x_record_display_, &ev); - } -} + auto* raw = event->As<x11::Input::RawDeviceEvent>(); + DCHECK(raw); + DCHECK(raw->opcode == x11::Input::RawDeviceEvent::RawMotion); -void LocalMouseInputMonitorX11::Core::ProcessXEvent(xEvent* event) { - DCHECK(input_task_runner_->BelongsToCurrentThread()); - if (event->u.u.type != MotionNotify) { - return; - } - - webrtc::DesktopVector position(event->u.keyButtonPointer.rootX, - event->u.keyButtonPointer.rootY); - caller_task_runner_->PostTask( - FROM_HERE, base::BindOnce(on_mouse_move_, position, ui::ET_MOUSE_MOVED)); -} - -// static -void LocalMouseInputMonitorX11::Core::ProcessReply(XPointer self, - XRecordInterceptData* data) { - if (data->category == XRecordFromServer) { - xEvent* event = reinterpret_cast<xEvent*>(data->data); - reinterpret_cast<Core*>(self)->ProcessXEvent(event); - } - XRecordFreeData(data); + connection_->QueryPointer({connection_->default_root()}) + .OnResponse(base::BindOnce( + [](scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner, + LocalInputMonitor::PointerMoveCallback on_mouse_move, + x11::QueryPointerResponse response) { + if (!response) + return; + webrtc::DesktopVector position(response->root_x, response->root_y); + caller_task_runner->PostTask( + FROM_HERE, + base::BindOnce(on_mouse_move, position, ui::ET_MOUSE_MOVED)); + }, + caller_task_runner_, on_mouse_move_)); + connection_->Flush(); } } // namespace
diff --git a/remoting/host/linux/x11_keyboard_impl.cc b/remoting/host/linux/x11_keyboard_impl.cc index d19f744..c55bf17 100644 --- a/remoting/host/linux/x11_keyboard_impl.cc +++ b/remoting/host/linux/x11_keyboard_impl.cc
@@ -9,6 +9,7 @@ #include "remoting/host/linux/unicode_to_keysym.h" #include "ui/gfx/x/x11.h" #include "ui/gfx/x/x11_types.h" +#include "ui/gfx/x/xtest.h" namespace { @@ -30,12 +31,12 @@ }; // TODO(sergeyu): Is there a better way to find modifiers state? - for (size_t i = 0; i < base::size(kModifiersToTry); ++i) { + for (auto i : kModifiersToTry) { unsigned long key_sym_with_mods; - if (XkbLookupKeySym(display, found_keycode, kModifiersToTry[i], nullptr, + if (XkbLookupKeySym(display, found_keycode, i, nullptr, &key_sym_with_mods) && key_sym_with_mods == key_sym) { - *modifiers = kModifiersToTry[i]; + *modifiers = i; *keycode = found_keycode; return true; } @@ -47,7 +48,8 @@ namespace remoting { -X11KeyboardImpl::X11KeyboardImpl(Display* display) : display_(display) {} +X11KeyboardImpl::X11KeyboardImpl(x11::Connection* connection) + : connection_(connection), display_(connection->display()) {} X11KeyboardImpl::~X11KeyboardImpl() = default; @@ -80,8 +82,8 @@ void X11KeyboardImpl::PressKey(uint32_t keycode, uint32_t modifiers) { XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, modifiers); - XTestFakeKeyEvent(display_, keycode, x11::True, x11::CurrentTime); - XTestFakeKeyEvent(display_, keycode, x11::False, x11::CurrentTime); + connection_->xtest().FakeInput({x11::KeyEvent::Press, keycode}); + connection_->xtest().FakeInput({x11::KeyEvent::Release, keycode}); XkbLockModifiers(display_, XkbUseCoreKbd, modifiers, 0); }
diff --git a/remoting/host/linux/x11_keyboard_impl.h b/remoting/host/linux/x11_keyboard_impl.h index a803072..fef5edc 100644 --- a/remoting/host/linux/x11_keyboard_impl.h +++ b/remoting/host/linux/x11_keyboard_impl.h
@@ -14,7 +14,7 @@ class X11KeyboardImpl : public X11Keyboard { public: - X11KeyboardImpl(Display* display); + explicit X11KeyboardImpl(x11::Connection* connection); ~X11KeyboardImpl() override; // KeyboardInterface overrides. @@ -34,6 +34,7 @@ private: // X11 graphics context. + x11::Connection* connection_; Display* display_; DISALLOW_COPY_AND_ASSIGN(X11KeyboardImpl);
diff --git a/remoting/host/linux/x11_util.cc b/remoting/host/linux/x11_util.cc index 9600005..1b1b186 100644 --- a/remoting/host/linux/x11_util.cc +++ b/remoting/host/linux/x11_util.cc
@@ -6,14 +6,14 @@ #include "base/bind.h" #include "ui/gfx/x/x11.h" +#include "ui/gfx/x/xtest.h" namespace remoting { static ScopedXErrorHandler* g_handler = nullptr; -ScopedXErrorHandler::ScopedXErrorHandler(const Handler& handler): - handler_(handler), - ok_(true) { +ScopedXErrorHandler::ScopedXErrorHandler(const Handler& handler) + : handler_(handler), ok_(true) { // This is a non-exhaustive check for incorrect usage. It doesn't handle the // case where a mix of ScopedXErrorHandler and raw XSetErrorHandler calls are // used, and it disallows nested ScopedXErrorHandlers on the same thread, @@ -36,9 +36,7 @@ return 0; } - -ScopedXGrabServer::ScopedXGrabServer(Display* display) - : display_(display) { +ScopedXGrabServer::ScopedXGrabServer(Display* display) : display_(display) { XGrabServer(display_); } @@ -47,17 +45,14 @@ XFlush(display_); } -bool IgnoreXServerGrabs(Display* display, bool ignore) { - int test_event_base = 0; - int test_error_base = 0; - int major = 0; - int minor = 0; - if (!XTestQueryExtension(display, &test_event_base, &test_error_base, - &major, &minor)) { +bool IgnoreXServerGrabs(x11::Connection* connection, bool ignore) { + if (!connection->xtest() + .GetVersion({x11::Test::major_version, x11::Test::minor_version}) + .Sync()) { return false; } - XTestGrabControl(display, ignore); + connection->xtest().GrabControl({ignore}); return true; }
diff --git a/remoting/host/linux/x11_util.h b/remoting/host/linux/x11_util.h index 9a83d05..5390f12 100644 --- a/remoting/host/linux/x11_util.h +++ b/remoting/host/linux/x11_util.h
@@ -61,7 +61,7 @@ // Make a connection to the X Server impervious to X Server grabs. Returns // true if successful or false if the required XTEST extension is not present. -bool IgnoreXServerGrabs(Display* display, bool ignore); +bool IgnoreXServerGrabs(x11::Connection* connection, bool ignore); } // namespace remoting
diff --git a/remoting/proto/remoting/v1/directory_messages.proto b/remoting/proto/remoting/v1/directory_messages.proto index e55f6fd..e2a99bb0 100644 --- a/remoting/proto/remoting/v1/directory_messages.proto +++ b/remoting/proto/remoting/v1/directory_messages.proto
@@ -75,8 +75,8 @@ // Indicates whether this request is the first heartbeat from a host instance. optional bool is_initial_heartbeat = 11; - // A hash of the local hostname of the machine. - optional string hostname_hash = 12; + // Local hostname of the machine. + optional string hostname = 12; } // Sent in response to a HeartbeatRequest.
diff --git a/sandbox/policy/mac/gpu_v2.sb b/sandbox/policy/mac/gpu_v2.sb index 53b46a4e..c1ee3ca 100644 --- a/sandbox/policy/mac/gpu_v2.sb +++ b/sandbox/policy/mac/gpu_v2.sb
@@ -35,6 +35,11 @@ (allow mach-lookup (xpc-service-name "com.apple.MTLCompilerService")) ) +; Needed for VideoToolbox H.264 SW and VP9 decoding - https://crbug.com/1113936 +(if (>= os-version 1016) + (allow mach-lookup (global-name "com.apple.trustd.agent")) +) + ; Needed for WebGL - https://crbug.com/75343 (allow iokit-open (iokit-connection "IOAccelerator")
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index 6c71822..7358258 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -381,10 +381,11 @@ break; case InitiatorLockCompatibility::kNoLock: - // TODO(lukasza): https://crbug.com/1098938: Browser process should always + // TODO(lukasza): https://crbug.com/1114906: Browser process should always // specify the request_initiator_site_lock in URLLoaderFactories given to - // a renderer process. Once https://crbug.com/1098938 is fixed, the case - // below should return |false| (i.e. = bad message). + // a renderer process. Once issues blocking https://crbug.com/1114906 are + // fixed, the case below should return |false| and call + // mojo::ReportBadMessage. break; case InitiatorLockCompatibility::kNoInitiator:
diff --git a/services/network/public/cpp/empty_url_loader_client.cc b/services/network/public/cpp/empty_url_loader_client.cc index 6d869d05..ded2ca5 100644 --- a/services/network/public/cpp/empty_url_loader_client.cc +++ b/services/network/public/cpp/empty_url_loader_client.cc
@@ -26,7 +26,7 @@ mojo::PendingRemote<mojom::URLLoader> url_loader) : receiver_(&client_, std::move(receiver)), url_loader_(std::move(url_loader)) { - client_.Drain(base::BindOnce(&EmptyURLLoaderClientWrapper::DeleteSelf, + client_.Drain(base::BindOnce(&EmptyURLLoaderClientWrapper::DidDrain, base::Unretained(this))); receiver_.set_disconnect_handler(base::BindOnce( &EmptyURLLoaderClientWrapper::DeleteSelf, base::Unretained(this))); @@ -34,6 +34,11 @@ EmptyURLLoaderClientWrapper::~EmptyURLLoaderClientWrapper() = default; +void EmptyURLLoaderClientWrapper::DidDrain( + const network::URLLoaderCompletionStatus& status) { + DeleteSelf(); +} + void EmptyURLLoaderClientWrapper::DeleteSelf() { delete this; } @@ -41,15 +46,16 @@ EmptyURLLoaderClient::EmptyURLLoaderClient() = default; EmptyURLLoaderClient::~EmptyURLLoaderClient() = default; -void EmptyURLLoaderClient::Drain(base::OnceClosure callback) { +void EmptyURLLoaderClient::Drain( + base::OnceCallback<void(const URLLoaderCompletionStatus&)> callback) { DCHECK(!callback_); callback_ = std::move(callback); MaybeDone(); } void EmptyURLLoaderClient::MaybeDone() { - if (done_ && callback_) - std::move(callback_).Run(); + if (done_status_ && callback_) + std::move(callback_).Run(*done_status_); } void EmptyURLLoaderClient::OnReceiveResponse( @@ -77,7 +83,7 @@ } void EmptyURLLoaderClient::OnComplete(const URLLoaderCompletionStatus& status) { - done_ = true; + done_status_ = status; MaybeDone(); }
diff --git a/services/network/public/cpp/empty_url_loader_client.h b/services/network/public/cpp/empty_url_loader_client.h index bcff77f..5a09472 100644 --- a/services/network/public/cpp/empty_url_loader_client.h +++ b/services/network/public/cpp/empty_url_loader_client.h
@@ -14,6 +14,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/data_pipe_drainer.h" +#include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/mojom/url_loader.mojom.h" namespace network { @@ -27,7 +28,7 @@ ~EmptyURLLoaderClient() override; // Calls |callback| when the request is done. - void Drain(base::OnceClosure callback); + void Drain(base::OnceCallback<void(const URLLoaderCompletionStatus&)>); private: void MaybeDone(); @@ -51,8 +52,8 @@ std::unique_ptr<mojo::DataPipeDrainer> response_body_drainer_; - bool done_ = false; - base::OnceClosure callback_; + base::Optional<URLLoaderCompletionStatus> done_status_; + base::OnceCallback<void(const URLLoaderCompletionStatus&)> callback_; DISALLOW_COPY_AND_ASSIGN(EmptyURLLoaderClient); }; @@ -75,6 +76,7 @@ mojo::PendingReceiver<mojom::URLLoaderClient> receiver, mojo::PendingRemote<mojom::URLLoader> url_loader); + void DidDrain(const network::URLLoaderCompletionStatus& status); void DeleteSelf(); EmptyURLLoaderClient client_;
diff --git a/services/network/public/cpp/initiator_lock_compatibility.cc b/services/network/public/cpp/initiator_lock_compatibility.cc index ace72cf5..50f60c4 100644 --- a/services/network/public/cpp/initiator_lock_compatibility.cc +++ b/services/network/public/cpp/initiator_lock_compatibility.cc
@@ -30,32 +30,17 @@ return InitiatorLockCompatibility::kNoInitiator; const url::Origin& initiator = request_initiator.value(); - // TODO(lukasza, nasko): Also consider equality of precursor origins (e.g. if - // |initiator| is opaque, then it's precursor origin should match the |lock| - // [or |lock|'s precursor if |lock| is also opaque]). - if (initiator.opaque() || (initiator == lock)) + if (initiator == lock) return InitiatorLockCompatibility::kCompatibleLock; - // TODO(lukasza): https://crbug.com/1098938: Return kIncorrectLock if - // the origins do not match exactly in the previous if statement. This should - // be possible to do once we no longer vend process-wide factory. - if (!initiator.opaque() && !lock.opaque() && - initiator.scheme() == lock.scheme() && - initiator.GetURL().SchemeIsHTTPOrHTTPS()) { - if (initiator.GetURL().HostIsIPAddress()) { - // For IP addresses, we require host equality (allowing ports to differ, - // since site_url ignores ports). See also https://crbug.com/1051674. - if (initiator.host() == lock.host()) - return InitiatorLockCompatibility::kCompatibleLock; - } else { - // For non-IP-address origins, we require sites (eTLD+1) to match - // (again ignoring ports). - std::string lock_domain = lock.host(); - if (!lock_domain.empty() && lock_domain.back() == '.') - lock_domain.erase(lock_domain.length() - 1); - if (initiator.DomainIs(lock_domain)) - return InitiatorLockCompatibility::kCompatibleLock; - } + // Opaque |initiator| is always allowed. In particular, a factory locked to a + // non-opaque |lock| may be used by an opaque |initiator| - for example when + // the factory is inherited by a data: URL frame. + if (initiator.opaque()) { + // TODO(lukasza, nasko): Also consider equality of precursor origins (e.g. + // if |initiator| is opaque, then it's precursor origin should match the + // |lock| [or |lock|'s precursor if |lock| is also opaque]). + return InitiatorLockCompatibility::kCompatibleLock; } return InitiatorLockCompatibility::kIncorrectLock;
diff --git a/services/network/public/cpp/initiator_lock_compatibility_unittest.cc b/services/network/public/cpp/initiator_lock_compatibility_unittest.cc index 769a9ef..bc203315 100644 --- a/services/network/public/cpp/initiator_lock_compatibility_unittest.cc +++ b/services/network/public/cpp/initiator_lock_compatibility_unittest.cc
@@ -66,24 +66,19 @@ EXPECT_EQ(InitiatorLockCompatibility::kIncorrectLock, VerifyRequestInitiatorLock(foo_example_com, bar_example_com)); - // Site-URL-based comparisons. - // - // TODO(lukasza): These should result in kIncorrectLock eventually (once - // request_initiator_site_lock becomes request_initiator_origin_lock - see - // https://crbug.com/1098938. - EXPECT_EQ(InitiatorLockCompatibility::kCompatibleLock, + // Site != origin. + EXPECT_EQ(InitiatorLockCompatibility::kIncorrectLock, VerifyRequestInitiatorLock(example_com, bar_foo_example_com)); - EXPECT_EQ(InitiatorLockCompatibility::kCompatibleLock, + EXPECT_EQ(InitiatorLockCompatibility::kIncorrectLock, VerifyRequestInitiatorLock(foo_example_com, bar_foo_example_com)); EXPECT_EQ( - InitiatorLockCompatibility::kCompatibleLock, + InitiatorLockCompatibility::kIncorrectLock, VerifyRequestInitiatorLock(ip_origin1, ip_origin1_with_different_port)); - // The trailing dot is not important (at least for site-URL-based - // comparisons). - EXPECT_EQ(InitiatorLockCompatibility::kCompatibleLock, + // The trailing dot. + EXPECT_EQ(InitiatorLockCompatibility::kIncorrectLock, VerifyRequestInitiatorLock(foo_example_com_dot, foo_example_com)); - EXPECT_EQ(InitiatorLockCompatibility::kCompatibleLock, + EXPECT_EQ(InitiatorLockCompatibility::kIncorrectLock, VerifyRequestInitiatorLock(foo_example_com, foo_example_com_dot)); }
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 2c5f258..cd3e4ca3 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -601,8 +601,14 @@ // If specified, then |request_initiator_site_lock| locks // |ResourceRequest::request_initiator| to the specified origin. - // TODO(lukasza): https://crbug.com/1098938: 1) Make this non-optional, - // 2) Make this an *origin* lock (rather than a *site* lock). + // + // SECURITY NOTE: |request_initiator_site_lock| should be present in all + // factories that may be vended to a Renderer process. + // |request_initiator_site_lock| may be missing only in factories used by the + // Browser process. + // + // TODO(lukasza): https://crbug.com/918967: Make this an *origin* lock + // (rather than a *site* lock). url.mojom.Origin? request_initiator_site_lock; // Cross-origin read blocking (CORB) configuration.
diff --git a/services/network/public/mojom/url_loader_factory.mojom b/services/network/public/mojom/url_loader_factory.mojom index 8fecf02..b141eff 100644 --- a/services/network/public/mojom/url_loader_factory.mojom +++ b/services/network/public/mojom/url_loader_factory.mojom
@@ -8,27 +8,48 @@ import "services/network/public/mojom/url_loader.mojom"; const uint32 kURLLoadOptionNone = 0; + // Sends the net::SSLInfo struct in OnReceiveResponse. const uint32 kURLLoadOptionSendSSLInfoWithResponse = 1; + // Enables mime sniffing. const uint32 kURLLoadOptionSniffMimeType = 2; + // Indicates that execution is blocking on the completion of the request. const uint32 kURLLoadOptionSynchronous = 4; + // Sends the net::SSLInfo struct in OnComplete when the connection had a major // certificate error. const uint32 kURLLoadOptionSendSSLInfoForCertificateError = 8; + // Uses the header client set in URLLoaderFactoryParams for this request. const uint32 kURLLoadOptionUseHeaderClient = 16; + // Disallow the request from sending cookies. Disallow the response from writing // cookies. const uint32 kURLLoadOptionBlockAllCookies = 32; + // Similar to |kURLLoadOptionBlockAllCookies|, but only for third party cookies. const uint32 kURLLoadOptionBlockThirdPartyCookies = 64; + // This request is for CORS preflight. This is used in the network service. // This is set and used only in the network service, no callsites outside the // service must set this. const uint32 kURLLoadOptionAsCorsPreflight = 128; +// Specifies that the request must not be made to a non-public IP address. This +// option is needed even with CORS-RFC1918 because CORS-RFC1918 is not enabled +// by default, and sometimes the client security state is not known as the time +// of the request, which skips CORS-RFC1918. +// +// This option is supported by the network service, but might not be supported +// by other URLLoaderFactory implementations. +// +// TODO(crbug.com/1115776): This option can be removed if CORS-RFC1918 ships +// without a feature flag, and additionally it changes to block requests by +// default if the security state is unknown. +const uint32 kURLLoadOptionBlockLocalRequest = 256; + // URLLoaderFactory is an interface for requesting URLs. It creates URLLoader // instances. One URLLoader instance can load one URL. interface URLLoaderFactory {
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 9586b77..c209506 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -993,6 +993,15 @@ // to make requests to the remote endpoint. // See the CORS-RFC1918 spec: https://wicg.github.io/cors-rfc1918. + const mojom::IPAddressSpace remote_address_space = + IPAddressToIPAddressSpace(info.endpoint.address()); + if (options_ & mojom::kURLLoadOptionBlockLocalRequest && + IsLessPublicAddressSpace(remote_address_space, + network::mojom::IPAddressSpace::kPublic)) { + DVLOG(1) << "Explicitly disallowing local request."; + return net::ERR_INSECURE_PRIVATE_NETWORK_REQUEST; + } + const mojom::ClientSecurityStatePtr& security_state = factory_params_->client_security_state; if (!security_state) { @@ -1012,8 +1021,6 @@ // are initiated from insecure contexts. This prevents malicious public // websites from making requests to someone's printer, for example. - const mojom::IPAddressSpace remote_address_space = - IPAddressToIPAddressSpace(info.endpoint.address()); const bool is_endpoint_less_public = IsLessPublicAddressSpace( remote_address_space, security_state->ip_address_space);
diff --git a/services/service_manager/embedder/set_process_title.cc b/services/service_manager/embedder/set_process_title.cc index ca614cc..ae234fa 100644 --- a/services/service_manager/embedder/set_process_title.cc +++ b/services/service_manager/embedder/set_process_title.cc
@@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Define _GNU_SOURCE to ensure that <error.h> defines +// Define _GNU_SOURCE to ensure that <errno.h> defines // program_invocation_short_name. Keep this at the top of the file since some -// system headers might include <error.h> and the header could be skipped on +// system headers might include <errno.h> and the header could be skipped on // subsequent includes. #if defined(OS_LINUX) && !defined(_GNU_SOURCE) #define _GNU_SOURCE @@ -27,7 +27,7 @@ #endif // defined(OS_POSIX) && !defined(OS_MAC) && !defined(OS_SOLARIS) #if defined(OS_LINUX) -#include <error.h> // Get program_invocation_short_name declaration. +#include <errno.h> // Get program_invocation_short_name declaration. #include <sys/prctl.h> #include "base/files/file_path.h"
diff --git a/services/viz/public/cpp/compositing/mojom_traits_perftest.cc b/services/viz/public/cpp/compositing/mojom_traits_perftest.cc index 06c11c0d..91fd73a 100644 --- a/services/viz/public/cpp/compositing/mojom_traits_perftest.cc +++ b/services/viz/public/cpp/compositing/mojom_traits_perftest.cc
@@ -27,7 +27,7 @@ namespace viz { namespace { -static const int kTimeLimitMillis = 2000; +static const auto kTimeLimit = base::TimeDelta::FromSeconds(2); static const int kNumWarmupRuns = 20; static const int kTimeCheckInterval = 10; @@ -74,8 +74,7 @@ } base::TimeTicks start = base::TimeTicks::Now(); - base::TimeTicks end = - start + base::TimeDelta::FromMilliseconds(kTimeLimitMillis); + base::TimeTicks end = start + kTimeLimit; base::TimeTicks now = start; base::TimeDelta min_time; size_t count = 0; @@ -99,7 +98,7 @@ reporter.AddResult(kMetricStructDeserializationTimeUs, min_time.InMicrosecondsF() / kTimeCheckInterval); reporter.AddResult(kMetricStructDeserializationThroughputRunsPerS, - count * 1000 / kTimeLimitMillis); + count * kTimeLimit.ToHz()); } static void RunSerializationTestStructTraits( @@ -112,8 +111,7 @@ } base::TimeTicks start = base::TimeTicks::Now(); - base::TimeTicks end = - start + base::TimeDelta::FromMilliseconds(kTimeLimitMillis); + base::TimeTicks end = start + kTimeLimit; base::TimeTicks now = start; base::TimeDelta min_time; size_t count = 0; @@ -136,7 +134,7 @@ reporter.AddResult(kMetricStructSerializationTimeUs, min_time.InMicrosecondsF() / kTimeCheckInterval); reporter.AddResult(kMetricStructSerializationThroughputRunsPerS, - count * 1000 / kTimeLimitMillis); + count * kTimeLimit.ToHz()); } static void RunComplexCompositorFrameTest(const std::string& story) {
diff --git a/sql/BUILD.gn b/sql/BUILD.gn index fe45f1db..c7fd00f 100644 --- a/sql/BUILD.gn +++ b/sql/BUILD.gn
@@ -38,6 +38,10 @@ "recover_module/table.h", "recovery.cc", "recovery.h", + "sandboxed_vfs.cc", + "sandboxed_vfs.h", + "sandboxed_vfs_file.cc", + "sandboxed_vfs_file.h", "sql_features.cc", "sql_features.h", "sql_memory_dump_provider.cc",
diff --git a/sql/sandboxed_vfs.cc b/sql/sandboxed_vfs.cc new file mode 100644 index 0000000..906a11c6 --- /dev/null +++ b/sql/sandboxed_vfs.cc
@@ -0,0 +1,259 @@ +// 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 "sql/sandboxed_vfs.h" + +#include <algorithm> +#include <cstring> +#include <string> +#include <utility> +#include <vector> + +#include "base/check_op.h" +#include "base/files/file.h" +#include "base/no_destructor.h" +#include "base/notreached.h" +#include "base/stl_util.h" +#include "base/threading/platform_thread.h" +#include "build/build_config.h" +#include "sql/initialization.h" +#include "sql/sandboxed_vfs_file.h" +#include "third_party/sqlite/sqlite3.h" + +namespace sql { + +namespace { + +// Extracts the SandboxedVfs* stashed in a SQLite VFS structure. +SandboxedVfs& SandboxedVfsFromSqliteVfs(sqlite3_vfs& vfs) { + return *reinterpret_cast<SandboxedVfs*>(vfs.pAppData); +} + +int SandboxedVfsOpen(sqlite3_vfs* vfs, + const char* full_path, + sqlite3_file* result_file, + int requested_flags, + int* granted_flags) { + return SandboxedVfsFromSqliteVfs(*vfs).Open(full_path, *result_file, + requested_flags, granted_flags); +} +int SandboxedVfsDelete(sqlite3_vfs* vfs, const char* full_path, int sync_dir) { + return SandboxedVfsFromSqliteVfs(*vfs).Delete(full_path, sync_dir); +} +int SandboxedVfsAccess(sqlite3_vfs* vfs, + const char* full_path, + int flags, + int* result) { + return SandboxedVfsFromSqliteVfs(*vfs).Access(full_path, flags, *result); +} +int SandboxedVfsFullPathname(sqlite3_vfs* vfs, + const char* file_path, + int result_size, + char* result) { + return SandboxedVfsFromSqliteVfs(*vfs).FullPathname(file_path, result_size, + result); +} +int SandboxedVfsRandomness(sqlite3_vfs* vfs, int result_size, char* result) { + return SandboxedVfsFromSqliteVfs(*vfs).Randomness(result_size, result); +} +int SandboxedVfsSleep(sqlite3_vfs* vfs, int microseconds) { + return SandboxedVfsFromSqliteVfs(*vfs).Sleep(microseconds); +} +int SandboxedVfsGetLastError(sqlite3_vfs* vfs, + int message_size, + char* message) { + return SandboxedVfsFromSqliteVfs(*vfs).GetLastError(message_size, message); +} +int SandboxedVfsCurrentTimeInt64(sqlite3_vfs* vfs, sqlite3_int64* result_ms) { + return SandboxedVfsFromSqliteVfs(*vfs).CurrentTimeInt64(result_ms); +} + +sqlite3_vfs SqliteVfsFor(SandboxedVfs* sandboxed_vfs, const char* name) { + DCHECK_EQ(sandboxed_vfs, reinterpret_cast<SandboxedVfs*>( + reinterpret_cast<void*>(sandboxed_vfs))) + << "This implementation round-trips SandboxedVfs* via void*"; + + // VFS API entry points are listed at https://www.sqlite.org/c3ref/vfs.html + static constexpr int kSqliteVfsApiVersion = 3; + + // Maximum file path size. + // TODO(pwnall): Obtain this from //base or some other good place. + static constexpr int kSqliteMaxPathSize = 512; + + return { + kSqliteVfsApiVersion, + sizeof(SandboxedVfsFileSqliteBridge), + kSqliteMaxPathSize, + /*pNext=*/nullptr, + name, + /*pAppData=*/reinterpret_cast<void*>(sandboxed_vfs), + SandboxedVfsOpen, + SandboxedVfsDelete, + SandboxedVfsAccess, + SandboxedVfsFullPathname, + /*xDlOpen=*/nullptr, + /*xDlError=*/nullptr, + /*xDlSym=*/nullptr, + /*xDlClose=*/nullptr, + SandboxedVfsRandomness, + SandboxedVfsSleep, + /*xCurrentTime=*/nullptr, // Deprecated in API versions 2 and above. + SandboxedVfsGetLastError, + SandboxedVfsCurrentTimeInt64, + /*xSetSystemCall=*/nullptr, + /*xGetSystemCall=*/nullptr, + /*xNextSystemCall=*/nullptr, + }; +} + +// SQLite measures time according to the Julian calendar. +base::Time SqliteEpoch() { + constexpr const double kMicroSecondsPerDay = 24 * 60 * 60 * 1000; + // The ".5" is intentional -- days in the Julian calendar start at noon. + // The offset is in the SQLite source code (os_unix.c) multiplied by 10. + constexpr const double kUnixEpochAsJulianDay = 2440587.5; + + return base::Time::FromJsTime(-kUnixEpochAsJulianDay * kMicroSecondsPerDay); +} + +} // namespace + +// static +void SandboxedVfs::Register(const char* name, + std::unique_ptr<Delegate> delegate, + bool make_default) { + static base::NoDestructor<std::vector<SandboxedVfs*>> + registered_vfs_instances; + sql::EnsureSqliteInitialized(); + registered_vfs_instances->push_back( + new SandboxedVfs(name, std::move(delegate), make_default)); +} + +int SandboxedVfs::Open(const char* full_path, + sqlite3_file& result_file, + int requested_flags, + int* granted_flags) { + base::FilePath file_path = base::FilePath::FromUTF8Unsafe(full_path); + base::File file = delegate_->OpenFile(file_path, requested_flags); + if (!file.IsValid()) { + // TODO(pwnall): Figure out if we can remove the fallback to read-only. + if (!(requested_flags & SQLITE_OPEN_READWRITE)) { + // The SQLite API requires that pMethods is set to null even if the open + // call returns a failure status. + result_file.pMethods = nullptr; + return SQLITE_CANTOPEN; + } + + int new_flags = + (requested_flags & ~SQLITE_OPEN_READWRITE) | SQLITE_OPEN_READONLY; + return Open(full_path, result_file, new_flags, granted_flags); + } + + SandboxedVfsFile::Create(std::move(file), std::move(file_path), this, + result_file); + if (granted_flags) + *granted_flags = requested_flags; + return SQLITE_OK; +} + +int SandboxedVfs::Delete(const char* full_path, int sync_dir) { + DCHECK(full_path); + return delegate_->DeleteFile(base::FilePath::FromUTF8Unsafe(full_path), + sync_dir == 1); +} + +int SandboxedVfs::Access(const char* full_path, int flags, int& result) { + DCHECK(full_path); + base::Optional<PathAccessInfo> access = + delegate_->GetPathAccess(base::FilePath::FromUTF8Unsafe(full_path)); + if (!access) { + result = 0; + return SQLITE_OK; + } + + switch (flags) { + case SQLITE_ACCESS_EXISTS: + result = 1; + break; + case SQLITE_ACCESS_READ: + result = access->can_read ? 1 : 0; + break; + case SQLITE_ACCESS_READWRITE: + result = (access->can_read && access->can_write) ? 1 : 0; + break; + default: + NOTREACHED() << "Unsupported xAccess flags: " << flags; + return SQLITE_ERROR; + } + return SQLITE_OK; +} + +int SandboxedVfs::FullPathname(const char* file_path, + int result_size, + char* result) { + DCHECK(file_path); + DCHECK_GT(result_size, 0); + DCHECK(result); + + // Renderer processes cannot access files directly, so it doesn't make sense + // to expose full paths here. + size_t file_path_size = std::strlen(file_path) + 1; + if (static_cast<size_t>(result_size) < file_path_size) + return SQLITE_CANTOPEN; + std::memcpy(result, file_path, file_path_size); + return SQLITE_OK; +} + +int SandboxedVfs::Randomness(int result_size, char* result) { + DCHECK_GT(result_size, 0); + DCHECK(result); + + // TODO(pwnall): Figure out if we need a real implementation. + std::memset(result, 0, result_size); + return result_size; +} + +int SandboxedVfs::Sleep(int microseconds) { + DCHECK_GE(microseconds, 0); + base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(microseconds)); + return SQLITE_OK; +} + +int SandboxedVfs::GetLastError(int message_size, char* message) const { + DCHECK_GE(message_size, 0); + DCHECK(message_size == 0 || message); + + std::string error_string = base::File::ErrorToString(last_error_); + size_t error_string_size = error_string.length() + 1; + size_t copy_length = + std::min(static_cast<size_t>(message_size), error_string_size); + std::memcpy(message, error_string.c_str(), copy_length); + // The return value is zero if the message fits in the buffer, and non-zero if + // it does not fit. + return copy_length != error_string_size; +} + +int SandboxedVfs::CurrentTimeInt64(sqlite3_int64* result_ms) { + DCHECK(result_ms); + + base::TimeDelta delta = base::Time::Now() - sqlite_epoch_; + *result_ms = delta.InMilliseconds(); + return SQLITE_OK; +} + +SandboxedVfs::SandboxedVfs(const char* name, + std::unique_ptr<Delegate> delegate, + bool make_default) + : sandboxed_vfs_(SqliteVfsFor(this, name)), + sqlite_epoch_(SqliteEpoch()), + delegate_(std::move(delegate)), + last_error_(base::File::FILE_OK) { + // The register function returns a SQLite status as an int. The status is + // ignored here. If registration fails, we'd want to report the error while + // attempting to open a database. This is exactly what will happen, because + // SQLite won't find the VFS we're asking for. + sqlite3_vfs_register(&sandboxed_vfs_, make_default ? 1 : 0); +} + +} // namespace sql
diff --git a/sql/sandboxed_vfs.h b/sql/sandboxed_vfs.h new file mode 100644 index 0000000..9a29d63 --- /dev/null +++ b/sql/sandboxed_vfs.h
@@ -0,0 +1,115 @@ +// 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 SQL_SANDBOXED_VFS_H_ +#define SQL_SANDBOXED_VFS_H_ + +#include <stdint.h> + +#include <memory> + +#include "base/component_export.h" +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/optional.h" +#include "third_party/sqlite/sqlite3.h" + +namespace sql { + +// SQLite VFS implementation for use within a typical Chromium sandbox +// environment. Instances are thread-friendly. +class COMPONENT_EXPORT(SQL) SandboxedVfs { + public: + // Describes access rights for a path, used by Delegate::GetPathAccess below. + struct PathAccessInfo { + bool can_read = false; + bool can_write = false; + }; + + // Interface which must be implemented by the environment using a + // SandboxedVfs. This abstracts a handful of operations that don't typically + // work in a sandbox environment given a typical naive implementation. + // + // Instances must be thread-friendly, as methods may be called from any + // thread. + class Delegate { + public: + virtual ~Delegate() = default; + + // Opens a file at the given `file_path`. `sqlite_requested_flags` is a + // bitwise combination SQLite flags used when opening files. Returns the + // opened File on success, or an invalid File on failure. + virtual base::File OpenFile(const base::FilePath& file_path, + int sqlite_requested_flags) = 0; + + // Deletes a file at the given `file_path`. If `sync_dir` is true, the + // implementation should synchronize the containing directory contents if + // possible. Returns an SQLite error code indicating the status of the + // operation. + virtual int DeleteFile(const base::FilePath& file_path, bool sync_dir) = 0; + + // Queries path access information for `file_path`. Returns null if the + // given path does not exist. + virtual base::Optional<PathAccessInfo> GetPathAccess( + const base::FilePath& file_path) = 0; + + // Resizes the file at `file_path` (opened in `file`) to `size` bytes, + // returning true if successful and false otherwise. Implementations may + // want to operate on the filesystem via `file_path`, or modify `file` + // directly if possible. + // + // Note that if this is called by the VFS, it's because a direct call to + // SetLength on `file` has already failed. The implementation should not + // attempt to repeat this. + virtual bool SetFileLength(const base::FilePath& file_path, + base::File& file, + size_t size) = 0; + }; + + // We don't allow SandboxedVfs instances to be destroyed. Once created, they + // are permanently registered in the calling process. + ~SandboxedVfs() = delete; + + // Constructs a new instance of ths object using `delegate` to support various + // operations from within the sandbox. The VFS is registered with SQLite under + // `name` and if `make_default` is true then the VFS is also set as the global + // default for new database instances within the calling process. + // + // Note that `name` must be globally unique to the calling process. + static void Register(const char* name, + std::unique_ptr<Delegate> delegate, + bool make_default); + + Delegate* delegate() const { return delegate_.get(); } + + // sqlite3_vfs implementation. + int Open(const char* full_path, + sqlite3_file& result_file, + int requested_flags, + int* granted_flags); + int Delete(const char* full_path, int sync_dir); + int Access(const char* full_path, int flags, int& result); + int FullPathname(const char* file_path, int result_size, char* result); + int Randomness(int result_size, char* result); + int Sleep(int microseconds); + int GetLastError(int message_size, char* message) const; + int CurrentTimeInt64(sqlite3_int64* result_ms); + + // Used by SandboxedVfsFile. + void SetLastError(base::File::Error error) { this->last_error_ = error; } + + private: + SandboxedVfs(const char* name, + std::unique_ptr<Delegate> delegate, + bool make_default); + + sqlite3_vfs sandboxed_vfs_; + const base::Time sqlite_epoch_; + const std::unique_ptr<Delegate> delegate_; + base::File::Error last_error_; +}; + +} // namespace sql + +#endif // SQL_SANDBOXED_VFS_H_
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.cc b/sql/sandboxed_vfs_file.cc similarity index 83% rename from third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.cc rename to sql/sandboxed_vfs_file.cc index 3c5c068..26d144e 100644 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.cc +++ b/sql/sandboxed_vfs_file.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 "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.h" +#include "sql/sandboxed_vfs_file.h" #include <atomic> #include <cstring> @@ -15,85 +15,83 @@ #include "base/threading/platform_thread.h" #include "build/build_config.h" #include "sql/initialization.h" -#include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h" -#include "third_party/blink/renderer/modules/webdatabase/web_database_host.h" +#include "sql/sandboxed_vfs.h" #include "third_party/sqlite/sqlite3.h" -namespace blink { +namespace sql { namespace { int SandboxedClose(sqlite3_file* file) { - return SandboxedVfsFile::FromSqliteFile(file)->Close(); + return SandboxedVfsFile::FromSqliteFile(*file).Close(); } int SandboxedRead(sqlite3_file* file, void* buffer, int size, sqlite3_int64 offset) { - return SandboxedVfsFile::FromSqliteFile(file)->Read(buffer, size, offset); + return SandboxedVfsFile::FromSqliteFile(*file).Read(buffer, size, offset); } int SandboxedWrite(sqlite3_file* file, const void* buffer, int size, sqlite3_int64 offset) { - return SandboxedVfsFile::FromSqliteFile(file)->Write(buffer, size, offset); + return SandboxedVfsFile::FromSqliteFile(*file).Write(buffer, size, offset); } int SandboxedTruncate(sqlite3_file* file, sqlite3_int64 size) { - return SandboxedVfsFile::FromSqliteFile(file)->Truncate(size); + return SandboxedVfsFile::FromSqliteFile(*file).Truncate(size); } int SandboxedSync(sqlite3_file* file, int flags) { - return SandboxedVfsFile::FromSqliteFile(file)->Sync(flags); + return SandboxedVfsFile::FromSqliteFile(*file).Sync(flags); } int SandboxedFileSize(sqlite3_file* file, sqlite3_int64* result_size) { - return SandboxedVfsFile::FromSqliteFile(file)->FileSize(result_size); + return SandboxedVfsFile::FromSqliteFile(*file).FileSize(result_size); } int SandboxedLock(sqlite3_file* file, int mode) { - return SandboxedVfsFile::FromSqliteFile(file)->Lock(mode); + return SandboxedVfsFile::FromSqliteFile(*file).Lock(mode); } int SandboxedUnlock(sqlite3_file* file, int mode) { - return SandboxedVfsFile::FromSqliteFile(file)->Unlock(mode); + return SandboxedVfsFile::FromSqliteFile(*file).Unlock(mode); } int SandboxedCheckReservedLock(sqlite3_file* file, int* has_reserved_lock) { - return SandboxedVfsFile::FromSqliteFile(file)->CheckReservedLock( + return SandboxedVfsFile::FromSqliteFile(*file).CheckReservedLock( has_reserved_lock); } int SandboxedFileControl(sqlite3_file* file, int opcode, void* data) { - return SandboxedVfsFile::FromSqliteFile(file)->FileControl(opcode, data); + return SandboxedVfsFile::FromSqliteFile(*file).FileControl(opcode, data); } int SandboxedSectorSize(sqlite3_file* file) { - return SandboxedVfsFile::FromSqliteFile(file)->SectorSize(); + return SandboxedVfsFile::FromSqliteFile(*file).SectorSize(); } int SandboxedDeviceCharacteristics(sqlite3_file* file) { - return SandboxedVfsFile::FromSqliteFile(file)->DeviceCharacteristics(); + return SandboxedVfsFile::FromSqliteFile(*file).DeviceCharacteristics(); } int SandboxedShmMap(sqlite3_file* file, int page_index, int page_size, int extend_file_if_needed, void volatile** result) { - return SandboxedVfsFile::FromSqliteFile(file)->ShmMap( + return SandboxedVfsFile::FromSqliteFile(*file).ShmMap( page_index, page_size, extend_file_if_needed, result); } int SandboxedShmLock(sqlite3_file* file, int offset, int size, int flags) { - return SandboxedVfsFile::FromSqliteFile(file)->ShmLock(offset, size, flags); + return SandboxedVfsFile::FromSqliteFile(*file).ShmLock(offset, size, flags); } void SandboxedShmBarrier(sqlite3_file* file) { - SandboxedVfsFile::FromSqliteFile(file)->ShmBarrier(); + SandboxedVfsFile::FromSqliteFile(*file).ShmBarrier(); } int SandboxedShmUnmap(sqlite3_file* file, int also_delete_file) { - return SandboxedVfsFile::FromSqliteFile(file)->ShmUnmap(also_delete_file); + return SandboxedVfsFile::FromSqliteFile(*file).ShmUnmap(also_delete_file); } int SandboxedFetch(sqlite3_file* file, sqlite3_int64 offset, int size, void** result) { - return SandboxedVfsFile::FromSqliteFile(file)->Fetch(offset, size, result); + return SandboxedVfsFile::FromSqliteFile(*file).Fetch(offset, size, result); } int SandboxedUnfetch(sqlite3_file* file, sqlite3_int64 offset, void* fetch_result) { - return SandboxedVfsFile::FromSqliteFile(file)->Unfetch(offset, fetch_result); + return SandboxedVfsFile::FromSqliteFile(*file).Unfetch(offset, fetch_result); } const sqlite3_io_methods* GetSqliteIoMethods() { @@ -130,19 +128,20 @@ // static void SandboxedVfsFile::Create(base::File file, - String file_name, + base::FilePath file_path, SandboxedVfs* vfs, - sqlite3_file* buffer) { - SandboxedVfsFileSqliteBridge* bridge = + sqlite3_file& buffer) { + SandboxedVfsFileSqliteBridge& bridge = SandboxedVfsFileSqliteBridge::FromSqliteFile(buffer); - bridge->blink_file = - new SandboxedVfsFile(std::move(file), std::move(file_name), vfs); - bridge->sqlite_file.pMethods = GetSqliteIoMethods(); + bridge.sandboxed_vfs_file = + new SandboxedVfsFile(std::move(file), std::move(file_path), vfs); + bridge.sqlite_file.pMethods = GetSqliteIoMethods(); } // static -SandboxedVfsFile* SandboxedVfsFile::FromSqliteFile(sqlite3_file* sqlite_file) { - return SandboxedVfsFileSqliteBridge::FromSqliteFile(sqlite_file)->blink_file; +SandboxedVfsFile& SandboxedVfsFile::FromSqliteFile(sqlite3_file& sqlite_file) { + return *SandboxedVfsFileSqliteBridge::FromSqliteFile(sqlite_file) + .sandboxed_vfs_file; } int SandboxedVfsFile::Close() { @@ -216,16 +215,18 @@ if (file_.SetLength(size)) return SQLITE_OK; - // On Mac and Linux, the renderer sandbox blocks ftruncate(), so we have to - // use a sync mojo IPC to ask the browser process to call ftruncate() for us. + // On Mac, the default sandbox blocks ftruncate(), so we have to use a sync + // mojo IPC to ask the browser process to call ftruncate() for us. // - // TODO(pwnall): Figure out if we can allow ftruncate() in the renderer. It - // would be useful for low-level storage APIs, like the upcoming - // filesystem API. - if (!WebDatabaseHost::GetInstance().SetFileSize(file_name_, size)) - return SQLITE_IOERR_TRUNCATE; + // TODO(crbug.com/1084565): Figure out if we can allow ftruncate() in renderer + // and utility processes. It would be useful for low-level storage APIs, like + // the upcoming filesystem API. + if (vfs_->delegate()->SetFileLength(file_path_, file_, + static_cast<size_t>(size))) { + return SQLITE_OK; + } - return SQLITE_OK; + return SQLITE_IOERR_TRUNCATE; } int SandboxedVfsFile::Sync(int flags) { @@ -508,28 +509,28 @@ } SandboxedVfsFile::SandboxedVfsFile(base::File file, - String file_name, + base::FilePath file_path, SandboxedVfs* vfs) : file_(std::move(file)), sqlite_lock_mode_(SQLITE_LOCK_NONE), vfs_(vfs), - file_name_(std::move(file_name)) {} + file_path_(std::move(file_path)) {} SandboxedVfsFile::~SandboxedVfsFile() = default; // static -SandboxedVfsFileSqliteBridge* SandboxedVfsFileSqliteBridge::FromSqliteFile( - sqlite3_file* sqlite_file) { +SandboxedVfsFileSqliteBridge& SandboxedVfsFileSqliteBridge::FromSqliteFile( + sqlite3_file& sqlite_file) { static_assert(std::is_standard_layout<SandboxedVfsFileSqliteBridge>::value, "needed for the reinterpret_cast below"); static_assert(offsetof(SandboxedVfsFileSqliteBridge, sqlite_file) == 0, "sqlite_file must be the first member of the struct."); - SandboxedVfsFileSqliteBridge* bridge = - reinterpret_cast<SandboxedVfsFileSqliteBridge*>(sqlite_file); - DCHECK_EQ(sqlite_file, &bridge->sqlite_file) + SandboxedVfsFileSqliteBridge& bridge = + reinterpret_cast<SandboxedVfsFileSqliteBridge&>(sqlite_file); + DCHECK_EQ(&sqlite_file, &bridge.sqlite_file) << "assumed by the reinterpret_casts in the implementation"; return bridge; } -} // namespace blink +} // namespace sql
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.h b/sql/sandboxed_vfs_file.h similarity index 71% rename from third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.h rename to sql/sandboxed_vfs_file.h index d2b95a0..292bf71 100644 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.h +++ b/sql/sandboxed_vfs_file.h
@@ -2,20 +2,18 @@ // 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_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_FILE_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_FILE_H_ +#ifndef SQL_SANDBOXED_VFS_FILE_H_ +#define SQL_SANDBOXED_VFS_FILE_H_ #include "base/files/file.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "base/files/file_path.h" #include "third_party/sqlite/sqlite3.h" -namespace blink { +namespace sql { class SandboxedVfs; -class SandboxedVfsFile; -// SQLite VFS file implementation that works in the Chrome renderer sandbox. +// SQLite VFS file implementation that works in a typical Chromium sandbox. // // An instance is created when SQLite calls into SandboxedVfs::Open(). The // instance is deleted by a call to SandboxedVfsFile::Close(). @@ -32,17 +30,16 @@ // SQLite's built-in VFSes use the OS support for locking a range of bytes in // the file, rather locking than the whole file. class SandboxedVfsFile { - USING_FAST_MALLOC(SandboxedVfsFile); - public: - // Creates an instance in the given buffer. + // Creates an instance in the given buffer. Note that `vfs` MUST outlive the + // returned sqlite3_file object. static void Create(base::File file, - String file_name, + base::FilePath file_path, SandboxedVfs* vfs, - sqlite3_file* buffer); + sqlite3_file& buffer); // Extracts the instance bridged to the given SQLite VFS file. - static SandboxedVfsFile* FromSqliteFile(sqlite3_file* sqlite_file); + static SandboxedVfsFile& FromSqliteFile(sqlite3_file& sqlite_file); // sqlite3_file implementation. int Close(); @@ -68,7 +65,9 @@ int Unfetch(sqlite3_int64 offset, void* fetch_result); private: - SandboxedVfsFile(base::File file, String file_name, SandboxedVfs* vfs); + SandboxedVfsFile(base::File file, + base::FilePath file_path, + SandboxedVfs* vfs); ~SandboxedVfsFile(); // Constructed from a file handle passed from the browser process. @@ -78,18 +77,18 @@ // The SandboxedVfs that created this instance. SandboxedVfs* const vfs_; // Used to identify the file in IPCs to the browser process. - const String file_name_; + const base::FilePath file_path_; }; // sqlite3_file "subclass" that bridges to a SandboxedVfsFile instance. struct SandboxedVfsFileSqliteBridge { sqlite3_file sqlite_file; - SandboxedVfsFile* blink_file; + SandboxedVfsFile* sandboxed_vfs_file; - static SandboxedVfsFileSqliteBridge* FromSqliteFile( - sqlite3_file* sqlite_file); + static SandboxedVfsFileSqliteBridge& FromSqliteFile( + sqlite3_file& sqlite_file); }; -} // namespace blink +} // namespace sql -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_FILE_H_ +#endif // SQL_SANDBOXED_VFS_FILE_H_
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 07d34ad..bf17e62 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -4623,7 +4623,7 @@ }, { "args": [ - "--gtest_filter=-NativeExtensionBindingsSystemUnittest*" + "--gtest_filter=-NativeExtensionBindingsSystemUnittest*:BluetoothSocketApiUnittest.CreateThenClose:FeatureProviderTest.PermissionFeatureAvailability" ], "experiment_percentage": 100, "merge": { @@ -5099,7 +5099,7 @@ }, { "args": [ - "--gtest_filter=-NativeDesktopMediaListTest*:PermissionMessageCombinationsUnittest.USBSerialBluetoothCoalescing:RelaunchNotificationControllerPlatformImplTest.SynchronousNotification:WindowSizerTest*" + "--gtest_filter=-NativeDesktopMediaListTest*:PermissionMessageCombinationsUnittest.USBSerialBluetoothCoalescing:RelaunchNotificationControllerPlatformImplTest.SynchronousNotification:WindowSizerTest*:ChromeContentBrowserClientTest.UserAgentStringOrdering:ChromeMetricsServiceClientTest.TestRegisterMetricsServiceProviders" ], "experiment_percentage": 100, "merge": { @@ -5127,7 +5127,7 @@ }, { "args": [ - "--gtest_filter=-DesktopWidgetFocusManagerTest.AnchoredDialogInDesktopNativeWidgetAura:DesktopWidgetTest.GetWindowPlacement:DesktopWidgetTest.MinimumSizeConstraints:EditableComboboxTest.EndOrHomeMovesToBeginningOrEndOfText:EditableComboboxTest.MenuCanAdaptToContentChange:TextfieldTest.ContextMenuDisplayTest:TooltipControllerTest*" + "--gtest_filter=-DesktopWidgetFocusManagerTest.AnchoredDialogInDesktopNativeWidgetAura:DesktopWidgetTest.GetWindowPlacement:DesktopWidgetTest.MinimumSizeConstraints:EditableComboboxTest.AltLeftOrRightDoesNothing:EditableComboboxTest.CtrlLeftOrRightMovesToNextWords:EditableComboboxTest.EndOrHomeMovesToBeginningOrEndOfText:EditableComboboxTest.MenuCanAdaptToContentChange:TextfieldTest.ContextMenuDisplayTest:TextfieldTest.CutCopyPasteWithEditCommand:TextfieldTest.OverflowTest:TextfieldTest.SwitchFocusInKeyDown:TooltipControllerTest*" ], "experiment_percentage": 100, "merge": {
diff --git a/testing/buildbot/chromium.ci.json b/testing/buildbot/chromium.ci.json index 74480b5..fa762a6 100644 --- a/testing/buildbot/chromium.ci.json +++ b/testing/buildbot/chromium.ci.json
@@ -9294,37 +9294,6 @@ "isolated_scripts": [ { "args": [ - "--gtest-benchmark-name=angle_perftests", - "-v", - "--one-frame-only", - "--shard-timeout=800" - ], - "isolate_name": "angle_perftests", - "merge": { - "args": [ - "--smoke-test-mode" - ], - "script": "//tools/perf/process_perf_results.py" - }, - "name": "angle_perftests", - "swarming": { - "can_use_on_swarming_builders": true, - "containment_type": "AUTO", - "dimension_sets": [ - { - "device_os": "M", - "device_os_type": "userdebug", - "device_type": "angler", - "os": "Android", - "pool": "chromium.tests.gpu" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_perftests/" - }, - { - "args": [ "context_lost", "--show-stdout", "--browser=android-chromium", @@ -37422,10 +37391,342 @@ ] }, "Linux FYI Experimental Release (NVIDIA)": { + "gtest_tests": [ + { + "args": [ + "--test-launcher-retry-limit=0", + "--test-launcher-batch-limit=256", + "--gtest_filter=-*Vulkan_SwiftShader*", + "--use-gpu-in-tests", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 + }, + "test": "angle_end2end_tests", + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_end2end_tests/" + }, + { + "args": [ + "--use-gpu-in-tests", + "--test-launcher-retry-limit=0", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_unittests", + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/" + }, + { + "args": [ + "--test-launcher-retry-limit=0", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_white_box_tests", + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_white_box_tests/" + }, + { + "args": [ + "--enable-gpu", + "--test-launcher-bot-mode", + "--test-launcher-jobs=1", + "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "tab_capture_end2end_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "browser_tests", + "test_id_prefix": "ninja://chrome/test:browser_tests/" + }, + { + "args": [ + "--use-cmd-decoder=passthrough", + "--use-gl=angle", + "--use-gpu-in-tests", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "gl_tests_passthrough", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gl_tests", + "test_id_prefix": "ninja://gpu:gl_tests/" + }, + { + "args": [ + "--use-cmd-decoder=validating", + "--use-gpu-in-tests", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "gl_tests_validating", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gl_tests", + "test_id_prefix": "ninja://gpu:gl_tests/" + }, + { + "args": [ + "--use-gpu-in-tests", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gl_unittests", + "test_id_prefix": "ninja://ui/gl:gl_unittests/" + }, + { + "args": [ + "--use-gpu-in-tests" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gles2_conform_test", + "test_id_prefix": "ninja://gpu/gles2_conform_support:gles2_conform_test/" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "swiftshader_unittests", + "test_id_prefix": "ninja://third_party/swiftshader/tests/GLESUnitTests:swiftshader_unittests/" + } + ], "isolated_scripts": [ { "args": [ - "noop_sleep", + "--gtest-benchmark-name=angle_perftests", + "-v", + "--one-frame-only" + ], + "isolate_name": "angle_perftests", + "merge": { + "args": [ + "--smoke-test-mode" + ], + "script": "//tools/perf/process_perf_results.py" + }, + "name": "angle_perftests", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_perftests/" + }, + { + "args": [ + "context_lost", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "context_lost_passthrough_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "context_lost", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "context_lost_validating_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "depth_capture", "--show-stdout", "--browser=release", "--passthrough", @@ -37437,16 +37738,16 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "noop_sleep_tests", + "name": "depth_capture_tests", "should_retry_with_patch": false, "swarming": { "can_use_on_swarming_builders": true, "containment_type": "AUTO", "dimension_sets": [ { - "gpu": "10de:1cb3-418.56", - "os": "Ubuntu-19.04", - "pool": "chromium.tests.gpu" + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" } ], "expiration": 21600, @@ -37454,6 +37755,506 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "gpu_process", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gpu_process_launch_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "hardware_accelerated_feature", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "hardware_accelerated_feature_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "info_collection", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu", + "--expected-vendor-id", + "10de", + "--expected-device-id", + "2184" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "info_collection_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "maps", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "maps_pixel_passthrough_test", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "maps", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "maps_pixel_validating_test", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_passthrough_test", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_validating_test", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "screenshot_sync", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "screenshot_sync_passthrough_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "screenshot_sync", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--dont-restore-color-profile-after-test" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "screenshot_sync_validating_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "trace_test", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "trace_test", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough --force_high_performance_gpu", + "--webgl-conformance-version=2.0.1", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl2_conformance_gl_passthrough_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating --force_high_performance_gpu", + "--webgl-conformance-version=2.0.1", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl2_conformance_validating_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough --force_high_performance_gpu", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl_conformance_gl_passthrough_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating --force_high_performance_gpu", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl_conformance_validating_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" } ] }, @@ -255067,7 +255868,7 @@ }, { "args": [ - "--gtest_filter=-NativeExtensionBindingsSystemUnittest*" + "--gtest_filter=-NativeExtensionBindingsSystemUnittest*:BluetoothSocketApiUnittest.CreateThenClose:FeatureProviderTest.PermissionFeatureAvailability" ], "experiment_percentage": 100, "merge": { @@ -255543,7 +256344,7 @@ }, { "args": [ - "--gtest_filter=-NativeDesktopMediaListTest*:PermissionMessageCombinationsUnittest.USBSerialBluetoothCoalescing:RelaunchNotificationControllerPlatformImplTest.SynchronousNotification:WindowSizerTest*" + "--gtest_filter=-NativeDesktopMediaListTest*:PermissionMessageCombinationsUnittest.USBSerialBluetoothCoalescing:RelaunchNotificationControllerPlatformImplTest.SynchronousNotification:WindowSizerTest*:ChromeContentBrowserClientTest.UserAgentStringOrdering:ChromeMetricsServiceClientTest.TestRegisterMetricsServiceProviders" ], "experiment_percentage": 100, "merge": { @@ -255571,7 +256372,7 @@ }, { "args": [ - "--gtest_filter=-DesktopWidgetFocusManagerTest.AnchoredDialogInDesktopNativeWidgetAura:DesktopWidgetTest.GetWindowPlacement:DesktopWidgetTest.MinimumSizeConstraints:EditableComboboxTest.EndOrHomeMovesToBeginningOrEndOfText:EditableComboboxTest.MenuCanAdaptToContentChange:TextfieldTest.ContextMenuDisplayTest:TooltipControllerTest*" + "--gtest_filter=-DesktopWidgetFocusManagerTest.AnchoredDialogInDesktopNativeWidgetAura:DesktopWidgetTest.GetWindowPlacement:DesktopWidgetTest.MinimumSizeConstraints:EditableComboboxTest.AltLeftOrRightDoesNothing:EditableComboboxTest.CtrlLeftOrRightMovesToNextWords:EditableComboboxTest.EndOrHomeMovesToBeginningOrEndOfText:EditableComboboxTest.MenuCanAdaptToContentChange:TextfieldTest.ContextMenuDisplayTest:TextfieldTest.CutCopyPasteWithEditCommand:TextfieldTest.OverflowTest:TextfieldTest.SwitchFocusInKeyDown:TooltipControllerTest*" ], "experiment_percentage": 100, "merge": {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 74e799a4..f5b1cb74 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -6130,37 +6130,6 @@ "isolated_scripts": [ { "args": [ - "--gtest-benchmark-name=angle_perftests", - "-v", - "--one-frame-only", - "--shard-timeout=800" - ], - "isolate_name": "angle_perftests", - "merge": { - "args": [ - "--smoke-test-mode" - ], - "script": "//tools/perf/process_perf_results.py" - }, - "name": "angle_perftests", - "swarming": { - "can_use_on_swarming_builders": true, - "containment_type": "AUTO", - "dimension_sets": [ - { - "device_os": "M", - "device_os_type": "userdebug", - "device_type": "angler", - "os": "Android", - "pool": "chromium.tests.gpu" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/angle/src/tests:angle_perftests/" - }, - { - "args": [ "context_lost", "--show-stdout", "--browser=android-chromium", @@ -9083,10 +9052,342 @@ ] }, "Linux FYI Experimental Release (NVIDIA)": { + "gtest_tests": [ + { + "args": [ + "--test-launcher-retry-limit=0", + "--test-launcher-batch-limit=256", + "--gtest_filter=-*Vulkan_SwiftShader*", + "--use-gpu-in-tests", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 4 + }, + "test": "angle_end2end_tests", + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_end2end_tests/" + }, + { + "args": [ + "--use-gpu-in-tests", + "--test-launcher-retry-limit=0", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_unittests", + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/" + }, + { + "args": [ + "--test-launcher-retry-limit=0", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_white_box_tests", + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_white_box_tests/" + }, + { + "args": [ + "--enable-gpu", + "--test-launcher-bot-mode", + "--test-launcher-jobs=1", + "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "tab_capture_end2end_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "browser_tests", + "test_id_prefix": "ninja://chrome/test:browser_tests/" + }, + { + "args": [ + "--use-cmd-decoder=passthrough", + "--use-gl=angle", + "--use-gpu-in-tests", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "gl_tests_passthrough", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gl_tests", + "test_id_prefix": "ninja://gpu:gl_tests/" + }, + { + "args": [ + "--use-cmd-decoder=validating", + "--use-gpu-in-tests", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "name": "gl_tests_validating", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gl_tests", + "test_id_prefix": "ninja://gpu:gl_tests/" + }, + { + "args": [ + "--use-gpu-in-tests", + "--no-xvfb" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gl_unittests", + "test_id_prefix": "ninja://ui/gl:gl_unittests/" + }, + { + "args": [ + "--use-gpu-in-tests" + ], + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gles2_conform_test", + "test_id_prefix": "ninja://gpu/gles2_conform_support:gles2_conform_test/" + }, + { + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_gtest_merge.py" + }, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "swiftshader_unittests", + "test_id_prefix": "ninja://third_party/swiftshader/tests/GLESUnitTests:swiftshader_unittests/" + } + ], "isolated_scripts": [ { "args": [ - "noop_sleep", + "--gtest-benchmark-name=angle_perftests", + "-v", + "--one-frame-only" + ], + "isolate_name": "angle_perftests", + "merge": { + "args": [ + "--smoke-test-mode" + ], + "script": "//tools/perf/process_perf_results.py" + }, + "name": "angle_perftests", + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_perftests/" + }, + { + "args": [ + "context_lost", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "context_lost_passthrough_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "context_lost", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "context_lost_validating_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "depth_capture", "--show-stdout", "--browser=release", "--passthrough", @@ -9098,16 +9399,16 @@ "args": [], "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "noop_sleep_tests", + "name": "depth_capture_tests", "should_retry_with_patch": false, "swarming": { "can_use_on_swarming_builders": true, "containment_type": "AUTO", "dimension_sets": [ { - "gpu": "10de:1cb3-418.56", - "os": "Ubuntu-19.04", - "pool": "chromium.tests.gpu" + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" } ], "expiration": 21600, @@ -9115,6 +9416,506 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "gpu_process", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "gpu_process_launch_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "hardware_accelerated_feature", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "hardware_accelerated_feature_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "info_collection", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_high_performance_gpu", + "--expected-vendor-id", + "10de", + "--expected-device-id", + "2184" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "info_collection_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "maps", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "maps_pixel_passthrough_test", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "maps", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "maps_pixel_validating_test", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_passthrough_test", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "pixel", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--dont-restore-color-profile-after-test", + "--test-machine-name", + "${buildername}", + "--git-revision=${got_revision}" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "pixel_skia_gold_validating_test", + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "screenshot_sync", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", + "--dont-restore-color-profile-after-test" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "screenshot_sync_passthrough_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "screenshot_sync", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating", + "--dont-restore-color-profile-after-test" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "screenshot_sync_validating_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "trace_test", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "trace_test", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough --force_high_performance_gpu", + "--webgl-conformance-version=2.0.1", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl2_conformance_gl_passthrough_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating --force_high_performance_gpu", + "--webgl-conformance-version=2.0.1", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl2_conformance_validating_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=gl --use-cmd-decoder=passthrough --force_high_performance_gpu", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl_conformance_gl_passthrough_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" + }, + { + "args": [ + "webgl_conformance", + "--show-stdout", + "--browser=release", + "--passthrough", + "-v", + "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating --force_high_performance_gpu", + "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl_conformance_tests_output.json" + ], + "isolate_name": "telemetry_gpu_integration_test", + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "webgl_conformance_validating_tests", + "should_retry_with_patch": false, + "swarming": { + "can_use_on_swarming_builders": true, + "containment_type": "AUTO", + "dimension_sets": [ + { + "gpu": "10de:2184-440.100", + "os": "Ubuntu-18.04", + "pool": "chromium.tests.gpu.experimental" + } + ], + "expiration": 21600, + "idempotent": false, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test_id_prefix": "ninja://chrome/test:telemetry_gpu_integration_test/" } ] },
diff --git a/testing/buildbot/filters/lacros.browser_tests.filter b/testing/buildbot/filters/lacros.browser_tests.filter index 52ab5093..1eeec121 100644 --- a/testing/buildbot/filters/lacros.browser_tests.filter +++ b/testing/buildbot/filters/lacros.browser_tests.filter
@@ -88,6 +88,7 @@ -BrowserViewTest.GetAccessibleTabModalDialogTree -BrowsingDataRemoverBrowserTest.StorageRemovedFromDisk -CaptivePortalBrowserTest.SecureDnsErrorTriggersCheck +-CaptivePortalBrowserTest.SlowLoadSecureDnsErrorAfterLogin -CaptivePortalBrowserTest.SlowLoadSecureDnsErrorWithCaptivePortal -ChromeSitePerProcessTest.PopupWindowFocus -ClientHintsBrowserTest.ClientHintsClearSession @@ -103,6 +104,7 @@ -ContextMenuBrowserTest.PngImageDownscaleToPng -ContextMenuBrowserTest.RealMenu -ContextMenuBrowserTest.RequestPngForGifImage +-ContextMenuBrowserTest.SuggestedFileNameCrossOrigin -CrComponentsCertificateManagerV3Test.All -CrComponentsManagedFootnoteV3Test.All -CreativeOriginAdsPageLoadMetricsObserverBrowserTest.CreativeOriginStatusWithThrottlingNestedThrottled @@ -175,6 +177,7 @@ -PaymentRequestShippingAddressEditorTest.FocusFirstInvalidField_NotName -PDFExtensionTestWithTestGuestViewManager.CSPDoesNotBlockEmbedStyles -PDFExtensionTestWithTestGuestViewManager.CSPFrameAncestorsOverridesXFrameOptions +-PDFExtensionTestWithTestGuestViewManager.PdfExtensionLoadedInGuest -PDFExtensionTestWithTestGuestViewManager.PdfInMainFrameHasFocus -PermissionRequestManagerWithBackForwardCacheBrowserTest.RequestsForPagesInCacheNotGrouped -PermissionsApiTest.AlwaysAllowed @@ -513,4 +516,4 @@ -WebViewTest.SelectShowHide -WebViewTest.Shim_TestDisplayNoneWebviewRemoveChild -WelcomeA11y.WelcomeFlow_listitem --WorkerTaskProviderBrowserTest.CreateTasksForMultiProfiles \ No newline at end of file +-WorkerTaskProviderBrowserTest.CreateTasksForMultiProfiles
diff --git a/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter b/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter index 2da3485..2c48157 100644 --- a/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter +++ b/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter
@@ -1,6 +1,8 @@ # TODO(https://crbug.com/1084469): fix these tests. # Failed: +-All/PopupBrowserTest.MoveClampedToCurrentDisplay/0 +-All/PopupBrowserTest.MoveClampedToCurrentDisplay/1 -AutomationManagerAuraBrowserTest.TransientFocusChangesAreSuppressed -BrowserActionApiTest.BrowserActionOpenPopupOnPopup -BrowserViewTest.F6CyclesThroughCaptionBubbleToo
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 592f6db9..f292678 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -395,12 +395,12 @@ 'expiration': 14400, } }, - 'linux_nvidia_quadro_p400_experimental': { + 'linux_nvidia_gtx_1660_experimental': { 'swarming': { 'dimensions': { - 'gpu': '10de:1cb3-418.56', - 'os': 'Ubuntu-19.04', - 'pool': 'chromium.tests.gpu', + 'gpu': '10de:2184-440.100', + 'os': 'Ubuntu-18.04', + 'pool': 'chromium.tests.gpu.experimental', }, }, },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index a5211555..daeca87f 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -66,6 +66,7 @@ 'remove_from': [ 'Android FYI Release (Nexus 5)', # crbug.com/915429 'Android FYI Release (Nexus 6)', # anglebug.com/2433 + 'Android FYI Release (Nexus 6P)', # anglebug.com/4909 'Linux FYI GPU TSAN Release', # crbug.com/950542 ], }, @@ -1171,7 +1172,9 @@ 'linux-lacros-tester-rel': { 'experiment_percentage': 100, 'args': [ - '--gtest_filter=-NativeExtensionBindingsSystemUnittest*', + '--gtest_filter=-NativeExtensionBindingsSystemUnittest*:' + 'BluetoothSocketApiUnittest.CreateThenClose:' + 'FeatureProviderTest.PermissionFeatureAvailability', ], }, }, @@ -2646,7 +2649,9 @@ 'experiment_percentage': 100, 'args': [ '--gtest_filter=-NativeDesktopMediaListTest*:PermissionMessageCombinationsUnittest.USBSerialBluetoothCoalescing:' - 'RelaunchNotificationControllerPlatformImplTest.SynchronousNotification:WindowSizerTest*', + 'RelaunchNotificationControllerPlatformImplTest.SynchronousNotification:WindowSizerTest*:' + 'ChromeContentBrowserClientTest.UserAgentStringOrdering:' + 'ChromeMetricsServiceClientTest.TestRegisterMetricsServiceProviders', ], }, }, @@ -2680,9 +2685,14 @@ '--gtest_filter=-DesktopWidgetFocusManagerTest.AnchoredDialogInDesktopNativeWidgetAura:' 'DesktopWidgetTest.GetWindowPlacement:' 'DesktopWidgetTest.MinimumSizeConstraints:' + 'EditableComboboxTest.AltLeftOrRightDoesNothing:' + 'EditableComboboxTest.CtrlLeftOrRightMovesToNextWords:' 'EditableComboboxTest.EndOrHomeMovesToBeginningOrEndOfText:' 'EditableComboboxTest.MenuCanAdaptToContentChange:' 'TextfieldTest.ContextMenuDisplayTest:' + 'TextfieldTest.CutCopyPasteWithEditCommand:' + 'TextfieldTest.OverflowTest:' + 'TextfieldTest.SwitchFocusInKeyDown:' 'TooltipControllerTest*', ], },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 7de5622a..6c0565a 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -3340,13 +3340,15 @@ 'browser_config': 'release', 'mixins': [ 'limited_capacity_bot', - 'linux_nvidia_quadro_p400_experimental', + 'linux_nvidia_gtx_1660_experimental', ], - # Currently the experimental driver is identical to the stable - # driver. If it's upgraded, change these test_suites to be the same as - # 'Linux FYI Release (NVIDIA)'. + # If the experimental configuration is the same as stable, this should + # only be running 'gpu_noop_sleep_telemetry_test'. Otherwise, this + # should be running the same tests as 'Linux FYI Release (NVIDIA)'. 'test_suites': { - 'gpu_telemetry_tests': 'gpu_noop_sleep_telemetry_test', + 'gtest_tests': 'gpu_fyi_linux_release_gtests', + 'isolated_scripts': 'gpu_angle_perf_smoke_isolated_scripts', + 'gpu_telemetry_tests': 'gpu_fyi_linux_intel_and_nvidia_release_telemetry_tests', }, }, 'Linux FYI GPU TSAN Release': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index bb4c23e..15a51234 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1129,6 +1129,7 @@ "platforms": [ "android", "android_weblayer", + "chromeos", "ios", "linux", "mac", @@ -1136,10 +1137,10 @@ ], "experiments": [ { - "name": "disable_timer-queues_until_onload", + "name": "best-effort_timer-queues_until_onload", "params": { "delay_ms": "0", - "method": "disable", + "method": "best-effort", "queues": "timer-queues", "signal": "onload" }, @@ -4341,6 +4342,24 @@ ] } ], + "MediaFeeds": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MediaFeeds" + ] + } + ] + } + ], "MediaFoundationAsyncH264Encoding": [ { "platforms": [ @@ -5060,6 +5079,21 @@ ] } ], + "OmniboxSuggestionsWrapAround": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OmniboxSuggestionsWrapAround" + ] + } + ] + } + ], "OutOfBlinkCors": [ { "platforms": [
diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.gn index 9431d17..04bd5cb 100644 --- a/third_party/android_deps/BUILD.gn +++ b/third_party/android_deps/BUILD.gn
@@ -83,6 +83,10 @@ deps = [ "$material_design_target" ] } +java_group("protobuf_lite_runtime_java") { + deps = [ "$android_proto_runtime" ] +} + java_annotation_processor("auto_service_processor") { main_class = "com.google.auto.service.processor.AutoServiceProcessor" deps = [ ":com_google_auto_service_auto_service_java" ]
diff --git a/third_party/blink/common/BUILD.gn b/third_party/blink/common/BUILD.gn index e1b4021..e230c07b 100644 --- a/third_party/blink/common/BUILD.gn +++ b/third_party/blink/common/BUILD.gn
@@ -106,6 +106,7 @@ "loader/mime_sniffing_throttle.cc", "loader/mime_sniffing_url_loader.cc", "loader/network_utils.cc", + "loader/referrer_utils.cc", "loader/resource_type_util.cc", "loader/throttling_url_loader.cc", "loader/url_loader_factory_bundle.cc", @@ -233,6 +234,7 @@ "input/synthetic_web_input_event_builders_unittest.cc", "input/web_input_event_unittest.cc", "loader/mime_sniffing_throttle_unittest.cc", + "loader/referrer_utils_unittest.cc", "loader/throttling_url_loader_unittest.cc", "manifest/manifest_icon_selector_unittest.cc", "manifest/manifest_util_unittest.cc",
diff --git a/third_party/blink/common/feature_policy/document_policy.cc b/third_party/blink/common/feature_policy/document_policy.cc index f601205a..234eee563 100644 --- a/third_party/blink/common/feature_policy/document_policy.cc +++ b/third_party/blink/common/feature_policy/document_policy.cc
@@ -75,26 +75,36 @@ // static DocumentPolicyFeatureState DocumentPolicy::MergeFeatureState( - const DocumentPolicyFeatureState& policy1, - const DocumentPolicyFeatureState& policy2) { + const DocumentPolicyFeatureState& base_policy, + const DocumentPolicyFeatureState& override_policy) { DocumentPolicyFeatureState result; - auto i1 = policy1.begin(); - auto i2 = policy2.begin(); + auto i1 = base_policy.begin(); + auto i2 = override_policy.begin(); // Because std::map is by default ordered in ascending order based on key // value, we can run 2 iterators simultaneously through both maps to merge // them. - while (i1 != policy1.end() || i2 != policy2.end()) { - if (i1 == policy1.end()) { + while (i1 != base_policy.end() || i2 != override_policy.end()) { + if (i1 == base_policy.end()) { result.insert(*i2); i2++; - } else if (i2 == policy2.end()) { + } else if (i2 == override_policy.end()) { result.insert(*i1); i1++; } else { if (i1->first == i2->first) { - // Take the stricter policy when there is a key conflict. - result.emplace(i1->first, std::min(i1->second, i2->second)); + const PolicyValue& base_value = i1->second; + const PolicyValue& override_value = i2->second; + // When policy value has strictness ordering e.g. boolean, take the + // stricter one. In this case a.IsCompatibleWith(b) means a is eq or + // stricter than b. + // When policy value does not have strictness ordering, e.g. enum, + // take override_value. In this case a.IsCompatibleWith(b) means + // a != b. + const PolicyValue& new_value = + base_value.IsCompatibleWith(override_value) ? base_value + : override_value; + result.emplace(i1->first, new_value); i1++; i2++; } else if (i1->first < i2->first) { @@ -121,7 +131,7 @@ bool DocumentPolicy::IsFeatureEnabled( mojom::DocumentPolicyFeature feature, const PolicyValue& threshold_value) const { - return GetFeatureValue(feature) >= threshold_value; + return threshold_value.IsCompatibleWith(GetFeatureValue(feature)); } PolicyValue DocumentPolicy::GetFeatureValue( @@ -172,10 +182,6 @@ const DocumentPolicyFeatureState& required_policy, const DocumentPolicyFeatureState& incoming_policy) { for (const auto& required_entry : required_policy) { - // feature value > threshold => enabled, where feature value is the value in - // document policy and threshold is the value to test against. - // The smaller the feature value, the stricter the policy. - // Incoming policy should be at least as strict as the required one. const auto& feature = required_entry.first; const auto& required_value = required_entry.second; // Use default value when incoming policy does not specify a value. @@ -185,7 +191,7 @@ ? incoming_entry->second : GetDocumentPolicyFeatureInfoMap().at(feature).default_value; - if (required_value < incoming_value) + if (!incoming_value.IsCompatibleWith(required_value)) return false; } return true;
diff --git a/third_party/blink/common/feature_policy/policy_value.cc b/third_party/blink/common/feature_policy/policy_value.cc index 7bcf38e..52be493 100644 --- a/third_party/blink/common/feature_policy/policy_value.cc +++ b/third_party/blink/common/feature_policy/policy_value.cc
@@ -91,13 +91,13 @@ return !(lhs == rhs); } -bool operator<(const PolicyValue& lhs, const PolicyValue& rhs) { - DCHECK_EQ(lhs.Type(), rhs.Type()); - switch (lhs.Type()) { +bool PolicyValue::IsCompatibleWith(const PolicyValue& required) const { + DCHECK_EQ(type_, required.Type()); + switch (type_) { case mojom::PolicyValueType::kBool: - return !lhs.BoolValue() && rhs.BoolValue(); + return !bool_value_ || required.bool_value_; case mojom::PolicyValueType::kDecDouble: - return lhs.DoubleValue() < rhs.DoubleValue(); + return double_value_ <= required.double_value_; case mojom::PolicyValueType::kNull: NOTREACHED(); break; @@ -105,18 +105,6 @@ return false; } -bool operator<=(const PolicyValue& lhs, const PolicyValue& rhs) { - return lhs < rhs || lhs == rhs; -} - -bool operator>(const PolicyValue& lhs, const PolicyValue& rhs) { - return rhs < lhs; -} - -bool operator>=(const PolicyValue& lhs, const PolicyValue& rhs) { - return rhs < lhs || rhs == lhs; -} - void PolicyValue::SetToMax() { switch (type_) { case mojom::PolicyValueType::kBool:
diff --git a/third_party/blink/common/feature_policy/policy_value_unittest.cc b/third_party/blink/common/feature_policy/policy_value_unittest.cc index 304a356..892213d 100644 --- a/third_party/blink/common/feature_policy/policy_value_unittest.cc +++ b/third_party/blink/common/feature_policy/policy_value_unittest.cc
@@ -43,33 +43,21 @@ PolicyValue false_value(false); PolicyValue true_value(true); - EXPECT_FALSE(false_value < false_value); - EXPECT_TRUE(false_value <= false_value); EXPECT_TRUE(false_value == false_value); EXPECT_FALSE(false_value != false_value); - EXPECT_TRUE(false_value >= false_value); - EXPECT_FALSE(false_value > false_value); + EXPECT_TRUE(false_value.IsCompatibleWith(false_value)); - EXPECT_TRUE(false_value < true_value); - EXPECT_TRUE(false_value <= true_value); EXPECT_FALSE(false_value == true_value); EXPECT_TRUE(false_value != true_value); - EXPECT_FALSE(false_value >= true_value); - EXPECT_FALSE(false_value > true_value); + EXPECT_TRUE(false_value.IsCompatibleWith(true_value)); - EXPECT_FALSE(true_value < false_value); - EXPECT_FALSE(true_value <= false_value); EXPECT_FALSE(true_value == false_value); EXPECT_TRUE(true_value != false_value); - EXPECT_TRUE(true_value >= false_value); - EXPECT_TRUE(true_value > false_value); + EXPECT_FALSE(true_value.IsCompatibleWith(false_value)); - EXPECT_FALSE(true_value < true_value); - EXPECT_TRUE(true_value <= true_value); EXPECT_TRUE(true_value == true_value); EXPECT_FALSE(true_value != true_value); - EXPECT_TRUE(true_value >= true_value); - EXPECT_FALSE(true_value > true_value); + EXPECT_TRUE(true_value.IsCompatibleWith(true_value)); } TEST_F(PolicyValueTest, TestCanCreateDoubleValues) { @@ -100,33 +88,21 @@ PolicyValue low_value(1.0); PolicyValue high_value(2.0); - EXPECT_FALSE(low_value < low_value); - EXPECT_TRUE(low_value <= low_value); EXPECT_TRUE(low_value == low_value); EXPECT_FALSE(low_value != low_value); - EXPECT_TRUE(low_value >= low_value); - EXPECT_FALSE(low_value > low_value); + EXPECT_TRUE(low_value.IsCompatibleWith(low_value)); - EXPECT_TRUE(low_value < high_value); - EXPECT_TRUE(low_value <= high_value); EXPECT_FALSE(low_value == high_value); EXPECT_TRUE(low_value != high_value); - EXPECT_FALSE(low_value >= high_value); - EXPECT_FALSE(low_value > high_value); + EXPECT_TRUE(low_value.IsCompatibleWith(high_value)); - EXPECT_FALSE(high_value < low_value); - EXPECT_FALSE(high_value <= low_value); EXPECT_FALSE(high_value == low_value); EXPECT_TRUE(high_value != low_value); - EXPECT_TRUE(high_value >= low_value); - EXPECT_TRUE(high_value > low_value); + EXPECT_FALSE(high_value.IsCompatibleWith(low_value)); - EXPECT_FALSE(high_value < high_value); - EXPECT_TRUE(high_value <= high_value); EXPECT_TRUE(high_value == high_value); EXPECT_FALSE(high_value != high_value); - EXPECT_TRUE(high_value >= high_value); - EXPECT_FALSE(high_value > high_value); + EXPECT_TRUE(high_value.IsCompatibleWith(high_value)); } } // namespace blink
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 444b671..c06eb2e5 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -54,11 +54,6 @@ const base::Feature kFreezeUserAgent{"FreezeUserAgent", base::FEATURE_DISABLED_BY_DEFAULT}; -// When enabled, use the maximum possible bounds in compositing overlap testing -// for fixed position elements. -const base::Feature kMaxOverlapBoundsForFixed{"MaxOverlapBoundsForFixed", - base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kMeasureMemoryExperiment{"MeasureMemoryExperiment", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -692,5 +687,13 @@ const base::Feature kCrOSAutoSelect{"CrOSAutoSelect", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kCompositingOptimizations{ + "CompositingOptimizations", base::FEATURE_DISABLED_BY_DEFAULT}; + +// Reduce the amount of information in the default 'referer' header for +// cross-origin requests. +const base::Feature kReducedReferrerGranularity{ + "ReducedReferrerGranularity", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace features } // namespace blink
diff --git a/third_party/blink/common/loader/network_utils.cc b/third_party/blink/common/loader/network_utils.cc index 73257e5..26fa51c9 100644 --- a/third_party/blink/common/loader/network_utils.cc +++ b/third_party/blink/common/loader/network_utils.cc
@@ -18,29 +18,4 @@ headers->HasHeaderValue("vary", "*"); } -network::mojom::ReferrerPolicy NetToMojoReferrerPolicy( - net::ReferrerPolicy net_policy) { - switch (net_policy) { - case net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE: - return network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade; - case net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN: - return network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin; - case net::ReferrerPolicy::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN: - return network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin; - case net::ReferrerPolicy::NEVER_CLEAR: - return network::mojom::ReferrerPolicy::kAlways; - case net::ReferrerPolicy::ORIGIN: - return network::mojom::ReferrerPolicy::kOrigin; - case net::ReferrerPolicy::CLEAR_ON_TRANSITION_CROSS_ORIGIN: - return network::mojom::ReferrerPolicy::kSameOrigin; - case net::ReferrerPolicy:: - ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE: - return network::mojom::ReferrerPolicy::kStrictOrigin; - case net::ReferrerPolicy::NO_REFERRER: - return network::mojom::ReferrerPolicy::kNever; - } - NOTREACHED(); - return network::mojom::ReferrerPolicy::kDefault; -} - } // namespace blink
diff --git a/third_party/blink/common/loader/referrer_utils.cc b/third_party/blink/common/loader/referrer_utils.cc new file mode 100644 index 0000000..c5c7bc8 --- /dev/null +++ b/third_party/blink/common/loader/referrer_utils.cc
@@ -0,0 +1,77 @@ +// 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/loader/referrer_utils.h" + +#include <atomic> + +#include "base/command_line.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/switches.h" + +namespace blink { + +network::mojom::ReferrerPolicy ReferrerUtils::NetToMojoReferrerPolicy( + net::ReferrerPolicy net_policy) { + switch (net_policy) { + case net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE: + return network::mojom::ReferrerPolicy::kNoReferrerWhenDowngrade; + case net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN: + return network::mojom::ReferrerPolicy::kStrictOriginWhenCrossOrigin; + case net::ReferrerPolicy::ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN: + return network::mojom::ReferrerPolicy::kOriginWhenCrossOrigin; + case net::ReferrerPolicy::NEVER_CLEAR: + return network::mojom::ReferrerPolicy::kAlways; + case net::ReferrerPolicy::ORIGIN: + return network::mojom::ReferrerPolicy::kOrigin; + case net::ReferrerPolicy::CLEAR_ON_TRANSITION_CROSS_ORIGIN: + return network::mojom::ReferrerPolicy::kSameOrigin; + case net::ReferrerPolicy:: + ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE: + return network::mojom::ReferrerPolicy::kStrictOrigin; + case net::ReferrerPolicy::NO_REFERRER: + return network::mojom::ReferrerPolicy::kNever; + } + NOTREACHED(); + return network::mojom::ReferrerPolicy::kDefault; +} + +net::ReferrerPolicy ReferrerUtils::GetDefaultNetReferrerPolicy() { + // The ReducedReferrerGranularity feature sets the default referrer + // policy to strict-origin-when-cross-origin unless forbidden + // by the "force legacy policy" global. + // TODO(crbug.com/1016541) Once the pertinent enterprise policy has + // been removed in M88, update this to remove the global. + + // Short-circuit to avoid acquiring the lock unless necessary. + if (!base::FeatureList::IsEnabled(features::kReducedReferrerGranularity)) + return net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE; + + bool should_force_legacy_default_referrer_policy = + ReadModifyWriteForceLegacyPolicyFlag(base::nullopt); + return should_force_legacy_default_referrer_policy + ? net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE + : net::ReferrerPolicy:: + REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN; +} + +// Using an atomic is necessary because this code is called from both the +// browser and the renderer (so that access is not on a single sequence when in +// single-process mode), and because it is called from multiple threads within +// the renderer. +bool ReferrerUtils::ReadModifyWriteForceLegacyPolicyFlag( + base::Optional<bool> maybe_new_value) { + // Default to false in the browser process (it is not expected + // that the browser will be provided this switch). + // The value is propagated to other processes through the command line. + DCHECK(base::CommandLine::InitializedForCurrentProcess()); + static std::atomic<bool> value( + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kForceLegacyDefaultReferrerPolicy)); + if (!maybe_new_value.has_value()) + return value; + return value.exchange(*maybe_new_value); +} + +} // namespace blink
diff --git a/third_party/blink/common/loader/referrer_utils_unittest.cc b/third_party/blink/common/loader/referrer_utils_unittest.cc new file mode 100644 index 0000000..435ac5d --- /dev/null +++ b/third_party/blink/common/loader/referrer_utils_unittest.cc
@@ -0,0 +1,25 @@ +// 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/loader/referrer_utils.h" + +#include "base/test/scoped_feature_list.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" + +namespace blink { + +TEST(DefaultNetReferrerPolicyTest, Unconfigured) { + EXPECT_EQ(blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), + net::ReferrerPolicy::CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE); +} + +TEST(DefaultNetReferrerPolicyTest, FeatureOnly) { + base::test::ScopedFeatureList f; + f.InitAndEnableFeature(blink::features::kReducedReferrerGranularity); + EXPECT_EQ(blink::ReferrerUtils::GetDefaultNetReferrerPolicy(), + net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN); +} + +} // namespace blink
diff --git a/third_party/blink/common/switches.cc b/third_party/blink/common/switches.cc index 31290d0..6d1c0f2 100644 --- a/third_party/blink/common/switches.cc +++ b/third_party/blink/common/switches.cc
@@ -49,6 +49,13 @@ // Enable rasterizer that writes directly to GPU memory associated with tiles. const char kEnableZeroCopy[] = "enable-zero-copy"; +// Pins the default referrer policy to the pre-M80 value of +// no-referrer-when-downgrade. +// TODO(crbug.com/1016541): After M88, remove when the corresponding +// enterprise policy has been deleted. +const char kForceLegacyDefaultReferrerPolicy[] = + "force-legacy-default-referrer-policy"; + // The number of multisample antialiasing samples for GPU rasterization. // Requires MSAA support on GPU to have an effect. 0 disables MSAA. const char kGpuRasterizationMSAASampleCount[] =
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index f64dca70..c70b25f 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -418,6 +418,7 @@ ":devtools_inspector_resources_grit", ":resources_grit", "//net", + "//services/network/public/mojom:mojom_shared", "//services/service_manager/public/cpp", "//skia", "//third_party/blink/public/common",
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index 6fba9a49a..bd9aef6c 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -114,6 +114,7 @@ "loader/mime_sniffing_url_loader.h", "loader/network_utils.h", "loader/previews_state.h", + "loader/referrer_utils.h", "loader/resource_type_util.h", "loader/url_loader_factory_bundle.h", "loader/url_loader_factory_bundle_mojom_traits.h",
diff --git a/third_party/blink/public/common/feature_policy/document_policy.h b/third_party/blink/public/common/feature_policy/document_policy.h index ebfe27c8..f08eef13 100644 --- a/third_party/blink/public/common/feature_policy/document_policy.h +++ b/third_party/blink/public/common/feature_policy/document_policy.h
@@ -109,10 +109,13 @@ const DocumentPolicyFeatureState& policy, const DocumentPolicyFeatureInfoMap&); - // Merge two FeatureState map. Take stricter value when there is conflict. + // Merge two FeatureState map. + // When there is conflict: + // - take the stricter value if PolicyValue is comparable + // - take override_policy's value if PolicyValue is not comparable static DocumentPolicyFeatureState MergeFeatureState( - const DocumentPolicyFeatureState& policy1, - const DocumentPolicyFeatureState& policy2); + const DocumentPolicyFeatureState& base_policy, + const DocumentPolicyFeatureState& override_policy); private: friend class DocumentPolicyTest;
diff --git a/third_party/blink/public/common/feature_policy/policy_value.h b/third_party/blink/public/common/feature_policy/policy_value.h index bcb49c9..2856e23 100644 --- a/third_party/blink/public/common/feature_policy/policy_value.h +++ b/third_party/blink/public/common/feature_policy/policy_value.h
@@ -52,6 +52,12 @@ void SetToMax(); void SetToMin(); + // Test whether this policy value is compatible with required policy value. + // Note: a.IsCompatibleWith(b) == true does not necessary indicate + // b.IsCompatibleWith(a) == false, because not all policy value types support + // strictness comparison, e.g. enum. + bool IsCompatibleWith(const PolicyValue& required) const; + private: mojom::PolicyValueType type_; bool bool_value_ = false; @@ -62,14 +68,6 @@ const PolicyValue& rhs); bool BLINK_COMMON_EXPORT operator!=(const PolicyValue& lhs, const PolicyValue& rhs); -bool BLINK_COMMON_EXPORT operator>(const PolicyValue& lhs, - const PolicyValue& rhs); -bool BLINK_COMMON_EXPORT operator>=(const PolicyValue& lhs, - const PolicyValue& rhs); -bool BLINK_COMMON_EXPORT operator<(const PolicyValue& lhs, - const PolicyValue& rhs); -bool BLINK_COMMON_EXPORT operator<=(const PolicyValue& lhs, - const PolicyValue& rhs); } // namespace blink #endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_FEATURE_POLICY_POLICY_VALUE_H_
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 882327f6..743df43 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -29,7 +29,6 @@ BLINK_COMMON_EXPORT extern const base::Feature kImplicitRootScroller; BLINK_COMMON_EXPORT extern const base::Feature kCSSOMViewScrollCoordinates; BLINK_COMMON_EXPORT extern const base::Feature kDisplayLocking; -BLINK_COMMON_EXPORT extern const base::Feature kMaxOverlapBoundsForFixed; BLINK_COMMON_EXPORT extern const base::Feature kMeasureMemoryExperiment; BLINK_COMMON_EXPORT extern const base::Feature kJSONModules; BLINK_COMMON_EXPORT extern const base::Feature kForceSynchronousHTMLParsing; @@ -277,6 +276,10 @@ BLINK_COMMON_EXPORT extern const base::Feature kCrOSAutoSelect; +BLINK_COMMON_EXPORT extern const base::Feature kCompositingOptimizations; + +BLINK_COMMON_EXPORT extern const base::Feature kReducedReferrerGranularity; + } // namespace features } // namespace blink
diff --git a/third_party/blink/public/common/loader/network_utils.h b/third_party/blink/public/common/loader/network_utils.h index 686037c..54fbf06b 100644 --- a/third_party/blink/public/common/loader/network_utils.h +++ b/third_party/blink/public/common/loader/network_utils.h
@@ -7,8 +7,6 @@ #include "base/memory/scoped_refptr.h" #include "net/http/http_response_headers.h" -#include "net/url_request/referrer_policy.h" -#include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "third_party/blink/public/common/common_export.h" namespace blink { @@ -18,9 +16,6 @@ BLINK_COMMON_EXPORT bool AlwaysAccessNetwork( const scoped_refptr<net::HttpResponseHeaders>& headers); -BLINK_COMMON_EXPORT network::mojom::ReferrerPolicy NetToMojoReferrerPolicy( - net::ReferrerPolicy net_policy); - } // namespace blink #endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_NETWORK_UTILS_H_
diff --git a/third_party/blink/public/common/loader/referrer_utils.h b/third_party/blink/public/common/loader/referrer_utils.h new file mode 100644 index 0000000..466255c --- /dev/null +++ b/third_party/blink/public/common/loader/referrer_utils.h
@@ -0,0 +1,28 @@ +// 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_LOADER_REFERRER_UTILS_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_REFERRER_UTILS_H_ + +#include "base/optional.h" +#include "net/url_request/referrer_policy.h" +#include "services/network/public/mojom/referrer_policy.mojom-shared.h" +#include "third_party/blink/public/common/common_export.h" + +namespace blink { + +class ReferrerUtils { + public: + static BLINK_COMMON_EXPORT network::mojom::ReferrerPolicy + NetToMojoReferrerPolicy(net::ReferrerPolicy net_policy); + + static BLINK_COMMON_EXPORT net::ReferrerPolicy GetDefaultNetReferrerPolicy(); + + static BLINK_COMMON_EXPORT bool ReadModifyWriteForceLegacyPolicyFlag( + base::Optional<bool> maybe_new_value); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_LOADER_REFERRER_UTILS_H_
diff --git a/third_party/blink/public/common/privacy_budget/identifiable_surface.h b/third_party/blink/public/common/privacy_budget/identifiable_surface.h index b24c128..9ceda4e 100644 --- a/third_party/blink/public/common/privacy_budget/identifiable_surface.h +++ b/third_party/blink/public/common/privacy_budget/identifiable_surface.h
@@ -12,6 +12,7 @@ #include <tuple> #include "third_party/blink/public/common/common_export.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_token.h" namespace blink { @@ -115,6 +116,14 @@ return IdentifiableSurface(KeyFromSurfaceTypeAndInput(type, input)); } + // Construct an IdentifiableSurface based on a surface type and an input + // token. + static constexpr IdentifiableSurface FromTypeAndToken( + Type type, + IdentifiableToken token) { + return IdentifiableSurface(KeyFromSurfaceTypeAndInput(type, token.value_)); + } + // Construct an invalid identifiable surface. static constexpr IdentifiableSurface Invalid() { return IdentifiableSurface(kInvalidHash);
diff --git a/third_party/blink/public/common/switches.h b/third_party/blink/public/common/switches.h index 12c6799..caeae00a 100644 --- a/third_party/blink/public/common/switches.h +++ b/third_party/blink/public/common/switches.h
@@ -27,6 +27,7 @@ BLINK_COMMON_EXPORT extern const char kEnableLowResTiling[]; BLINK_COMMON_EXPORT extern const char kEnableRGBA4444Textures[]; BLINK_COMMON_EXPORT extern const char kEnableZeroCopy[]; +BLINK_COMMON_EXPORT extern const char kForceLegacyDefaultReferrerPolicy[]; BLINK_COMMON_EXPORT extern const char kGpuRasterizationMSAASampleCount[]; BLINK_COMMON_EXPORT extern const char kIntensiveWakeUpThrottlingPolicy[]; BLINK_COMMON_EXPORT extern const char
diff --git a/third_party/blink/public/mojom/frame/BUILD.gn b/third_party/blink/public/mojom/frame/BUILD.gn index e855482..a2f9dd6a 100644 --- a/third_party/blink/public/mojom/frame/BUILD.gn +++ b/third_party/blink/public/mojom/frame/BUILD.gn
@@ -16,6 +16,7 @@ # TODO(crbug.com/1078875): Reorganize how we assign frame/*mojom files to # mojom GN targets to match better the core/platform separation in C++. sources = [ + "back_forward_cache_controller.mojom", "blocked_navigation_types.mojom", "find_in_page.mojom", "frame_owner_element_type.mojom",
diff --git a/third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom b/third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom new file mode 100644 index 0000000..7d30b07 --- /dev/null +++ b/third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom
@@ -0,0 +1,18 @@ +// 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; + +// This interface defines back-forward cache related methods that will be +// invoked from the renderer process. +// +// Calls to any of the methods defined in this interface must be allowed while +// the frame is in the back-forward cache. Calls to other (associated) interface +// methods while the frame is in the back-forward cache are disallowed and may +// trigger a renderer kill, depending on policy. +interface BackForwardCacheControllerHost { + // Evicts the page from the back/forward cache due to e.g., JavaScript + // execution. + EvictFromBackForwardCache(); +};
diff --git a/third_party/blink/public/mojom/frame/frame.mojom b/third_party/blink/public/mojom/frame/frame.mojom index d3ea704..c96113d0 100644 --- a/third_party/blink/public/mojom/frame/frame.mojom +++ b/third_party/blink/public/mojom/frame/frame.mojom
@@ -189,10 +189,6 @@ // behavior of 'shifting' the content via insets and a scrollIntoView). SetVirtualKeyboardOverlayPolicy(bool vk_overlays_content); - // Evicts the page from the back/forward cache due to e.g., JavaScript - // execution. - EvictFromBackForwardCache(); - // Notifies the browser that the associated frame has changed its visibility // status. Visibility status changes occur when the frame moves in/out // of the viewport, or the need for a layout object changes, e.g. if the @@ -734,7 +730,7 @@ // in another process. Actually entering fullscreen will be done separately // as part of ViewMsg_Resize, once the browser process has resized the tab for // fullscreen. - WillEnterFullscreen(); + WillEnterFullscreen(FullscreenOptions options); // Updates replicated ContentSecurityPolicy on the remote frame's // SecurityContent.
diff --git a/third_party/blink/public/mojom/frame/fullscreen.mojom b/third_party/blink/public/mojom/frame/fullscreen.mojom index dfee4373..9e77621 100644 --- a/third_party/blink/public/mojom/frame/fullscreen.mojom +++ b/third_party/blink/public/mojom/frame/fullscreen.mojom
@@ -12,5 +12,9 @@ // If the Window Placement experiment is enabled, fullscreen may be requested // on a particular display. In that case, this is the requested display's id. int64 display_id = -1; + + // True if this should be treated as a "webkit"-prefixed fullscreen request. + // These don't return promises, and fire "webkit"-prefixed events. + bool is_prefixed = false; };
diff --git a/third_party/blink/public/mojom/page/drag.mojom b/third_party/blink/public/mojom/page/drag.mojom index 676e5653..ff0a985 100644 --- a/third_party/blink/public/mojom/page/drag.mojom +++ b/third_party/blink/public/mojom/page/drag.mojom
@@ -6,6 +6,7 @@ import "mojo/public/mojom/base/file_path.mojom"; import "mojo/public/mojom/base/string16.mojom"; +import "services/network/public/mojom/referrer_policy.mojom"; import "url/mojom/url.mojom"; import "third_party/blink/public/mojom/native_file_system/native_file_system_drag_drop_token.mojom"; @@ -88,4 +89,8 @@ string file_system_id; // Only used when dragging into Blink to represent a // new isolated file system to access the dropped // files. + + // Used for DragItemString when string_type == "downloadurl". + network.mojom.ReferrerPolicy referrer_policy = + network.mojom.ReferrerPolicy.kDefault; };
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 2500559..c6d8ff0 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2704,6 +2704,8 @@ kWrongBaselineOfEmptyLineButton = 3373, kV8RTCRtpTransceiver_Stopped_AttributeGetter = 3374, kV8RTCRtpTransceiver_Stop_Method = 3375, + kSecurePaymentConfirmation = 3376, + kCSSInvalidVariableUnset = 3377, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/web_drag_data.h b/third_party/blink/public/platform/web_drag_data.h index a17d883..e36e4b3 100644 --- a/third_party/blink/public/platform/web_drag_data.h +++ b/third_party/blink/public/platform/web_drag_data.h
@@ -32,6 +32,7 @@ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_DRAG_DATA_H_ #include "base/memory/scoped_refptr.h" +#include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_drag_drop_token.mojom-shared.h" #include "third_party/blink/public/platform/cross_variant_mojo_util.h" #include "third_party/blink/public/platform/web_common.h" @@ -121,9 +122,23 @@ filesystem_id_ = filesystem_id; } + network::mojom::ReferrerPolicy ReferrerPolicy() const { + return referrer_policy_; + } + + void SetReferrerPolicy(network::mojom::ReferrerPolicy referrer_policy) { + referrer_policy_ = referrer_policy; + } + private: WebVector<Item> item_list_; WebString filesystem_id_; + + // Used for items where string_type == "downloadurl". Stores the referrer + // policy for usage when dragging a link out of the webview results in a + // download. + network::mojom::ReferrerPolicy referrer_policy_ = + network::mojom::ReferrerPolicy::kDefault; }; } // namespace blink
diff --git a/third_party/blink/public/web/web_settings.h b/third_party/blink/public/web/web_settings.h index 5a970f6..47ca17b 100644 --- a/third_party/blink/public/web/web_settings.h +++ b/third_party/blink/public/web/web_settings.h
@@ -156,7 +156,6 @@ virtual void SetEditingBehavior(EditingBehavior) = 0; virtual void SetEnableScrollAnimator(bool) = 0; virtual void SetPrefersReducedMotion(bool) = 0; - virtual void SetEnableTouchAdjustment(bool) = 0; virtual void SetSmoothScrollForFindEnabled(bool) = 0; virtual void SetWebGL1Enabled(bool) = 0; virtual void SetWebGL2Enabled(bool) = 0;
diff --git a/third_party/blink/public/web/web_widget_client.h b/third_party/blink/public/web/web_widget_client.h index a4d443c..505f0d6 100644 --- a/third_party/blink/public/web/web_widget_client.h +++ b/third_party/blink/public/web/web_widget_client.h
@@ -187,8 +187,7 @@ } // Called when a drag-and-drop operation should begin. - virtual void StartDragging(network::mojom::ReferrerPolicy, - const WebDragData&, + virtual void StartDragging(const WebDragData&, WebDragOperationsMask, const SkBitmap& drag_image, const gfx::Point& drag_image_offset) {}
diff --git a/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc b/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc index 6fdce97..37f6ed6 100644 --- a/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc +++ b/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc
@@ -395,7 +395,7 @@ const QualifiedName& content_attribute, const char* interface_name, const char* attribute_name) { - PerformAttributeSetCEReactionsReflect<IDLStringV2, const AtomicString&, + PerformAttributeSetCEReactionsReflect<IDLStringV2, AtomicString, &Element::setAttribute>( info, content_attribute, interface_name, attribute_name); } @@ -406,8 +406,7 @@ const char* interface_name, const char* attribute_name) { PerformAttributeSetCEReactionsReflect<IDLStringTreatNullAsEmptyStringV2, - const AtomicString&, - &Element::setAttribute>( + AtomicString, &Element::setAttribute>( info, content_attribute, interface_name, attribute_name); } @@ -416,8 +415,8 @@ const QualifiedName& content_attribute, const char* interface_name, const char* attribute_name) { - PerformAttributeSetCEReactionsReflect< - IDLNullable<IDLStringV2>, const AtomicString&, &Element::setAttribute>( + PerformAttributeSetCEReactionsReflect<IDLNullable<IDLStringV2>, AtomicString, + &Element::setAttribute>( info, content_attribute, interface_name, attribute_name); }
diff --git a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.cc b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.cc index dfae144..d4a62780 100644 --- a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.cc +++ b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.cc
@@ -38,64 +38,19 @@ IDLIntegerConvMode::kEnforceRange) == kEnforceRange, "IDLIntegerConvMode::kEnforceRange == kEnforceRange"); -ScriptWrappable* NativeValueTraitsInterfaceNativeValue( - v8::Isolate* isolate, +void NativeValueTraitsInterfaceNotOfType( const WrapperTypeInfo* wrapper_type_info, - v8::Local<v8::Value> value, ExceptionState& exception_state) { - if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value)) - return ToScriptWrappable(value.As<v8::Object>()); - exception_state.ThrowTypeError(ExceptionMessages::FailedToConvertJSValue( wrapper_type_info->interface_name)); - return nullptr; } -ScriptWrappable* NativeValueTraitsInterfaceArgumentValue( - v8::Isolate* isolate, +void NativeValueTraitsInterfaceNotOfType( const WrapperTypeInfo* wrapper_type_info, int argument_index, - v8::Local<v8::Value> value, ExceptionState& exception_state) { - if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value)) - return ToScriptWrappable(value.As<v8::Object>()); - exception_state.ThrowTypeError(ExceptionMessages::ArgumentNotOfType( argument_index, wrapper_type_info->interface_name)); - return nullptr; -} - -ScriptWrappable* NativeValueTraitsInterfaceOrNullNativeValue( - v8::Isolate* isolate, - const WrapperTypeInfo* wrapper_type_info, - v8::Local<v8::Value> value, - ExceptionState& exception_state) { - if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value)) - return ToScriptWrappable(value.As<v8::Object>()); - - if (value->IsNullOrUndefined()) - return nullptr; - - exception_state.ThrowTypeError(ExceptionMessages::FailedToConvertJSValue( - wrapper_type_info->interface_name)); - return nullptr; -} - -ScriptWrappable* NativeValueTraitsInterfaceOrNullArgumentValue( - v8::Isolate* isolate, - const WrapperTypeInfo* wrapper_type_info, - int argument_index, - v8::Local<v8::Value> value, - ExceptionState& exception_state) { - if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value)) - return ToScriptWrappable(value.As<v8::Object>()); - - if (value->IsNullOrUndefined()) - return nullptr; - - exception_state.ThrowTypeError(ExceptionMessages::ArgumentNotOfType( - argument_index, wrapper_type_info->interface_name)); - return nullptr; } } // namespace bindings
diff --git a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h index 958a6b7c..c4184a5 100644 --- a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h +++ b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h
@@ -38,30 +38,13 @@ class EnumerationBase; class UnionBase; -CORE_EXPORT ScriptWrappable* NativeValueTraitsInterfaceNativeValue( - v8::Isolate* isolate, +CORE_EXPORT void NativeValueTraitsInterfaceNotOfType( const WrapperTypeInfo* wrapper_type_info, - v8::Local<v8::Value> value, ExceptionState& exception_state); -CORE_EXPORT ScriptWrappable* NativeValueTraitsInterfaceArgumentValue( - v8::Isolate* isolate, +CORE_EXPORT void NativeValueTraitsInterfaceNotOfType( const WrapperTypeInfo* wrapper_type_info, int argument_index, - v8::Local<v8::Value> value, - ExceptionState& exception_state); - -CORE_EXPORT ScriptWrappable* NativeValueTraitsInterfaceOrNullNativeValue( - v8::Isolate* isolate, - const WrapperTypeInfo* wrapper_type_info, - v8::Local<v8::Value> value, - ExceptionState& exception_state); - -CORE_EXPORT ScriptWrappable* NativeValueTraitsInterfaceOrNullArgumentValue( - v8::Isolate* isolate, - const WrapperTypeInfo* wrapper_type_info, - int argument_index, - v8::Local<v8::Value> value, ExceptionState& exception_state); } // namespace bindings @@ -1208,22 +1191,29 @@ T, typename std::enable_if_t<std::is_base_of<ScriptWrappable, T>::value>> : public NativeValueTraitsBase<T*> { - static T* NativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exception_state) { - return bindings::NativeValueTraitsInterfaceNativeValue( - isolate, T::GetStaticWrapperTypeInfo(), value, exception_state) - ->template ToImpl<T>(); + static inline T* NativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exception_state) { + const WrapperTypeInfo* wrapper_type_info = T::GetStaticWrapperTypeInfo(); + if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value)) + return ToScriptWrappable(value.As<v8::Object>())->template ToImpl<T>(); + + bindings::NativeValueTraitsInterfaceNotOfType(wrapper_type_info, + exception_state); + return nullptr; } - static T* ArgumentValue(v8::Isolate* isolate, - int argument_index, - v8::Local<v8::Value> value, - ExceptionState& exception_state) { - return bindings::NativeValueTraitsInterfaceArgumentValue( - isolate, T::GetStaticWrapperTypeInfo(), argument_index, value, - exception_state) - ->template ToImpl<T>(); + static inline T* ArgumentValue(v8::Isolate* isolate, + int argument_index, + v8::Local<v8::Value> value, + ExceptionState& exception_state) { + const WrapperTypeInfo* wrapper_type_info = T::GetStaticWrapperTypeInfo(); + if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value)) + return ToScriptWrappable(value.As<v8::Object>())->template ToImpl<T>(); + + bindings::NativeValueTraitsInterfaceNotOfType( + wrapper_type_info, argument_index, exception_state); + return nullptr; } }; @@ -1232,22 +1222,35 @@ IDLNullable<T>, typename std::enable_if_t<std::is_base_of<ScriptWrappable, T>::value>> : public NativeValueTraitsBase<IDLNullable<T>> { - static T* NativeValue(v8::Isolate* isolate, - v8::Local<v8::Value> value, - ExceptionState& exception_state) { - return bindings::NativeValueTraitsInterfaceOrNullNativeValue( - isolate, T::GetStaticWrapperTypeInfo(), value, exception_state) - ->template ToImpl<T>(); + static inline T* NativeValue(v8::Isolate* isolate, + v8::Local<v8::Value> value, + ExceptionState& exception_state) { + const WrapperTypeInfo* wrapper_type_info = T::GetStaticWrapperTypeInfo(); + if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value)) + return ToScriptWrappable(value.As<v8::Object>())->template ToImpl<T>(); + + if (value->IsNullOrUndefined()) + return nullptr; + + bindings::NativeValueTraitsInterfaceNotOfType(wrapper_type_info, + exception_state); + return nullptr; } - static T* ArgumentValue(v8::Isolate* isolate, - int argument_index, - v8::Local<v8::Value> value, - ExceptionState& exception_state) { - return bindings::NativeValueTraitsInterfaceOrNullArgumentValue( - isolate, T::GetStaticWrapperTypeInfo(), argument_index, value, - exception_state) - ->template ToImpl<T>(); + static inline T* ArgumentValue(v8::Isolate* isolate, + int argument_index, + v8::Local<v8::Value> value, + ExceptionState& exception_state) { + const WrapperTypeInfo* wrapper_type_info = T::GetStaticWrapperTypeInfo(); + if (V8PerIsolateData::From(isolate)->HasInstance(wrapper_type_info, value)) + return ToScriptWrappable(value.As<v8::Object>())->template ToImpl<T>(); + + if (value->IsNullOrUndefined()) + return nullptr; + + bindings::NativeValueTraitsInterfaceNotOfType( + wrapper_type_info, argument_index, exception_state); + return nullptr; } };
diff --git a/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/third_party/blink/renderer/bindings/core/v8/script_controller.cc index 02ff8f7..abf3624 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_controller.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_controller.cc
@@ -37,10 +37,8 @@ #include "base/bind_helpers.h" #include "third_party/blink/public/web/web_settings.h" -#include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h" #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" #include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" #include "third_party/blink/renderer/bindings/core/v8/window_proxy.h" @@ -112,53 +110,11 @@ v8::TryCatch try_catch(GetIsolate()); try_catch.SetVerbose(true); - // Omit storing base URL if it is same as source URL. - // Note: This improves chance of getting into a fast path in - // ReferrerScriptInfo::ToV8HostDefinedOptions. - KURL stored_base_url = (base_url == source.Url()) ? KURL() : base_url; - - // TODO(hiroshige): Remove this code and related use counters once the - // measurement is done. - ReferrerScriptInfo::BaseUrlSource base_url_source = - ReferrerScriptInfo::BaseUrlSource::kOther; - if (source.SourceLocationType() == - ScriptSourceLocationType::kExternalFile && - !base_url.IsNull()) { - switch (sanitize_script_errors) { - case SanitizeScriptErrors::kDoNotSanitize: - base_url_source = - ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSSameOrigin; - break; - case SanitizeScriptErrors::kSanitize: - base_url_source = - ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin; - break; - } - } - const ReferrerScriptInfo referrer_info(stored_base_url, fetch_options, - base_url_source); - - v8::Local<v8::Script> script; - - v8::ScriptCompiler::CompileOptions compile_options; - V8CodeCache::ProduceCacheOptions produce_cache_options; - v8::ScriptCompiler::NoCacheReason no_cache_reason; - std::tie(compile_options, produce_cache_options, no_cache_reason) = - V8CodeCache::GetCompileOptions(v8_cache_options, source); - if (!V8ScriptRunner::CompileScript(ScriptState::From(context), source, - sanitize_script_errors, compile_options, - no_cache_reason, referrer_info) - .ToLocal(&script)) - return result; - - v8::MaybeLocal<v8::Value> maybe_result; - maybe_result = V8ScriptRunner::RunCompiledScript(GetIsolate(), script, - GetFrame()->DomWindow()); - probe::ProduceCompilationCache(frame_, source, script); - V8CodeCache::ProduceCache(GetIsolate(), script, source, - produce_cache_options); - - if (!maybe_result.ToLocal(&result)) { + if (!V8ScriptRunner::CompileAndRunScript( + GetIsolate(), ScriptState::From(context), GetFrame()->DomWindow(), + source, base_url, sanitize_script_errors, fetch_options, + v8_cache_options) + .ToLocal(&result)) { return result; } }
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc index 94dfa0b..942e6bb 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc
@@ -362,6 +362,65 @@ return result; } +v8::MaybeLocal<v8::Value> V8ScriptRunner::CompileAndRunScript( + v8::Isolate* isolate, + ScriptState* script_state, + ExecutionContext* execution_context, + const ScriptSourceCode& source, + const KURL& base_url, + SanitizeScriptErrors sanitize_script_errors, + const ScriptFetchOptions& fetch_options, + V8CacheOptions v8_cache_options) { + DCHECK_EQ(isolate, script_state->GetIsolate()); + + // Omit storing base URL if it is same as source URL. + // Note: This improves chance of getting into a fast path in + // ReferrerScriptInfo::ToV8HostDefinedOptions. + KURL stored_base_url = (base_url == source.Url()) ? KURL() : base_url; + + // TODO(hiroshige): Remove this code and related use counters once the + // measurement is done. + ReferrerScriptInfo::BaseUrlSource base_url_source = + ReferrerScriptInfo::BaseUrlSource::kOther; + if (source.SourceLocationType() == ScriptSourceLocationType::kExternalFile && + !base_url.IsNull()) { + switch (sanitize_script_errors) { + case SanitizeScriptErrors::kDoNotSanitize: + base_url_source = + ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSSameOrigin; + break; + case SanitizeScriptErrors::kSanitize: + base_url_source = + ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin; + break; + } + } + const ReferrerScriptInfo referrer_info(stored_base_url, fetch_options, + base_url_source); + + v8::Local<v8::Script> script; + + v8::ScriptCompiler::CompileOptions compile_options; + V8CodeCache::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8CodeCache::GetCompileOptions(v8_cache_options, source); + + if (!V8ScriptRunner::CompileScript(script_state, source, + sanitize_script_errors, compile_options, + no_cache_reason, referrer_info) + .ToLocal(&script)) + return v8::MaybeLocal<v8::Value>(); + + v8::MaybeLocal<v8::Value> maybe_result = + V8ScriptRunner::RunCompiledScript(isolate, script, execution_context); + probe::ProduceCompilationCache(probe::ToCoreProbeSink(execution_context), + source, script); + V8CodeCache::ProduceCache(isolate, script, source, produce_cache_options); + + return maybe_result; +} + v8::MaybeLocal<v8::Value> V8ScriptRunner::CompileAndRunInternalScript( v8::Isolate* isolate, ScriptState* script_state,
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h index 01c1eb55..42d9eb8 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h
@@ -27,6 +27,7 @@ #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_SCRIPT_RUNNER_H_ #include "third_party/blink/renderer/bindings/core/v8/sanitize_script_errors.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_cache_options.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -39,7 +40,9 @@ namespace blink { class ExecutionContext; +class KURL; class ReferrerScriptInfo; +class ScriptFetchOptions; class ScriptSourceCode; class ScriptState; class SingleCachedMetadataHandler; @@ -66,9 +69,15 @@ v8::ScriptCompiler::CompileOptions, v8::ScriptCompiler::NoCacheReason, const ReferrerScriptInfo&); - static v8::MaybeLocal<v8::Value> RunCompiledScript(v8::Isolate*, - v8::Local<v8::Script>, - ExecutionContext*); + static v8::MaybeLocal<v8::Value> CompileAndRunScript( + v8::Isolate*, + ScriptState*, + ExecutionContext*, + const ScriptSourceCode&, + const KURL&, + SanitizeScriptErrors, + const ScriptFetchOptions&, + V8CacheOptions); static v8::MaybeLocal<v8::Value> CompileAndRunInternalScript( v8::Isolate*, ScriptState*, @@ -102,6 +111,11 @@ // TODO(adamk): This should live on V8ThrowException, but it depends on // V8Initializer and so can't trivially move to platform/bindings. static void ReportException(v8::Isolate*, v8::Local<v8::Value> exception); + + private: + static v8::MaybeLocal<v8::Value> RunCompiledScript(v8::Isolate*, + v8::Local<v8::Script>, + ExecutionContext*); }; } // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc index e85ea767..c0ed21b 100644 --- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc +++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -358,26 +358,26 @@ v8::TryCatch block(isolate_); - v8::Local<v8::Script> compiled_script; - v8::MaybeLocal<v8::Value> maybe_result; + // TODO(crbug/1114994): Plumb this from ClassicScript. + const KURL base_url = source_code.Url(); + // Use default ReferrerScriptInfo here, as // - A work{er,let} script doesn't have a nonce, and // - a work{er,let} script is always "not parser inserted". - ReferrerScriptInfo referrer_info; - v8::ScriptCompiler::CompileOptions compile_options; - V8CodeCache::ProduceCacheOptions produce_cache_options; - v8::ScriptCompiler::NoCacheReason no_cache_reason; - std::tie(compile_options, produce_cache_options, no_cache_reason) = - V8CodeCache::GetCompileOptions(v8_cache_options, source_code); - if (V8ScriptRunner::CompileScript(script_state_, source_code, - sanitize_script_errors, compile_options, - no_cache_reason, referrer_info) - .ToLocal(&compiled_script)) { - maybe_result = V8ScriptRunner::RunCompiledScript(isolate_, compiled_script, - global_scope_); - V8CodeCache::ProduceCache(isolate_, compiled_script, source_code, - produce_cache_options); - } + // TODO(crbug/1114988): After crbug/1114988 is fixed, this can be the + // default ScriptFetchOptions(). Currently the default ScriptFetchOptions() + // is not used because it has CredentialsMode::kOmit. + // TODO(crbug/1114989): Plumb this from ClassicScript. + ScriptFetchOptions script_fetch_options( + String(), IntegrityMetadataSet(), String(), + ParserDisposition::kNotParserInserted, + network::mojom::CredentialsMode::kSameOrigin, + network::mojom::ReferrerPolicy::kDefault, + mojom::blink::FetchImportanceMode::kImportanceAuto); + + v8::MaybeLocal<v8::Value> maybe_result = V8ScriptRunner::CompileAndRunScript( + isolate_, script_state_, global_scope_, source_code, base_url, + sanitize_script_errors, script_fetch_options, v8_cache_options); if (!block.CanContinue()) { ForbidExecution();
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py index 73ddc4bc0..6cb6ae5 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
@@ -316,8 +316,21 @@ local_vars.append(S("script_state", _format(pattern, _1=_1))) # execution_context - node = S("execution_context", ("ExecutionContext* ${execution_context} = " - "ExecutionContext::From(${script_state});")) + pattern = "ExecutionContext* ${execution_context} = {_1};" + _1 = ("${receiver_execution_context}" + if is_receiver_context else "${current_execution_context}") + local_vars.append(S("execution_context", _format(pattern, _1=_1))) + node = S("current_execution_context", + ("ExecutionContext* ${current_execution_context} = " + "ExecutionContext::From(${current_script_state});")) + node.accumulate( + CodeGenAccumulator.require_include_headers([ + "third_party/blink/renderer/core/execution_context/execution_context.h" + ])) + local_vars.append(node) + node = S("receiver_execution_context", + ("ExecutionContext* ${receiver_execution_context} = " + "ExecutionContext::From(${receiver_script_state});")) node.accumulate( CodeGenAccumulator.require_include_headers([ "third_party/blink/renderer/core/execution_context/execution_context.h" @@ -329,7 +342,7 @@ if is_receiver_context: _1 = "bindings::ExecutionContextFromV8Wrappable(${blink_receiver})" else: - _1 = "${execution_context}" # of the current context + _1 = "${current_execution_context}" text = _format(pattern, _1=_1) local_vars.append(S("execution_context_of_document_tree", text)) @@ -865,8 +878,8 @@ "WebFeature::{}", name_style.constant("CrossOrigin", cg_context.class_like.identifier, cg_context.property_.identifier)) - use_counter = _format("UseCounter::Count(${execution_context}, {});", - web_feature) + use_counter = _format( + "UseCounter::Count(${current_execution_context}, {});", web_feature) cond = T("!BindingSecurity::ShouldAllowAccessTo(" "ToLocalDOMWindow(${current_context}), ${return_value}, " "BindingSecurity::ErrorReportOption::kDoNotReport)") @@ -1236,7 +1249,7 @@ pattern = ("// [DeprecateAs]\n" "Deprecation::CountDeprecation(" - "${execution_context}, WebFeature::k{_1});") + "${current_execution_context}, WebFeature::k{_1});") _1 = name node = TextNode(_format(pattern, _1=_1)) node.accumulate( @@ -1292,13 +1305,15 @@ if ext_attrs.value_of("HighEntropy") == "Direct": text = _format( "// [HighEntropy=Direct]\n" - "Dactyloscoper::RecordDirectSurface" - "(${execution_context}, {measure_constant}, ${return_value});", + "Dactyloscoper::RecordDirectSurface(" + "${current_execution_context}, {measure_constant}, " + "${return_value});", measure_constant=_make_measure_web_feature_constant(cg_context)) else: text = _format( "// [HighEntropy]\n" - "Dactyloscoper::Record(${execution_context}, {measure_constant});", + "Dactyloscoper::Record(" + "${current_execution_context}, {measure_constant});", measure_constant=_make_measure_web_feature_constant(cg_context)) node = TextNode(text) node.accumulate( @@ -1317,7 +1332,7 @@ text = _format( "// [Measure], [MeasureAs]\n" - "UseCounter::Count(${execution_context}, {measure_constant});", + "UseCounter::Count(${current_execution_context}, {measure_constant});", measure_constant=_make_measure_web_feature_constant(cg_context)) node = TextNode(text) node.accumulate(
diff --git a/third_party/blink/renderer/core/animation/animation.cc b/third_party/blink/renderer/core/animation/animation.cc index ceecbc795..1c85b87 100644 --- a/third_party/blink/renderer/core/animation/animation.cc +++ b/third_party/blink/renderer/core/animation/animation.cc
@@ -942,9 +942,7 @@ // * animation does not have either a pending play task or a pending pause // task, // then idle. - // https://github.com/w3c/csswg-drafts/issues/5400 - if (!CurrentTimeInternal() && (!start_time_ || !timeline_) && - !PendingInternal()) + if (!CurrentTimeInternal() && !start_time_ && !PendingInternal()) return kIdle; // 2. Either of the following conditions are true:
diff --git a/third_party/blink/renderer/core/css/BUILD.gn b/third_party/blink/renderer/core/css/BUILD.gn index 5a9abb4..e97aa1f 100644 --- a/third_party/blink/renderer/core/css/BUILD.gn +++ b/third_party/blink/renderer/core/css/BUILD.gn
@@ -687,6 +687,7 @@ "style_element_test.cc", "style_engine_test.cc", "style_environment_variables_test.cc", + "style_rule_test.cc", "style_sheet_contents_test.cc", "style_traversal_root_test.cc", "threaded/css_parser_threaded_test.cc",
diff --git a/third_party/blink/renderer/core/css/css_test_helpers.cc b/third_party/blink/renderer/core/css/css_test_helpers.cc index 51372b85..9df117e 100644 --- a/third_party/blink/renderer/core/css/css_test_helpers.cc +++ b/third_party/blink/renderer/core/css/css_test_helpers.cc
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/css/css_style_sheet.h" #include "third_party/blink/renderer/core/css/css_syntax_string_parser.h" #include "third_party/blink/renderer/core/css/css_variable_data.h" +#include "third_party/blink/renderer/core/css/parser/css_parser.h" #include "third_party/blink/renderer/core/css/parser/css_parser_context.h" #include "third_party/blink/renderer/core/css/parser/css_parser_local_context.h" #include "third_party/blink/renderer/core/css/parser/css_property_parser.h" @@ -137,5 +138,13 @@ return set; } +StyleRuleBase* ParseRule(Document& document, String text) { + TextPosition position; + auto* sheet = CSSStyleSheet::CreateInline(document, NullURL(), position, + UTF8Encoding()); + const auto* context = MakeGarbageCollected<CSSParserContext>(document); + return CSSParser::ParseRule(context, sheet->Contents(), text); +} + } // namespace css_test_helpers } // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_test_helpers.h b/third_party/blink/renderer/core/css/css_test_helpers.h index 04bb35f..26af4fbc 100644 --- a/third_party/blink/renderer/core/css/css_test_helpers.h +++ b/third_party/blink/renderer/core/css/css_test_helpers.h
@@ -66,6 +66,7 @@ const CSSPropertyValueSet* ParseDeclarationBlock( const String& block_text, CSSParserMode mode = kHTMLStandardMode); +StyleRuleBase* ParseRule(Document& document, String text); } // namespace css_test_helpers } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc b/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc index 23cca084..8bd7ea36 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
@@ -210,4 +210,14 @@ local_context.IsAnimationTainted()); } +bool CustomProperty::HasInitialValue() const { + if (!registration_) + return false; + return registration_->InitialVariableData(); +} + +bool CustomProperty::SupportsGuaranteedInvalid() const { + return !registration_ || registration_->Syntax().IsUniversal(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/custom_property.h b/third_party/blink/renderer/core/css/properties/longhands/custom_property.h index 6940f08c..e847acf 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/custom_property.h +++ b/third_party/blink/renderer/core/css/properties/longhands/custom_property.h
@@ -52,6 +52,11 @@ bool IsRegistered() const { return registration_; } + bool HasInitialValue() const; + + // https://drafts.csswg.org/css-variables/#guaranteed-invalid-value + bool SupportsGuaranteedInvalid() const; + void Trace(Visitor* visitor) const { visitor->Trace(registration_); } private:
diff --git a/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc b/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc index 9cc5744..3adeb65 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc
@@ -237,4 +237,36 @@ EXPECT_EQ(CSSPropertyName("--x"), property.GetCSSPropertyName()); } +TEST_F(CustomPropertyTest, SupportsGuaranteedInvalid) { + RegisterProperty(GetDocument(), "--universal", "*", "foo", true); + RegisterProperty(GetDocument(), "--no-initial", "*", base::nullopt, true); + RegisterProperty(GetDocument(), "--length", "<length>", "0px", true); + + CustomProperty unregistered("--unregistered", GetDocument()); + CustomProperty universal("--universal", GetDocument()); + CustomProperty no_initial_value("--no-initial", GetDocument()); + CustomProperty length("--length", GetDocument()); + + EXPECT_TRUE(unregistered.SupportsGuaranteedInvalid()); + EXPECT_TRUE(universal.SupportsGuaranteedInvalid()); + EXPECT_TRUE(no_initial_value.SupportsGuaranteedInvalid()); + EXPECT_FALSE(length.SupportsGuaranteedInvalid()); +} + +TEST_F(CustomPropertyTest, HasInitialValue) { + RegisterProperty(GetDocument(), "--universal", "*", "foo", true); + RegisterProperty(GetDocument(), "--no-initial", "*", base::nullopt, true); + RegisterProperty(GetDocument(), "--length", "<length>", "0px", true); + + CustomProperty unregistered("--unregistered", GetDocument()); + CustomProperty universal("--universal", GetDocument()); + CustomProperty no_initial_value("--no-initial", GetDocument()); + CustomProperty length("--length", GetDocument()); + + EXPECT_FALSE(unregistered.HasInitialValue()); + EXPECT_TRUE(universal.HasInitialValue()); + EXPECT_FALSE(no_initial_value.HasInitialValue()); + EXPECT_TRUE(length.HasInitialValue()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index 8a5dfbf..140d08a 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -963,11 +963,7 @@ track_sizes.push_back(ConvertGridTrackSize(state, *curr_value)); } - GridTrackList track_list(track_sizes); - if (RuntimeEnabledFeatures::LayoutNGGridEnabled()) { - track_list.NGTrackList().AddRepeater(track_sizes, 1); - } - return track_list; + return GridTrackList(track_sizes); } void StyleBuilderConverter::ConvertGridTrackList(
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.cc b/third_party/blink/renderer/core/css/resolver/style_cascade.cc index 37ad268f..1e7bee6 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade.cc +++ b/third_party/blink/renderer/core/css/resolver/style_cascade.cc
@@ -639,8 +639,10 @@ if (resolver.InCycle()) return CSSInvalidVariableValue::Create(); - if (!data) + if (!data) { + MaybeUseCountInvalidVariableUnset(To<CustomProperty>(property)); return cssvalue::CSSUnsetValue::Create(); + } if (data == decl.Value()) return &decl; @@ -999,4 +1001,18 @@ } } +void StyleCascade::MaybeUseCountInvalidVariableUnset( + const CustomProperty& property) { + if (!property.SupportsGuaranteedInvalid()) + return; + if (!property.IsInherited() && !property.HasInitialValue()) + return; + const AtomicString& name = property.GetPropertyNameAtomicString(); + const ComputedStyle* parent_style = state_.ParentStyle(); + if (parent_style && + parent_style->GetVariableData(name, property.IsInherited())) { + CountUse(WebFeature::kCSSInvalidVariableUnset); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.h b/third_party/blink/renderer/core/css/resolver/style_cascade.h index be9389b..40ae3ecc 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade.h +++ b/third_party/blink/renderer/core/css/resolver/style_cascade.h
@@ -343,6 +343,7 @@ void CountUse(WebFeature); void MaybeUseCountRevert(const CSSValue&); void MaybeUseCountSummaryDisplayBlock(); + void MaybeUseCountInvalidVariableUnset(const CustomProperty&); StyleResolverState& state_; MatchResult match_result_;
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc index 2629714..a0a2735 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
@@ -139,6 +139,7 @@ EXPECT_EQ("50px", ComputedValue("font-size", *StyleForId("div"))); div->SetNeedsAnimationStyleRecalc(); + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); StyleForId("div"); ASSERT_TRUE(div->GetElementAnimations()); @@ -170,6 +171,7 @@ EXPECT_EQ("10px", ComputedValue("height", *StyleForId("div"))); div->SetNeedsAnimationStyleRecalc(); + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); StyleForId("div"); ASSERT_TRUE(div->GetElementAnimations()); @@ -209,6 +211,7 @@ EXPECT_EQ("10px", ComputedValue("height", *StyleForId("div"))); div->SetNeedsAnimationStyleRecalc(); + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); StyleForId("div"); ASSERT_TRUE(div->GetElementAnimations()); @@ -239,6 +242,7 @@ EXPECT_EQ("10px", ComputedValue("height", *StyleForId("div"))); div->SetNeedsAnimationStyleRecalc(); + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); StyleForId("div"); ASSERT_TRUE(div->GetElementAnimations()); @@ -387,6 +391,7 @@ EXPECT_EQ("50px", ComputedValue("font-size", *StyleForId("div"))); div->SetNeedsAnimationStyleRecalc(); + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); auto computed_style = StyleForId("div"); EXPECT_TRUE(computed_style->HasFontRelativeUnits()); @@ -411,6 +416,7 @@ EXPECT_EQ("50px", ComputedValue("height", *StyleForId("div"))); div->SetNeedsAnimationStyleRecalc(); + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); auto computed_style = StyleForId("div"); EXPECT_TRUE(computed_style->HasFontRelativeUnits());
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index 71747f8..2e48a73 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -92,6 +92,15 @@ GetStyleEngine().InjectSheet(StyleSheetKey(key), sheet, origin); } + bool IsUseCounted(mojom::WebFeature feature) { + return GetDocument().IsUseCounted(feature); + } + + void ClearUseCounter(mojom::WebFeature feature) { + GetDocument().ClearUseCounterForTesting(feature); + DCHECK(!IsUseCounted(feature)); + } + private: std::unique_ptr<DummyPageHolder> dummy_page_holder_; }; @@ -2942,6 +2951,239 @@ GetDocument().IsUseCounted(WebFeature::kCSSSystemColorComputeToSelf)); } +TEST_F(StyleEngineTest, InvalidVariableUnsetUseCount) { + // Do not count for basic variable usage. + GetDocument().body()->setInnerHTML(R"HTML( + <style> + #outer { --x: foo; } + #inner { --x: bar; } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_FALSE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Do not count when a fallback handles the unknown variable. + GetDocument().body()->setInnerHTML(R"HTML( + <style> + #outer { --x: foo; } + #inner { --x: var(--unknown,bar); } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_FALSE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Do not count for explicit 'unset'. + GetDocument().body()->setInnerHTML(R"HTML( + <style> + #outer { --x: foo; } + #inner { --x: unset; } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_FALSE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Do not count when we anyway end up with the guaranteed-invalid value. + // (Applies to registered properties as well). + GetDocument().body()->setInnerHTML(R"HTML( + <style> + @property --y { + syntax: "*"; + inherits: true; + } + @property --z { + syntax: "*"; + inherits: false; + } + #inner { + --x: var(--unknown); + --y: var(--unknown); + --z: var(--unknown); + } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_FALSE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Count when 'unset' inherits something that not guaranteed-invalid. + GetDocument().body()->setInnerHTML(R"HTML( + <style> + #outer { --x: foo; } + #inner { --x: var(--unknown); } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_TRUE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Do not count for non-universal registered custom properties. + GetDocument().body()->setInnerHTML(R"HTML( + <style> + @property --x { + syntax: "<length>"; + inherits: true; + initial-value: 0px; + } + #outer { --x: 1px; } + #inner { --x: var(--unknown); } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_FALSE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Count for universal registered custom properties. + GetDocument().body()->setInnerHTML(R"HTML( + <style> + @property --x { + syntax: "*"; + inherits: true; + } + #outer { --x: bar; } + #inner { --x: var(--unknown); } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_TRUE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Do not count for non-inherited universal registered custom properties + // without initial value. + GetDocument().body()->setInnerHTML(R"HTML( + <style> + @property --x { + syntax: "*"; + inherits: false; + } + #outer { --x: bar; } + #inner { --x: var(--unknown); } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_FALSE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Count for universal registered custom properties even with an + // initial-value defined. + GetDocument().body()->setInnerHTML(R"HTML( + <style> + @property --x { + syntax: "*"; + inherits: true; + initial-value: foo; + } + #outer { --x: bar; } + #inner { --x: var(--unknown); } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_TRUE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Do not count for cycles. + GetDocument().body()->setInnerHTML(R"HTML( + <style> + @property --a { + syntax: "*"; + inherits: true; + } + @property --b { + syntax: "*"; + inherits: true; + } + #outer { + --a: foo; + --b: foo; + --c: foo; + --d: foo; + } + #inner { + --a: var(--b); + --b: var(--a); + --c: var(--d); + --d: var(--c); + } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_FALSE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Count for @keyframes + GetDocument().body()->setInnerHTML(R"HTML( + <style> + @keyframes anim { + from { --x: var(--unknown); } + to { --x: var(--unknown); } + } + #outer { + --x: foo; + } + #inner { + animation: anim 10s; + } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_TRUE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); + + // Don't count for @keyframes if there's nothing to inherit. + GetDocument().body()->setInnerHTML(R"HTML( + <style> + @keyframes anim { + from { --x: var(--unknown); } + to { --x: var(--unknown); } + } + #inner { + animation: anim 10s; + } + </style> + <div id=outer> + <div id=inner></div> + <div> + )HTML"); + UpdateAllLifecyclePhases(); + EXPECT_FALSE(IsUseCounted(WebFeature::kCSSInvalidVariableUnset)); + ClearUseCounter(WebFeature::kCSSInvalidVariableUnset); +} + class ParameterizedStyleEngineTest : public testing::WithParamInterface<bool>, private ScopedCSSReducedFontLoadingInvalidationsForTest,
diff --git a/third_party/blink/renderer/core/css/style_rule.cc b/third_party/blink/renderer/core/css/style_rule.cc index 6014f7fe..517c868 100644 --- a/third_party/blink/renderer/core/css/style_rule.cc +++ b/third_party/blink/renderer/core/css/style_rule.cc
@@ -380,38 +380,25 @@ StyleRuleScrollTimeline::StyleRuleScrollTimeline( const String& name, const CSSPropertyValueSet* properties) - : StyleRuleBase(kScrollTimeline), name_(name), properties_(properties) {} - -StyleRuleScrollTimeline::StyleRuleScrollTimeline( - const StyleRuleScrollTimeline& scroll_timeline_rule) - : StyleRuleBase(scroll_timeline_rule), - properties_(scroll_timeline_rule.properties_->MutableCopy()) {} + : StyleRuleBase(kScrollTimeline), + name_(name), + source_(properties->GetPropertyCSSValue(CSSPropertyID::kSource)), + orientation_( + properties->GetPropertyCSSValue(CSSPropertyID::kOrientation)), + start_(properties->GetPropertyCSSValue(CSSPropertyID::kStart)), + end_(properties->GetPropertyCSSValue(CSSPropertyID::kEnd)), + time_range_(properties->GetPropertyCSSValue(CSSPropertyID::kTimeRange)) {} StyleRuleScrollTimeline::~StyleRuleScrollTimeline() = default; -const CSSValue* StyleRuleScrollTimeline::GetSource() const { - return properties_->GetPropertyCSSValue(CSSPropertyID::kSource); -} - -const CSSValue* StyleRuleScrollTimeline::GetOrientation() const { - return properties_->GetPropertyCSSValue(CSSPropertyID::kOrientation); -} - -const CSSValue* StyleRuleScrollTimeline::GetStart() const { - return properties_->GetPropertyCSSValue(CSSPropertyID::kStart); -} - -const CSSValue* StyleRuleScrollTimeline::GetEnd() const { - return properties_->GetPropertyCSSValue(CSSPropertyID::kEnd); -} - -const CSSValue* StyleRuleScrollTimeline::GetTimeRange() const { - return properties_->GetPropertyCSSValue(CSSPropertyID::kTimeRange); -} - void StyleRuleScrollTimeline::TraceAfterDispatch( blink::Visitor* visitor) const { - visitor->Trace(properties_); + visitor->Trace(source_); + visitor->Trace(orientation_); + visitor->Trace(start_); + visitor->Trace(end_); + visitor->Trace(time_range_); + StyleRuleBase::TraceAfterDispatch(visitor); }
diff --git a/third_party/blink/renderer/core/css/style_rule.h b/third_party/blink/renderer/core/css/style_rule.h index 34dea7eb..83d81c3 100644 --- a/third_party/blink/renderer/core/css/style_rule.h +++ b/third_party/blink/renderer/core/css/style_rule.h
@@ -212,10 +212,10 @@ Member<CSSPropertyValueSet> properties_; }; -class StyleRuleScrollTimeline : public StyleRuleBase { +class CORE_EXPORT StyleRuleScrollTimeline : public StyleRuleBase { public: StyleRuleScrollTimeline(const String& name, const CSSPropertyValueSet*); - StyleRuleScrollTimeline(const StyleRuleScrollTimeline&); + StyleRuleScrollTimeline(const StyleRuleScrollTimeline&) = default; ~StyleRuleScrollTimeline(); StyleRuleScrollTimeline* Copy() const { @@ -225,15 +225,19 @@ void TraceAfterDispatch(blink::Visitor*) const; const String& GetName() const { return name_; } - const CSSValue* GetSource() const; - const CSSValue* GetOrientation() const; - const CSSValue* GetStart() const; - const CSSValue* GetEnd() const; - const CSSValue* GetTimeRange() const; + const CSSValue* GetSource() const { return source_; } + const CSSValue* GetOrientation() const { return orientation_; } + const CSSValue* GetStart() const { return start_; } + const CSSValue* GetEnd() const { return end_; } + const CSSValue* GetTimeRange() const { return time_range_; } private: String name_; - Member<const CSSPropertyValueSet> properties_; + Member<const CSSValue> source_; + Member<const CSSValue> orientation_; + Member<const CSSValue> start_; + Member<const CSSValue> end_; + Member<const CSSValue> time_range_; }; class CORE_EXPORT StyleRuleGroup : public StyleRuleBase {
diff --git a/third_party/blink/renderer/core/css/style_rule_test.cc b/third_party/blink/renderer/core/css/style_rule_test.cc new file mode 100644 index 0000000..92423a3b --- /dev/null +++ b/third_party/blink/renderer/core/css/style_rule_test.cc
@@ -0,0 +1,80 @@ +// 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/renderer/core/css/style_rule.h" + +#include "third_party/blink/renderer/core/css/css_test_helpers.h" +#include "third_party/blink/renderer/core/testing/page_test_base.h" +#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" + +namespace blink { + +class StyleRuleTest : public PageTestBase {}; + +// Verifies that a StyleRuleScrollTimeline can be accessed even if +// the runtime flag CSSScrollTimeline is disabled. +// +// Note that this test can be removed when the CSSScrollTimeline flag is +// removed. +TEST_F(StyleRuleTest, StyleRuleScrollTimelineGettersWithoutFeature) { + ScopedCSSScrollTimelineForTest scoped_feature(false); + + StyleRuleBase* base_rule = nullptr; + + { + ScopedCSSScrollTimelineForTest scoped_feature(true); + base_rule = css_test_helpers::ParseRule(GetDocument(), R"CSS( + @scroll-timeline timeline { + source: selector(#foo); + start: 1px; + end: 2px; + time-range: 10s; + } + )CSS"); + } + + ASSERT_TRUE(base_rule); + const auto* rule = To<StyleRuleScrollTimeline>(base_rule); + + // Don't crash: + EXPECT_FALSE(rule->GetName().IsEmpty()); + EXPECT_TRUE(rule->GetSource()); + EXPECT_TRUE(rule->GetStart()); + EXPECT_TRUE(rule->GetEnd()); + EXPECT_TRUE(rule->GetTimeRange()); +} + +TEST_F(StyleRuleTest, StyleRuleScrollTimelineCopy) { + ScopedCSSScrollTimelineForTest scoped_feature(true); + + auto* base_rule = css_test_helpers::ParseRule(GetDocument(), R"CSS( + @scroll-timeline timeline { + source: selector(#foo); + start: 1px; + end: 2px; + time-range: 10s; + } + )CSS"); + + ASSERT_TRUE(base_rule); + auto* base_copy = base_rule->Copy(); + + EXPECT_NE(base_rule, base_copy); + EXPECT_EQ(base_rule->GetType(), base_copy->GetType()); + + auto* rule = DynamicTo<StyleRuleScrollTimeline>(base_rule); + auto* copy = DynamicTo<StyleRuleScrollTimeline>(base_copy); + + ASSERT_TRUE(rule); + ASSERT_TRUE(copy); + + EXPECT_EQ(rule->GetName(), copy->GetName()); + EXPECT_EQ(rule->GetSource(), copy->GetSource()); + EXPECT_EQ(rule->GetOrientation(), copy->GetOrientation()); + EXPECT_EQ(rule->GetStart(), copy->GetStart()); + EXPECT_EQ(rule->GetEnd(), copy->GetEnd()); + EXPECT_EQ(rule->GetTimeRange(), copy->GetTimeRange()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/dom/attribute.h b/third_party/blink/renderer/core/dom/attribute.h index 3db098e..1869c50 100644 --- a/third_party/blink/renderer/core/dom/attribute.h +++ b/third_party/blink/renderer/core/dom/attribute.h
@@ -39,8 +39,8 @@ DISALLOW_NEW(); public: - Attribute(const QualifiedName& name, AtomicString value) - : name_(name), value_(std::move(value)) {} + Attribute(const QualifiedName& name, const AtomicString& value) + : name_(name), value_(value) {} // NOTE: The references returned by these functions are only valid for as long // as the Attribute stays in place. For example, calling a function that @@ -56,10 +56,7 @@ bool Matches(const QualifiedName&) const; bool MatchesCaseInsensitive(const QualifiedName&) const; - void SetValue(AtomicString value) { value_ = std::move(value); } - AtomicString ExchangeValue(AtomicString value) { - return std::exchange(value_, std::move(value)); - } + void SetValue(const AtomicString& value) { value_ = value; } // Note: This API is only for HTMLTreeBuilder. It is not safe to change the // name of an attribute once parseAttribute has been called as DOM
diff --git a/third_party/blink/renderer/core/dom/attribute_collection.h b/third_party/blink/renderer/core/dom/attribute_collection.h index 30df3cc..c403f85 100644 --- a/third_party/blink/renderer/core/dom/attribute_collection.h +++ b/third_party/blink/renderer/core/dom/attribute_collection.h
@@ -160,15 +160,13 @@ attributes) {} // These functions do no error/duplicate checking. - const AtomicString& Append(const QualifiedName&, AtomicString value); + void Append(const QualifiedName&, const AtomicString& value); void Remove(unsigned index); }; -inline const AtomicString& MutableAttributeCollection::Append( - const QualifiedName& name, - AtomicString value) { - attributes_.emplace_back(name, std::move(value)); - return attributes_.back().Value(); +inline void MutableAttributeCollection::Append(const QualifiedName& name, + const AtomicString& value) { + attributes_.push_back(Attribute(name, value)); } inline void MutableAttributeCollection::Remove(unsigned index) {
diff --git a/third_party/blink/renderer/core/dom/element-hot.cc b/third_party/blink/renderer/core/dom/element-hot.cc index 87b14332..bee9f40f 100644 --- a/third_party/blink/renderer/core/dom/element-hot.cc +++ b/third_party/blink/renderer/core/dom/element-hot.cc
@@ -120,45 +120,45 @@ g_null_atom)); } -void Element::setAttribute(const QualifiedName& name, AtomicString value) { +void Element::setAttribute(const QualifiedName& name, + const AtomicString& value) { SynchronizeAttribute(name); wtf_size_t index = GetElementData() ? GetElementData()->Attributes().FindIndex(name) : kNotFound; - SetAttributeInternal(index, name, std::move(value), + SetAttributeInternal(index, name, value, kNotInSynchronizationOfLazyAttribute); } void Element::setAttribute(const QualifiedName& name, - AtomicString value, + const AtomicString& value, ExceptionState& exception_state) { SynchronizeAttribute(name); wtf_size_t index = GetElementData() ? GetElementData()->Attributes().FindIndex(name) : kNotFound; - AtomicString trusted_value(TrustedTypesCheckFor( - ExpectedTrustedTypeForAttribute(name), std::move(value), - GetExecutionContext(), exception_state)); + AtomicString trusted_value( + TrustedTypesCheckFor(ExpectedTrustedTypeForAttribute(name), value, + GetExecutionContext(), exception_state)); if (exception_state.HadException()) return; - SetAttributeInternal(index, name, std::move(trusted_value), + SetAttributeInternal(index, name, trusted_value, kNotInSynchronizationOfLazyAttribute); } void Element::SetSynchronizedLazyAttribute(const QualifiedName& name, - AtomicString value) { + const AtomicString& value) { wtf_size_t index = GetElementData() ? GetElementData()->Attributes().FindIndex(name) : kNotFound; - SetAttributeInternal(index, name, std::move(value), - kInSynchronizationOfLazyAttribute); + SetAttributeInternal(index, name, value, kInSynchronizationOfLazyAttribute); } void Element::SetAttributeHinted(const AtomicString& local_name, WTF::AtomicStringTable::WeakResult hint, - AtomicString value, + const AtomicString& value, ExceptionState& exception_state) { if (!Document::IsValidName(local_name)) { exception_state.ThrowDOMException( @@ -178,7 +178,7 @@ if (exception_state.HadException()) return; - SetAttributeInternal(index, q_name, std::move(trusted_value), + SetAttributeInternal(index, q_name, trusted_value, kNotInSynchronizationOfLazyAttribute); } @@ -204,14 +204,14 @@ GetExecutionContext(), exception_state)); if (exception_state.HadException()) return; - SetAttributeInternal(index, q_name, std::move(value), + SetAttributeInternal(index, q_name, value, kNotInSynchronizationOfLazyAttribute); } ALWAYS_INLINE void Element::SetAttributeInternal( wtf_size_t index, const QualifiedName& name, - AtomicString new_value, + const AtomicString& new_value, SynchronizationOfLazyAttribute in_synchronization_of_lazy_attribute) { if (new_value.IsNull()) { if (index != kNotFound) @@ -220,32 +220,25 @@ } if (index == kNotFound) { - AppendAttributeInternal(name, std::move(new_value), + AppendAttributeInternal(name, new_value, in_synchronization_of_lazy_attribute); return; } const Attribute& existing_attribute = GetElementData()->Attributes().at(index); + AtomicString existing_attribute_value = existing_attribute.Value(); + QualifiedName existing_attribute_name = existing_attribute.GetName(); if (!in_synchronization_of_lazy_attribute) { - WillModifyAttribute(existing_attribute.GetName(), - existing_attribute.Value(), new_value); + WillModifyAttribute(existing_attribute_name, existing_attribute_value, + new_value); } - - AtomicString old_value_storage; // Keep the old value alive in an update. - const AtomicString* old_val_ptr = &existing_attribute.Value(); - const AtomicString* new_val_ptr = &new_value; - if (new_value != *old_val_ptr) { - Attribute& attribute = EnsureUniqueElementData().Attributes().at(index); - old_value_storage = attribute.ExchangeValue(std::move(new_value)); - old_val_ptr = &old_value_storage; - new_val_ptr = &attribute.Value(); - } - + if (new_value != existing_attribute_value) + EnsureUniqueElementData().Attributes().at(index).SetValue(new_value); if (!in_synchronization_of_lazy_attribute) { - DidModifyAttribute(existing_attribute.GetName(), *old_val_ptr, - *new_val_ptr); + DidModifyAttribute(existing_attribute_name, existing_attribute_value, + new_value); } } @@ -308,7 +301,7 @@ } } - SetAttributeInternal(index, attr_node->GetQualifiedName(), std::move(value), + SetAttributeInternal(index, attr_node->GetQualifiedName(), value, kNotInSynchronizationOfLazyAttribute); attr_node->AttachToElement(this, local_name);
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 3ed7bcb..4e763c6 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3794,7 +3794,7 @@ if (exception_state.HadException()) return; - setAttribute(parsed_name, std::move(value)); + setAttribute(parsed_name, value); } void Element::RemoveAttributeInternal( @@ -3828,14 +3828,13 @@ void Element::AppendAttributeInternal( const QualifiedName& name, - AtomicString value, + const AtomicString& value, SynchronizationOfLazyAttribute in_synchronization_of_lazy_attribute) { if (!in_synchronization_of_lazy_attribute) WillModifyAttribute(name, g_null_atom, value); - const AtomicString& stored_value = - EnsureUniqueElementData().Attributes().Append(name, std::move(value)); + EnsureUniqueElementData().Attributes().Append(name, value); if (!in_synchronization_of_lazy_attribute) - DidAddAttribute(name, stored_value); + DidAddAttribute(name, value); } void Element::removeAttributeNS(const AtomicString& namespace_uri,
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index d21249ab..7d6143be 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -162,9 +162,12 @@ // Passing g_null_atom as the second parameter removes the attribute when // calling either of these set methods. - void setAttribute(const QualifiedName&, AtomicString value); - void setAttribute(const QualifiedName&, AtomicString value, ExceptionState&); - void SetSynchronizedLazyAttribute(const QualifiedName&, AtomicString value); + void setAttribute(const QualifiedName&, const AtomicString& value); + void setAttribute(const QualifiedName&, + const AtomicString& value, + ExceptionState&); + void SetSynchronizedLazyAttribute(const QualifiedName&, + const AtomicString& value); void removeAttribute(const QualifiedName&); @@ -230,7 +233,7 @@ void setAttribute(const AtomicString& name, AtomicString value, ExceptionState& exception_state = ASSERT_NO_EXCEPTION) { - SetAttributeHinted(name, WeakLowercaseIfNecessary(name), std::move(value), + SetAttributeHinted(name, WeakLowercaseIfNecessary(name), value, exception_state); } @@ -262,7 +265,7 @@ bool toggleAttribute(const AtomicString&, bool force, ExceptionState&); const AtomicString& GetIdAttribute() const; - void SetIdAttribute(AtomicString); + void SetIdAttribute(const AtomicString&); const AtomicString& GetNameAttribute() const; const AtomicString& GetClassAttribute() const; @@ -1099,10 +1102,10 @@ void SetAttributeInternal(wtf_size_t index, const QualifiedName&, - AtomicString value, + const AtomicString& value, SynchronizationOfLazyAttribute); void AppendAttributeInternal(const QualifiedName&, - AtomicString value, + const AtomicString& value, SynchronizationOfLazyAttribute); void RemoveAttributeInternal(wtf_size_t index, SynchronizationOfLazyAttribute); @@ -1126,7 +1129,7 @@ WTF::AtomicStringTable::WeakResult hint) const; void SetAttributeHinted(const AtomicString& name, WTF::AtomicStringTable::WeakResult hint, - AtomicString value, + const AtomicString& value, ExceptionState& = ASSERT_NO_EXCEPTION); void SetAttributeHinted( const AtomicString& name, @@ -1326,8 +1329,8 @@ return FastGetAttribute(html_names::kClassAttr); } -inline void Element::SetIdAttribute(AtomicString value) { - setAttribute(html_names::kIdAttr, std::move(value)); +inline void Element::SetIdAttribute(const AtomicString& value) { + setAttribute(html_names::kIdAttr, value); } inline const SpaceSplitString& Element::ClassNames() const {
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.cc b/third_party/blink/renderer/core/exported/web_settings_impl.cc index de0a67d0..bc993032 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.cc +++ b/third_party/blink/renderer/core/exported/web_settings_impl.cc
@@ -564,10 +564,6 @@ settings_->SetPrefersReducedMotion(enabled); } -void WebSettingsImpl::SetEnableTouchAdjustment(bool enabled) { - settings_->SetTouchAdjustmentEnabled(enabled); -} - bool WebSettingsImpl::ViewportEnabled() const { return settings_->GetViewportEnabled(); }
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.h b/third_party/blink/renderer/core/exported/web_settings_impl.h index 13ed538..f6589f1 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.h +++ b/third_party/blink/renderer/core/exported/web_settings_impl.h
@@ -84,7 +84,6 @@ void SetEditingBehavior(EditingBehavior) override; void SetEnableScrollAnimator(bool) override; void SetPrefersReducedMotion(bool) override; - void SetEnableTouchAdjustment(bool) override; void SetWebGL1Enabled(bool) override; void SetWebGL2Enabled(bool) override; void SetFantasyFontFamily(const WebString&,
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 59751ba1f..e42105c0 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1683,9 +1683,8 @@ void WebViewImpl::EnterFullscreen(LocalFrame& frame, const FullscreenOptions* options, - bool for_cross_process_descendant) { - fullscreen_controller_->EnterFullscreen(frame, options, - for_cross_process_descendant); + FullscreenRequestType request_type) { + fullscreen_controller_->EnterFullscreen(frame, options, request_type); } void WebViewImpl::ExitFullscreen(LocalFrame& frame) { @@ -2461,11 +2460,31 @@ /*is_initial_state=*/false); } + // Make sure no TrackedFeaturesUpdate message is sent after the ACK + // TODO(carlscab): Do we really need to go through LocalFrame => + // platform/scheduler/ => LocalFrame to report the features? We can probably + // move SchedulerTrackedFeatures to core/ and remove the back and forth. + ReportActiveSchedulerTrackedFeatures(); + lifecycle_state_ = std::move(state); // Tell the browser that the freezing or resuming was successful. std::move(callback).Run(); } +void WebViewImpl::ReportActiveSchedulerTrackedFeatures() { + Page* page = GetPage(); + if (!page) + return; + + for (Frame* frame = page->MainFrame(); frame; + frame = frame->Tree().TraverseNext()) { + if (!frame->IsLocalFrame()) + continue; + auto* local_frame = DynamicTo<LocalFrame>(frame); + local_frame->GetFrameScheduler()->ReportActiveSchedulerTrackedFeatures(); + } +} + void WebViewImpl::AudioStateChanged(bool is_audio_playing) { GetPage()->GetPageScheduler()->AudioStateChanged(is_audio_playing); }
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 24fc09e..dfa50fb 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -95,6 +95,8 @@ class WebFrameWidgetBase; class WebViewFrameWidget; +enum class FullscreenRequestType; + namespace mojom { namespace blink { class TextAutosizerPageInfo; @@ -377,7 +379,7 @@ void EnterFullscreen(LocalFrame&, const FullscreenOptions*, - bool for_cross_process_descendant); + FullscreenRequestType); void ExitFullscreen(LocalFrame&); void FullscreenElementChanged(Element* old_element, Element* new_element); @@ -570,6 +572,9 @@ IntPoint& scroll, bool& need_animation); + // Sends any outstanding TrackedFeaturesUpdate messages to the browser. + void ReportActiveSchedulerTrackedFeatures(); + // These member variables should not be accessed within calls to WebWidget // APIs. They can be called from within WebView APIs, and internal methods, // though these need to be sorted as being for the view or the widget also.
diff --git a/third_party/blink/renderer/core/frame/fullscreen_controller.cc b/third_party/blink/renderer/core/frame/fullscreen_controller.cc index 3a19bd8b..78482d7 100644 --- a/third_party/blink/renderer/core/frame/fullscreen_controller.cc +++ b/third_party/blink/renderer/core/frame/fullscreen_controller.cc
@@ -112,7 +112,7 @@ void FullscreenController::EnterFullscreen(LocalFrame& frame, const FullscreenOptions* options, - bool for_cross_process_descendant) { + FullscreenRequestType request_type) { // TODO(dtapuska): If we are already in fullscreen. If the options are // different than the currently requested one we may wish to request // fullscreen mode again. @@ -155,9 +155,28 @@ fullscreen_options->display_id = options->screen()->DisplayId(); } + // TODO(alexmos): currently, this assumes prefixed requests, but in the + // future, this should plumb in information about which request type + // (prefixed or unprefixed) to use for firing fullscreen events. + // + // This is basically implemented, but disabled for now since it's potentially + // an application-visible change in behavior. To enable, use the following: + // + // fullscreen_options->is_prefixed = + // request_type & FullscreenRequestType::kPrefixed; + fullscreen_options->is_prefixed = true; + +#if DCHECK_IS_ON() + DVLOG(2) << __func__ << ": request_type=" + << FullscreenRequestTypeToDebugString(request_type) + << " fullscreen_options={display_id=" + << fullscreen_options->display_id + << ", is_prefixed=" << fullscreen_options->is_prefixed << "}"; +#endif + // Don't send redundant EnterFullscreen message to the browser for the // ancestor frames if the subframe has already entered fullscreen. - if (!for_cross_process_descendant) { + if (!(request_type & FullscreenRequestType::kForCrossProcessDescendant)) { frame.GetLocalFrameHostRemote().EnterFullscreen( std::move(fullscreen_options), WTF::Bind(&FullscreenController::EnterFullscreenCallback,
diff --git a/third_party/blink/renderer/core/frame/fullscreen_controller.h b/third_party/blink/renderer/core/frame/fullscreen_controller.h index e7c0e47..243b734 100644 --- a/third_party/blink/renderer/core/frame/fullscreen_controller.h +++ b/third_party/blink/renderer/core/frame/fullscreen_controller.h
@@ -47,6 +47,8 @@ class LocalFrame; class WebViewImpl; +enum class FullscreenRequestType; + // FullscreenController is a per-WebView class that manages the transition into // and out of fullscreen, including restoring scroll offset and scale after // exiting fullscreen. It is (indirectly) used by the Fullscreen class. @@ -60,7 +62,7 @@ // fullscreen. void EnterFullscreen(LocalFrame&, const FullscreenOptions*, - bool for_cross_process_descendant); + FullscreenRequestType request_type); void ExitFullscreen(LocalFrame&); // Called by content::RenderWidget (via WebWidget) to notify that we've
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index a022db8..97cd8eb 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -343,6 +343,9 @@ GetRemoteNavigationAssociatedInterfaces()->GetInterface( local_frame_host_remote_.BindNewEndpointAndPassReceiver( GetTaskRunner(blink::TaskType::kInternalDefault))); + GetRemoteNavigationAssociatedInterfaces()->GetInterface( + back_forward_cache_controller_host_remote_.BindNewEndpointAndPassReceiver( + GetTaskRunner(blink::TaskType::kInternalDefault))); GetInterfaceRegistry()->AddAssociatedInterface(WTF::BindRepeating( &LocalFrame::BindToReceiver, WrapWeakPersistent(this))); GetInterfaceRegistry()->AddInterface( @@ -443,6 +446,7 @@ visitor->Trace(text_input_host_); #endif visitor->Trace(local_frame_host_remote_); + visitor->Trace(back_forward_cache_controller_host_remote_); visitor->Trace(receiver_); visitor->Trace(main_frame_receiver_); visitor->Trace(high_priority_frame_receiver_); @@ -2328,7 +2332,7 @@ } void LocalFrame::EvictFromBackForwardCache() { - GetLocalFrameHostRemote().EvictFromBackForwardCache(); + GetBackForwardCacheControllerHostRemote().EvictFromBackForwardCache(); } void LocalFrame::AnimateDoubleTapZoom(const gfx::Point& point, @@ -2559,6 +2563,11 @@ return *local_frame_host_remote_.get(); } +mojom::blink::BackForwardCacheControllerHost& +LocalFrame::GetBackForwardCacheControllerHostRemote() { + return *back_forward_cache_controller_host_remote_.get(); +} + void LocalFrame::GetTextSurroundingSelection( uint32_t max_length, GetTextSurroundingSelectionCallback callback) {
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 4d11452d..ddbe21c 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -39,6 +39,7 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/unique_receiver_set.h" #include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h" +#include "third_party/blink/public/mojom/frame/back_forward_cache_controller.mojom-blink.h" #include "third_party/blink/public/mojom/frame/frame.mojom-blink.h" #include "third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink-forward.h" #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink-forward.h" @@ -481,6 +482,11 @@ // associated interface with the legacy Chrome IPC channel. mojom::blink::LocalFrameHost& GetLocalFrameHostRemote(); + // Returns the bfcache controller host ptr. The interface returned is backed + // by an associated interface with the legacy Chrome IPC channel. + mojom::blink::BackForwardCacheControllerHost& + GetBackForwardCacheControllerHostRemote(); + // Overlays a color on top of this LocalFrameView if it is associated with // the main frame. Should not have multiple consumers. void SetMainFrameColorOverlay(SkColor color); @@ -841,6 +847,10 @@ HeapMojoWrapperMode::kWithoutContextObserver> local_frame_host_remote_{nullptr}; // LocalFrame can be reused by multiple ExecutionContext. + HeapMojoAssociatedRemote<mojom::blink::BackForwardCacheControllerHost, + HeapMojoWrapperMode::kWithoutContextObserver> + back_forward_cache_controller_host_remote_{nullptr}; + // LocalFrame can be reused by multiple ExecutionContext. HeapMojoAssociatedReceiver<mojom::blink::LocalFrame, LocalFrame, HeapMojoWrapperMode::kWithoutContextObserver>
diff --git a/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc b/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc index 2b98cc3..96231b7 100644 --- a/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc +++ b/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc
@@ -2,6 +2,7 @@ // 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/mojom/frame/back_forward_cache_controller.mojom-blink.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "base/run_loop.h" @@ -19,9 +20,25 @@ namespace blink { -class TestLocalFrameBackForwardCacheClient : public FakeLocalFrameHost { +class TestLocalFrameBackForwardCacheClient + : public mojom::blink::BackForwardCacheControllerHost { public: - TestLocalFrameBackForwardCacheClient() {} + explicit TestLocalFrameBackForwardCacheClient( + blink::AssociatedInterfaceProvider* provider) { + provider->OverrideBinderForTesting( + mojom::blink::BackForwardCacheControllerHost::Name_, + base::BindRepeating( + [](TestLocalFrameBackForwardCacheClient* parent, + mojo::ScopedInterfaceEndpointHandle handle) { + parent->receiver_.Bind( + mojo::PendingAssociatedReceiver< + mojom::blink::BackForwardCacheControllerHost>( + std::move(handle))); + }, + base::Unretained(this))); + fake_local_frame_host_.Init(provider); + } + ~TestLocalFrameBackForwardCacheClient() override = default; void EvictFromBackForwardCache() override { quit_closure_.Run(); } @@ -33,6 +50,14 @@ } private: + void BindReceiver(mojo::ScopedInterfaceEndpointHandle handle) { + receiver_.Bind( + mojo::PendingAssociatedReceiver< + mojom::blink::BackForwardCacheControllerHost>(std::move(handle))); + } + FakeLocalFrameHost fake_local_frame_host_; + mojo::AssociatedReceiver<mojom::blink::BackForwardCacheControllerHost> + receiver_{this}; base::RepeatingClosure quit_closure_; }; @@ -47,10 +72,10 @@ // frame state is immutable when the frame is in the bfcache. // (https://www.chromestatus.com/feature/5815270035685376). TEST_F(LocalFrameBackForwardCacheTest, EvictionOnV8ExecutionAtMicrotask) { - TestLocalFrameBackForwardCacheClient frame_host; frame_test_helpers::TestWebFrameClient web_frame_client; + TestLocalFrameBackForwardCacheClient frame_host( + web_frame_client.GetRemoteNavigationAssociatedInterfaces()); frame_test_helpers::WebViewHelper web_view_helper; - frame_host.Init(web_frame_client.GetRemoteNavigationAssociatedInterfaces()); web_view_helper.Initialize( &web_frame_client, nullptr, nullptr, [](WebSettings* settings) { settings->SetJavaScriptEnabled(true); });
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index ae92c1c2..990744f 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2169,6 +2169,12 @@ DocumentLifecycle::kCompositingAssignmentsClean, reason); } +bool LocalFrameView::UpdateLifecycleToPrePaintClean( + DocumentUpdateReason reason) { + return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases( + DocumentLifecycle::kPrePaintClean, reason); +} + // TODO(schenney): Pass a LifecycleUpdateReason in here bool LocalFrameView::UpdateLifecycleToCompositingInputsClean( DocumentUpdateReason reason) { @@ -2187,7 +2193,6 @@ void LocalFrameView::UpdateLifecyclePhasesForPrinting() { auto* local_frame_view_root = GetFrame().LocalFrameRoot().View(); - // TODO(chrishr): this can be changed to kPrePaintClean local_frame_view_root->UpdateLifecyclePhases( DocumentLifecycle::kCompositingAssignmentsClean, DocumentUpdateReason::kPrinting);
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index f13c88d..3e099dda 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -353,6 +353,8 @@ // detached frame and need special handling of the frame. void UpdateLifecyclePhasesForPrinting(); + bool UpdateLifecycleToPrePaintClean(DocumentUpdateReason reason); + // After calling this method, all frames will be in a lifecycle // state >= CompositingClean, and scrolling has been updated (unless // throttling is allowed), unless the frame was throttled or inactive.
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc index 83fb8fd..a607c06 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.cc +++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -404,7 +404,8 @@ security_context_.SetInsecureNavigationsSet(set); } -void RemoteFrame::WillEnterFullscreen() { +void RemoteFrame::WillEnterFullscreen( + mojom::blink::FullscreenOptionsPtr request_options) { // This should only ever be called when the FrameOwner is local. HTMLFrameOwnerElement* owner_element = To<HTMLFrameOwnerElement>(Owner()); @@ -412,17 +413,17 @@ // fullscreen element in anticipation of the coming |didEnterFullscreen()| // call. // - // PrefixedForCrossProcessDescendant is necessary because: + // ForCrossProcessDescendant is necessary because: // - The fullscreen element ready check and other checks should be bypassed. // - |ownerElement| will need :-webkit-full-screen-ancestor style in addition // to :fullscreen. - // - // TODO(alexmos): currently, this assumes prefixed requests, but in the - // future, this should plumb in information about which request type - // (prefixed or unprefixed) to use for firing fullscreen events. - Fullscreen::RequestFullscreen( - *owner_element, FullscreenOptions::Create(), - Fullscreen::RequestType::kPrefixedForCrossProcessDescendant); + FullscreenRequestType request_type = + (request_options->is_prefixed ? FullscreenRequestType::kPrefixed + : FullscreenRequestType::kUnprefixed) | + FullscreenRequestType::kForCrossProcessDescendant; + + Fullscreen::RequestFullscreen(*owner_element, FullscreenOptions::Create(), + request_type); } void RemoteFrame::AddReplicatedContentSecurityPolicies(
diff --git a/third_party/blink/renderer/core/frame/remote_frame.h b/third_party/blink/renderer/core/frame/remote_frame.h index 636ee4325..ed5b3c7 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.h +++ b/third_party/blink/renderer/core/frame/remote_frame.h
@@ -112,7 +112,7 @@ const String& UniqueName() const { return unique_name_; } // blink::mojom::RemoteFrame overrides: - void WillEnterFullscreen() override; + void WillEnterFullscreen(mojom::blink::FullscreenOptionsPtr) override; void AddReplicatedContentSecurityPolicies( WTF::Vector<network::mojom::blink::ContentSecurityPolicyHeaderPtr> headers) override;
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5 index 3ea132ac..880a7b7 100644 --- a/third_party/blink/renderer/core/frame/settings.json5 +++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -266,15 +266,6 @@ type: "int", }, - // Whether touch gestures should be "fuzzed" to nearest touch targets. - // It's expected that this is enabled everywhere by default, but it may be - // disabled for testing purposes as the algorithm is not yet perfect. - // crbug.com/304895 tracks removal once we're satisfied with the algorithm. - { - name: "touchAdjustmentEnabled", - initial: true, - }, - // Determines whether WebViewClient::didTapMultipleTargets will be used for // touch disambiguation. {
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc index 0046801d..cb6ee2d 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
@@ -368,13 +368,12 @@ doing_drag_and_drop_ = false; } -void WebFrameWidgetBase::StartDragging(network::mojom::ReferrerPolicy policy, - const WebDragData& data, +void WebFrameWidgetBase::StartDragging(const WebDragData& data, WebDragOperationsMask mask, const SkBitmap& drag_image, const gfx::Point& drag_image_offset) { doing_drag_and_drop_ = true; - Client()->StartDragging(policy, data, mask, drag_image, drag_image_offset); + Client()->StartDragging(data, mask, drag_image, drag_image_offset); } WebDragOperation WebFrameWidgetBase::DragTargetDragEnterOrOver(
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.h b/third_party/blink/renderer/core/frame/web_frame_widget_base.h index cfb2fd2..30ec693 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_base.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.h
@@ -11,7 +11,6 @@ #include "cc/input/layer_selection_bound.h" #include "cc/input/overscroll_behavior.h" #include "cc/trees/layer_tree_host.h" -#include "services/network/public/mojom/referrer_policy.mojom-blink-forward.h" #include "third_party/blink/public/common/input/web_coalesced_input_event.h" #include "third_party/blink/public/common/input/web_gesture_device.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom-blink.h" @@ -251,8 +250,7 @@ bool HandlingSelectRange() override; // Called when a drag-n-drop operation should begin. - void StartDragging(network::mojom::ReferrerPolicy, - const WebDragData&, + void StartDragging(const WebDragData&, WebDragOperationsMask, const SkBitmap& drag_image, const gfx::Point& drag_image_offset);
diff --git a/third_party/blink/renderer/core/fullscreen/BUILD.gn b/third_party/blink/renderer/core/fullscreen/BUILD.gn index 213571c..353358e 100644 --- a/third_party/blink/renderer/core/fullscreen/BUILD.gn +++ b/third_party/blink/renderer/core/fullscreen/BUILD.gn
@@ -12,6 +12,8 @@ "element_fullscreen.h", "fullscreen.cc", "fullscreen.h", + "fullscreen_request_type.cc", + "fullscreen_request_type.h", "scoped_allow_fullscreen.cc", "scoped_allow_fullscreen.h", ]
diff --git a/third_party/blink/renderer/core/fullscreen/element_fullscreen.cc b/third_party/blink/renderer/core/fullscreen/element_fullscreen.cc index ab226fca..2c8885fb 100644 --- a/third_party/blink/renderer/core/fullscreen/element_fullscreen.cc +++ b/third_party/blink/renderer/core/fullscreen/element_fullscreen.cc
@@ -17,7 +17,7 @@ const FullscreenOptions* options, ExceptionState& exception_state) { return Fullscreen::RequestFullscreen(element, options, - Fullscreen::RequestType::kUnprefixed, + FullscreenRequestType::kUnprefixed, script_state, &exception_state); } @@ -35,7 +35,7 @@ WebFeature::kPrefixedElementRequestFullscreenInShadow); } Fullscreen::RequestFullscreen(element, options, - Fullscreen::RequestType::kPrefixed); + FullscreenRequestType::kPrefixed); } } // namespace blink
diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen.cc b/third_party/blink/renderer/core/fullscreen/fullscreen.cc index e4a1f3567..667064dc 100644 --- a/third_party/blink/renderer/core/fullscreen/fullscreen.cc +++ b/third_party/blink/renderer/core/fullscreen/fullscreen.cc
@@ -65,7 +65,7 @@ void FullscreenElementChanged(Document& document, Element* old_element, Element* new_element, - Fullscreen::RequestType new_request_type) { + FullscreenRequestType new_request_type) { DCHECK_NE(old_element, new_element); document.GetStyleEngine().EnsureUAStyleForFullscreen(); @@ -87,11 +87,10 @@ new_element->PseudoStateChanged(CSSSelector::kPseudoFullScreen); new_element->PseudoStateChanged(CSSSelector::kPseudoFullscreen); - // OOPIF: For RequestType::PrefixedForCrossProcessDescendant, |new_element| + // OOPIF: For RequestType::kForCrossProcessDescendant, |new_element| // is the iframe element for the out-of-process frame that contains the // fullscreen element. Hence, it must match :-webkit-full-screen-ancestor. - if (new_request_type == - Fullscreen::RequestType::kPrefixedForCrossProcessDescendant) { + if (new_request_type & FullscreenRequestType::kForCrossProcessDescendant) { DCHECK(IsA<HTMLIFrameElement>(new_element)); new_element->SetContainsFullScreenElement(true); } @@ -125,7 +124,7 @@ } using ElementRequestTypeMap = - HeapHashMap<WeakMember<Element>, Fullscreen::RequestType>; + HeapHashMap<WeakMember<Element>, FullscreenRequestType>; ElementRequestTypeMap& FullscreenFlagMap() { DEFINE_STATIC_LOCAL(Persistent<ElementRequestTypeMap>, map, @@ -137,7 +136,7 @@ return FullscreenFlagMap().Contains(&element); } -void SetFullscreenFlag(Element& element, Fullscreen::RequestType request_type) { +void SetFullscreenFlag(Element& element, FullscreenRequestType request_type) { FullscreenFlagMap().insert(&element, request_type); } @@ -145,12 +144,12 @@ FullscreenFlagMap().erase(&element); } -Fullscreen::RequestType GetRequestType(Element& element) { +FullscreenRequestType GetRequestType(Element& element) { return FullscreenFlagMap().find(&element)->value; } // https://fullscreen.spec.whatwg.org/#fullscreen-an-element -void GoFullscreen(Element& element, Fullscreen::RequestType request_type) { +void GoFullscreen(Element& element, FullscreenRequestType request_type) { Document& document = element.GetDocument(); Element* old_element = Fullscreen::FullscreenElementFrom(document); @@ -185,9 +184,9 @@ Element* new_element = Fullscreen::FullscreenElementFrom(document); if (old_element != new_element) { - Fullscreen::RequestType new_request_type = + FullscreenRequestType new_request_type = new_element ? GetRequestType(*new_element) - : Fullscreen::RequestType::kUnprefixed; + : FullscreenRequestType::kUnprefixed; FullscreenElementChanged(document, old_element, new_element, new_request_type); } @@ -465,11 +464,11 @@ } const AtomicString& AdjustEventType(const AtomicString& type, - Fullscreen::RequestType request_type) { + FullscreenRequestType request_type) { DCHECK(type == event_type_names::kFullscreenchange || type == event_type_names::kFullscreenerror); - if (request_type == Fullscreen::RequestType::kUnprefixed) + if (!(request_type & FullscreenRequestType::kPrefixed)) return type; return type == event_type_names::kFullscreenchange ? event_type_names::kWebkitfullscreenchange @@ -479,7 +478,7 @@ void EnqueueEvent(const AtomicString& type, Element& element, Document& document, - Fullscreen::RequestType request_type) { + FullscreenRequestType request_type) { const AtomicString& adjusted_type = AdjustEventType(type, request_type); document.EnqueueAnimationFrameTask(WTF::Bind(FireEvent, adjusted_type, WrapWeakPersistent(&element), @@ -557,12 +556,12 @@ // API is enabled. https://crbug.com/383813 FullscreenOptions* options = FullscreenOptions::Create(); options->setNavigationUI("hide"); - RequestFullscreen(pending, options, RequestType::kPrefixed); + RequestFullscreen(pending, options, FullscreenRequestType::kPrefixed); } ScriptPromise Fullscreen::RequestFullscreen(Element& pending, const FullscreenOptions* options, - RequestType request_type, + FullscreenRequestType request_type, ScriptState* script_state, ExceptionState* exception_state) { RequestFullscreenScope scope; @@ -587,12 +586,12 @@ if (script_state) { // We should only be creating promises for unprefixed variants. - DCHECK_EQ(Fullscreen::RequestType::kUnprefixed, request_type); + DCHECK(!(request_type & FullscreenRequestType::kPrefixed)); resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); } bool for_cross_process_descendant = - request_type == RequestType::kPrefixedForCrossProcessDescendant; + request_type & FullscreenRequestType::kForCrossProcessDescendant; // Use counters only need to be incremented in the process of the actual // fullscreen element. @@ -631,8 +630,7 @@ From(window).pending_requests_.push_back( MakeGarbageCollected<PendingRequest>(&pending, request_type, resolver)); LocalFrame& frame = *window.GetFrame(); - frame.GetChromeClient().EnterFullscreen(frame, options, - for_cross_process_descendant); + frame.GetChromeClient().EnterFullscreen(frame, options, request_type); // After the first fullscreen request, the user activation should be // consumed, and the following fullscreen requests should receive an error. @@ -679,7 +677,7 @@ void Fullscreen::ContinueRequestFullscreen(Document& document, Element& pending, - RequestType request_type, + FullscreenRequestType request_type, ScriptPromiseResolver* resolver, bool error) { DCHECK(document.IsActive()); @@ -843,7 +841,7 @@ // 7. If |doc|'s fullscreen element is not connected. Element* element = FullscreenElementFrom(doc); if (!element->isConnected()) { - RequestType request_type = GetRequestType(*element); + FullscreenRequestType request_type = GetRequestType(*element); // 7.1. Append (fullscreenchange, |doc|'s fullscreen element) to // |doc|'s list of pending fullscreen events. @@ -941,7 +939,7 @@ for (Document* exit_doc : exit_docs) { Element* exit_element = FullscreenElementFrom(*exit_doc); DCHECK(exit_element); - RequestType request_type = GetRequestType(*exit_element); + FullscreenRequestType request_type = GetRequestType(*exit_element); // 12.1. Append (fullscreenchange, |exitDoc|'s fullscreen element) to // |exitDoc|'s list of pending fullscreen events. @@ -960,7 +958,7 @@ for (Document* descendant_doc : descendant_docs) { Element* descendant_element = FullscreenElementFrom(*descendant_doc); DCHECK(descendant_element); - RequestType request_type = GetRequestType(*descendant_element); + FullscreenRequestType request_type = GetRequestType(*descendant_element); // 13.1. Append (fullscreenchange, |descendantDoc|'s fullscreen element) to // |descendantDoc|'s list of pending fullscreen events. @@ -1028,7 +1026,7 @@ } Fullscreen::PendingRequest::PendingRequest(Element* element, - RequestType type, + FullscreenRequestType type, ScriptPromiseResolver* resolver) : element_(element), type_(type), resolver_(resolver) {}
diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen.h b/third_party/blink/renderer/core/fullscreen/fullscreen.h index dd96602..0627ccc 100644 --- a/third_party/blink/renderer/core/fullscreen/fullscreen.h +++ b/third_party/blink/renderer/core/fullscreen/fullscreen.h
@@ -36,6 +36,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/fullscreen/fullscreen_request_type.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/supplementable.h" #include "third_party/blink/renderer/platform/wtf/deque.h" @@ -65,22 +66,11 @@ static bool IsFullscreenElement(const Element&); static bool IsInFullscreenElementStack(const Element&); - enum class RequestType { - // Element.requestFullscreen() - kUnprefixed, - // Element.webkitRequestFullscreen()/webkitRequestFullScreen() and - // HTMLVideoElement.webkitEnterFullscreen()/webkitEnterFullScreen() - kPrefixed, - // For WebRemoteFrameImpl to notify that a cross-process descendant frame - // has requested and is about to enter fullscreen. - kPrefixedForCrossProcessDescendant, - }; - static void RequestFullscreen(Element&); static ScriptPromise RequestFullscreen( Element&, const FullscreenOptions*, - RequestType, + FullscreenRequestType, ScriptState* state = nullptr, ExceptionState* exception_state = nullptr); @@ -111,7 +101,7 @@ static void ContinueRequestFullscreen(Document&, Element&, - RequestType, + FullscreenRequestType, ScriptPromiseResolver* resolver, bool error); @@ -121,25 +111,25 @@ void FullscreenElementChanged(Element* old_element, Element* new_element, - RequestType new_request_type); + FullscreenRequestType new_request_type); // Stores the pending request, promise and the type for executing // the asynchronous portion of the request. class PendingRequest : public GarbageCollected<PendingRequest> { public: PendingRequest(Element* element, - RequestType type, + FullscreenRequestType type, ScriptPromiseResolver* resolver); virtual ~PendingRequest(); virtual void Trace(Visitor* visitor) const; Element* element() { return element_; } - RequestType type() { return type_; } + FullscreenRequestType type() { return type_; } ScriptPromiseResolver* resolver() { return resolver_; } private: Member<Element> element_; - RequestType type_; + FullscreenRequestType type_; Member<ScriptPromiseResolver> resolver_; DISALLOW_COPY_AND_ASSIGN(PendingRequest);
diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen_request_type.cc b/third_party/blink/renderer/core/fullscreen/fullscreen_request_type.cc new file mode 100644 index 0000000..9fbc0c2 --- /dev/null +++ b/third_party/blink/renderer/core/fullscreen/fullscreen_request_type.cc
@@ -0,0 +1,24 @@ +// 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/renderer/core/fullscreen/fullscreen_request_type.h" + +#if DCHECK_IS_ON() +#include <sstream> +#endif + +namespace blink { + +#if DCHECK_IS_ON() +std::string FullscreenRequestTypeToDebugString(FullscreenRequestType req) { + std::stringstream result; + result << (req & FullscreenRequestType::kPrefixed ? "Prefixed" + : "Unprefixed"); + if (req & FullscreenRequestType::kForCrossProcessDescendant) + result << "|ForCrossProcessDescendant"; + return result.str(); +} +#endif + +} // namespace blink
diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen_request_type.h b/third_party/blink/renderer/core/fullscreen/fullscreen_request_type.h new file mode 100644 index 0000000..a3269a8 --- /dev/null +++ b/third_party/blink/renderer/core/fullscreen/fullscreen_request_type.h
@@ -0,0 +1,57 @@ +// 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_RENDERER_CORE_FULLSCREEN_FULLSCREEN_REQUEST_TYPE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FULLSCREEN_FULLSCREEN_REQUEST_TYPE_H_ + +#include "base/check.h" + +#if DCHECK_IS_ON() +#include <string> +#endif + +namespace blink { + +// This enum class represents Implementation-internal details for the fullscreen +// request, these are in addition to API options from fullscreen_options.idl +// that are passed separately. +// +// The integer values are powers of two for use as a flag bitmap. The class +// provides minimal operators for combining flags and checking if a specific +// flag is set. +enum class FullscreenRequestType { + // No bits set, equivalent to unprefixed with no other properties + kNull = 0, + + // True for Element.requestFullscreen(), false for + // Element.webkitRequestFullscreen()/webkitRequestFullScreen() and + // HTMLVideoElement.webkitEnterFullscreen()/webkitEnterFullScreen() + kPrefixed = 1, + + // For WebRemoteFrameImpl to notify that a cross-process descendant frame + // has requested and is about to enter fullscreen. + kForCrossProcessDescendant = 2, + + // Explicit name for "no options" for backwards compatibility and convenience + kUnprefixed = kNull, +}; + +inline FullscreenRequestType operator|(FullscreenRequestType lhs, + FullscreenRequestType rhs) { + return static_cast<FullscreenRequestType>(static_cast<int>(lhs) | + static_cast<int>(rhs)); +} + +// Returns true if lhs and rhs have at least one flag bit in common. +inline bool operator&(FullscreenRequestType lhs, FullscreenRequestType rhs) { + return static_cast<int>(lhs) & static_cast<int>(rhs); +} + +#if DCHECK_IS_ON() +std::string FullscreenRequestTypeToDebugString(FullscreenRequestType req); +#endif + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FULLSCREEN_FULLSCREEN_REQUEST_TYPE_H_
diff --git a/third_party/blink/renderer/core/html/link_web_bundle.cc b/third_party/blink/renderer/core/html/link_web_bundle.cc index 8bc4a33..c501451 100644 --- a/third_party/blink/renderer/core/html/link_web_bundle.cc +++ b/third_party/blink/renderer/core/html/link_web_bundle.cc
@@ -6,12 +6,14 @@ #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/renderer/core/html/html_link_element.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/loader/threadable_loader.h" #include "third_party/blink/renderer/core/loader/threadable_loader_client.h" #include "third_party/blink/renderer/platform/loader/cors/cors.h" #include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader.h" +#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" namespace blink { @@ -68,9 +70,10 @@ void DidStartLoadingResponseBody(BytesConsumer& consumer) override { DCHECK(pending_factory_receiver_); CreateWebBundleSubresourceLoaderFactory( - std::move(pending_factory_receiver_), consumer.DrainAsDataPipe()); - // TODO(crbug.com/1082020): Set |failed_| to true on metadata parse error, - // so that "error" event is dispatched. + std::move(pending_factory_receiver_), consumer.DrainAsDataPipe(), + ConvertToBaseRepeatingCallback( + CrossThreadBindRepeating(&WebBundleLoader::OnWebBundleError, + WrapCrossThreadWeakPersistent(this)))); } void DidFinishLoading(uint64_t) override { link_web_bundle_->NotifyLoaded(); } @@ -87,12 +90,19 @@ // |pending_factory_receiver_| are processed (and fail). CreateWebBundleSubresourceLoaderFactory( std::move(pending_factory_receiver_), - mojo::ScopedDataPipeConsumerHandle()); + mojo::ScopedDataPipeConsumerHandle(), base::DoNothing()); } failed_ = true; link_web_bundle_->NotifyLoaded(); } + void OnWebBundleError(WebBundleErrorType type, const String& message) { + // TODO(crbug.com/1082020): Dispatch "error" event on metadata parse error. + // Simply setting |failed_| here does not work because DidFinishLoading() + // may already be called. + link_web_bundle_->OnWebBundleError(url_.ElidedString() + ": " + message); + } + Member<LinkWebBundle> link_web_bundle_; Member<ThreadableLoader> loader_; mojo::Remote<network::mojom::blink::URLLoaderFactory> loader_factory_; @@ -116,6 +126,17 @@ owner_->ScheduleEvent(); } +void LinkWebBundle::OnWebBundleError(const String& message) { + if (!owner_) + return; + ExecutionContext* context = owner_->GetDocument().GetExecutionContext(); + if (!context) + return; + context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kOther, + mojom::blink::ConsoleMessageLevel::kWarning, message)); +} + void LinkWebBundle::Process() { if (!owner_ || !owner_->GetDocument().GetFrame()) return;
diff --git a/third_party/blink/renderer/core/html/link_web_bundle.h b/third_party/blink/renderer/core/html/link_web_bundle.h index 1040a52..3921af9 100644 --- a/third_party/blink/renderer/core/html/link_web_bundle.h +++ b/third_party/blink/renderer/core/html/link_web_bundle.h
@@ -31,6 +31,7 @@ void Trace(Visitor* visitor) const override; void NotifyLoaded(); + void OnWebBundleError(const String& message); // LinkResource overrides: void Process() override;
diff --git a/third_party/blink/renderer/core/html/media/html_video_element.cc b/third_party/blink/renderer/core/html/media/html_video_element.cc index 6ff240e..ef466068 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element.cc +++ b/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -463,7 +463,7 @@ FullscreenOptions* options = FullscreenOptions::Create(); options->setNavigationUI("hide"); Fullscreen::RequestFullscreen(*this, options, - Fullscreen::RequestType::kPrefixed); + FullscreenRequestType::kPrefixed); } }
diff --git a/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc b/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc index 011db7b..38aa754 100644 --- a/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc +++ b/third_party/blink/renderer/core/html/media/html_video_element_persistent_test.cc
@@ -25,7 +25,7 @@ MOCK_METHOD3(EnterFullscreen, void(LocalFrame&, const FullscreenOptions*, - bool for_cross_process_descendant)); + FullscreenRequestType)); MOCK_METHOD1(ExitFullscreen, void(LocalFrame&)); };
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc index 3d6f721..484d423a 100644 --- a/third_party/blink/renderer/core/input/event_handler.cc +++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -1632,10 +1632,6 @@ bool EventHandler::ShouldApplyTouchAdjustment( const WebGestureEvent& event) const { - if (frame_->GetSettings() && - !frame_->GetSettings()->GetTouchAdjustmentEnabled()) - return false; - if (event.primary_pointer_type == WebPointerProperties::PointerType::kPen) return false;
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.cc b/third_party/blink/renderer/core/input/pointer_event_manager.cc index fd4d7c55..67884d3 100644 --- a/third_party/blink/renderer/core/input/pointer_event_manager.cc +++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -333,10 +333,6 @@ bool PointerEventManager::ShouldAdjustPointerEvent( const WebPointerEvent& pointer_event) const { - if (frame_->GetSettings() && - !frame_->GetSettings()->GetTouchAdjustmentEnabled()) - return false; - return pointer_event.pointer_type == WebPointerProperties::PointerType::kTouch && pointer_event.GetType() == WebInputEvent::Type::kPointerDown &&
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc index e188eeb..2bdfd515 100644 --- a/third_party/blink/renderer/core/layout/layout_block.cc +++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -1023,7 +1023,8 @@ if (!StyleRef().HasPseudoElementStyle(kPseudoIdFirstLine)) return; - const auto* first_line_style = FirstLineStyleWithoutFallback(); + const auto* first_line_style = + StyleRef().GetCachedPseudoElementStyle(kPseudoIdFirstLine); if (!first_line_style) return; if (auto* first_line_container = NearestInnerBlockWithFirstLine()) {
diff --git a/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/third_party/blink/renderer/core/layout/layout_box_model_object.cc index 61e5c1ef..2d0bfbfb 100644 --- a/third_party/blink/renderer/core/layout/layout_box_model_object.cc +++ b/third_party/blink/renderer/core/layout/layout_box_model_object.cc
@@ -126,6 +126,11 @@ return kBackgroundPaintInScrollingContents; } + // TODO(crbug.com/1113269): Temporarily disable composited scrolling for + // clipped layers. + if (HasClip()) + return kBackgroundPaintInGraphicsLayer; + // Inset box shadow is painted in the scrolling area above the background, and // it doesn't scroll, so the background can only be painted in the main layer. if (HasInsetBoxShadow(StyleRef()))
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_content.cc b/third_party/blink/renderer/core/layout/layout_embedded_content.cc index c1dfd182..4506ffca 100644 --- a/third_party/blink/renderer/core/layout/layout_embedded_content.cc +++ b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
@@ -182,13 +182,13 @@ if (local_frame_view->ShouldThrottleRendering() || !local_frame_view->GetFrame().GetDocument() || local_frame_view->GetFrame().GetDocument()->Lifecycle().GetState() < - DocumentLifecycle::kCompositingAssignmentsClean) { + DocumentLifecycle::kPrePaintClean) { return NodeAtPointOverEmbeddedContentView(result, hit_test_location, accumulated_offset, action); } DCHECK_GE(GetDocument().Lifecycle().GetState(), - DocumentLifecycle::kCompositingAssignmentsClean); + DocumentLifecycle::kPrePaintClean); if (action == kHitTestForeground) { auto* child_layout_view = local_frame_view->GetLayoutView();
diff --git a/third_party/blink/renderer/core/layout/layout_grid.cc b/third_party/blink/renderer/core/layout/layout_grid.cc index 18536f4..bc21c55 100644 --- a/third_party/blink/renderer/core/layout/layout_grid.cc +++ b/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -884,10 +884,10 @@ if (grid.HasGridItems()) { DCHECK_GE(grid.NumTracks(kForRows), GridPositionsResolver::ExplicitGridRowCount( - *Style(), grid.AutoRepeatTracks(kForRows))); + StyleRef(), grid.AutoRepeatTracks(kForRows))); DCHECK_GE(grid.NumTracks(kForColumns), GridPositionsResolver::ExplicitGridColumnCount( - *Style(), grid.AutoRepeatTracks(kForColumns))); + StyleRef(), grid.AutoRepeatTracks(kForColumns))); } #endif @@ -972,9 +972,9 @@ size_t auto_repeat_rows = grid.AutoRepeatTracks(kForRows); size_t auto_repeat_columns = grid.AutoRepeatTracks(kForColumns); size_t maximum_row_index = - GridPositionsResolver::ExplicitGridRowCount(*Style(), auto_repeat_rows); + GridPositionsResolver::ExplicitGridRowCount(StyleRef(), auto_repeat_rows); size_t maximum_column_index = GridPositionsResolver::ExplicitGridColumnCount( - *Style(), auto_repeat_columns); + StyleRef(), auto_repeat_columns); for (LayoutBox* child = FirstInFlowChildBox(); child; child = child->NextInFlowSiblingBox()) { @@ -984,10 +984,10 @@ // build it. GridSpan row_positions = GridPositionsResolver::ResolveGridPositionsFromStyle( - *Style(), *child, kForRows, auto_repeat_rows); + StyleRef(), child->StyleRef(), kForRows, auto_repeat_rows); GridSpan column_positions = GridPositionsResolver::ResolveGridPositionsFromStyle( - *Style(), *child, kForColumns, auto_repeat_columns); + StyleRef(), child->StyleRef(), kForColumns, auto_repeat_columns); grid.SetGridItemArea(*child, GridArea(row_positions, column_positions)); // |positions| is 0 if we need to run the auto-placement algorithm. @@ -999,8 +999,8 @@ } else { // Grow the grid for items with a definite row span, getting the largest // such span. - size_t span_size = - GridPositionsResolver::SpanSizeForAutoPlacedItem(*child, kForRows); + size_t span_size = GridPositionsResolver::SpanSizeForAutoPlacedItem( + child->StyleRef(), kForRows); maximum_row_index = std::max(maximum_row_index, span_size); } @@ -1012,8 +1012,8 @@ } else { // Grow the grid for items with a definite column span, getting the // largest such span. - size_t span_size = - GridPositionsResolver::SpanSizeForAutoPlacedItem(*child, kForColumns); + size_t span_size = GridPositionsResolver::SpanSizeForAutoPlacedItem( + child->StyleRef(), kForColumns); maximum_column_index = std::max(maximum_column_index, span_size); } } @@ -1033,7 +1033,7 @@ specified_direction == kForColumns ? kForRows : kForColumns; const size_t end_of_cross_direction = grid.NumTracks(cross_direction); size_t cross_direction_span_size = - GridPositionsResolver::SpanSizeForAutoPlacedItem(grid_item, + GridPositionsResolver::SpanSizeForAutoPlacedItem(grid_item.StyleRef(), cross_direction); GridSpan cross_direction_positions = GridSpan::TranslatedDefiniteGridSpan( end_of_cross_direction, @@ -1068,7 +1068,7 @@ .IsTranslatedDefinite()); size_t minor_axis_span_size = GridPositionsResolver::SpanSizeForAutoPlacedItem( - *auto_grid_item, AutoPlacementMinorAxisDirection()); + auto_grid_item->StyleRef(), AutoPlacementMinorAxisDirection()); unsigned major_axis_initial_position = major_axis_positions.StartLine(); auto iterator = grid.CreateIterator( @@ -1117,7 +1117,7 @@ .IsTranslatedDefinite()); size_t major_axis_span_size = GridPositionsResolver::SpanSizeForAutoPlacedItem( - grid_item, AutoPlacementMajorAxisDirection()); + grid_item.StyleRef(), AutoPlacementMajorAxisDirection()); const size_t end_of_major_axis = grid.NumTracks(AutoPlacementMajorAxisDirection()); @@ -1153,7 +1153,7 @@ } else { size_t minor_axis_span_size = GridPositionsResolver::SpanSizeForAutoPlacedItem( - grid_item, AutoPlacementMinorAxisDirection()); + grid_item.StyleRef(), AutoPlacementMinorAxisDirection()); for (size_t major_axis_index = major_axis_auto_placement_cursor; major_axis_index < end_of_major_axis; ++major_axis_index) { @@ -2050,7 +2050,8 @@ DCHECK(child.IsOutOfFlowPositioned()); bool is_row_axis = direction == kForColumns; GridSpan span = GridPositionsResolver::ResolveGridPositionsFromStyle( - *Style(), child, direction, AutoRepeatCountForDirection(direction)); + StyleRef(), child.StyleRef(), direction, + AutoRepeatCountForDirection(direction)); if (span.IsIndefinite()) return is_row_axis ? ClientLogicalWidth() : ClientLogicalHeight();
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 5e7b81f..005c92f 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -3022,7 +3022,8 @@ return true; AncestorSkipInfo skip_info(ancestor); - PropertyTreeState container_properties = PropertyTreeState::Uninitialized(); + PropertyTreeStateOrAlias container_properties = + PropertyTreeState::Uninitialized(); const LayoutObject* property_container = GetPropertyContainer(&skip_info, &container_properties); if (!property_container)
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h index 108ff94..d3d5a11 100644 --- a/third_party/blink/renderer/core/layout/layout_object.h +++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1714,11 +1714,10 @@ // If TraverseDocumentBoundaries is specified, the result will be in the // space of the local root frame. // Otherwise, the result will be in the space of the containing frame. - // This method supports kUseGeometryMapper. + // This method supports kUseGeometryMapperMode. PhysicalRect LocalToAncestorRect(const PhysicalRect& rect, const LayoutBoxModelObject* ancestor, MapCoordinatesFlags mode = 0) const; - // This method supports kUseGeometryMapper. FloatQuad LocalRectToAncestorQuad(const PhysicalRect& rect, const LayoutBoxModelObject* ancestor, MapCoordinatesFlags mode = 0) const { @@ -1756,7 +1755,7 @@ // Shorthands of the above LocalToAncestor* and AncestorToLocal* functions, // with nullptr as the ancestor. See the above functions for the meaning of // "absolute" coordinates. - // This method supports kUseGeometryMapper. + // This method supports kUseGeometryMapperMode. PhysicalRect LocalToAbsoluteRect(const PhysicalRect& rect, MapCoordinatesFlags mode = 0) const { return LocalToAncestorRect(rect, nullptr, mode);
diff --git a/third_party/blink/renderer/core/layout/layout_object_test.cc b/third_party/blink/renderer/core/layout/layout_object_test.cc index 4592c68..a1cbc41b 100644 --- a/third_party/blink/renderer/core/layout/layout_object_test.cc +++ b/third_party/blink/renderer/core/layout/layout_object_test.cc
@@ -8,9 +8,11 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/core/css/style_sheet_contents.h" #include "third_party/blink/renderer/core/frame/event_handler_registry.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" +#include "third_party/blink/renderer/core/html/html_style_element.h" #include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/svg/svg_g_element.h" @@ -1229,6 +1231,53 @@ UpdateAllLifecyclePhasesForTest(); } +TEST_F(LayoutObjectSimTest, FirstLineBackgroundImageDirtyStyleCrash) { + SimRequest main_resource("https://example.com/test.html", "text/html"); + + LoadURL("https://example.com/test.html"); + main_resource.Complete(R"HTML( + <style id="style"> + #target { display: list-item; } + div::first-line { + background-image: url(data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==); + } + </style> + <div id="target">Text</div> + )HTML"); + + GetDocument().View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest); + + CSSStyleSheet* sheet = + To<HTMLStyleElement>(GetDocument().getElementById("style"))->sheet(); + { + // "Mutate" the rules to clear the StyleSheetContents RuleSet member. + CSSStyleSheet::RuleMutationScope scope(sheet); + } + EXPECT_FALSE(sheet->Contents()->HasRuleSet()); + + auto* target = GetDocument().getElementById("target"); + auto* target_object = target->GetLayoutObject(); + auto* image_resource_content = target_object->FirstLineStyleRef() + .BackgroundLayers() + .GetImage() + ->CachedImage(); + auto* image = image_resource_content->GetImage(); + auto* image_observer = static_cast<ImageObserver*>(image_resource_content); + + // LayoutBlock::ImageChanged() will be triggered which makes us look up the + // ::first-line style before marking for paint invalidation. We should not try + // to compute style if it doesn't exist. The first invocation will mark for + // paint invalidation which will clear the cached ::first-line styles. + image_observer->Changed(image); + EXPECT_TRUE(target_object->ShouldDoFullPaintInvalidation()); + + // For the second invocation, the ::first-line styles is null. If we try to + // compute the styles here, we will crash since the RuleSet is null and we + // need an active style update. + image_observer->Changed(image); + EXPECT_TRUE(target_object->ShouldDoFullPaintInvalidation()); +} + TEST_F(LayoutObjectTest, NeedsLayoutOverflowRecalc) { if (!RuntimeEnabledFeatures::LayoutNGEnabled()) return;
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc index fcfd3bd..24ef2130 100644 --- a/third_party/blink/renderer/core/layout/layout_view.cc +++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -137,9 +137,15 @@ // Note that if an iframe has its render pipeline throttled, it will not // update layout here, and it will also not propagate the hit test into the // iframe's inner document. - if (!GetFrameView()->UpdateAllLifecyclePhasesExceptPaint( - DocumentUpdateReason::kHitTest)) - return false; + if (RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) { + if (!GetFrameView()->UpdateLifecycleToPrePaintClean( + DocumentUpdateReason::kHitTest)) + return false; + } else { + if (!GetFrameView()->UpdateAllLifecyclePhasesExceptPaint( + DocumentUpdateReason::kHitTest)) + return false; + } HitTestLatencyRecorder hit_test_latency_recorder( result.GetHitTestRequest().AllowsChildFrameContent()); return HitTestNoLifecycleUpdate(location, result);
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc index c7ebcd03..612c242 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.cc
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_child_iterator.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h" #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" +#include "third_party/blink/renderer/core/style/grid_positions_resolver.h" namespace blink { @@ -29,6 +30,7 @@ switch (state_) { case GridLayoutAlgorithmState::kMeasuringItems: { SetSpecifiedTracks(); + DetermineExplicitTrackStarts(); ConstructAndAppendGridItems(); block_column_track_collection_.FinalizeRanges(); block_row_track_collection_.FinalizeRanges(); @@ -92,7 +94,8 @@ for (NGBlockNode child = iterator.NextChild(); child; child = iterator.NextChild()) { ConstructAndAppendGridItem(child); - EnsureTrackCoverageForGridItem(child); + EnsureTrackCoverageForGridItem(child, kForRows); + EnsureTrackCoverageForGridItem(child, kForColumns); } } @@ -165,36 +168,62 @@ block_column_track_collection_.SetSpecifiedTracks( &grid_style.GridTemplateColumns().NGTrackList(), &grid_style.GridAutoColumns().NGTrackList(), - automatic_column_repetitions_for_testing); + automatic_column_repetitions_); block_row_track_collection_.SetSpecifiedTracks( &grid_style.GridTemplateRows().NGTrackList(), - &grid_style.GridAutoRows().NGTrackList(), - automatic_row_repetitions_for_testing); + &grid_style.GridAutoRows().NGTrackList(), automatic_row_repetitions_); } void NGGridLayoutAlgorithm::EnsureTrackCoverageForGridItem( - const NGBlockNode& grid_item) { + const NGBlockNode& grid_item, + GridTrackSizingDirection grid_direction) { const ComputedStyle& item_style = grid_item.Style(); - EnsureTrackCoverageForGridPositions(item_style.GridColumnStart(), - item_style.GridColumnEnd(), - block_column_track_collection_); - EnsureTrackCoverageForGridPositions(item_style.GridRowStart(), - item_style.GridRowEnd(), - block_row_track_collection_); + GridSpan span = GridPositionsResolver::ResolveGridPositionsFromStyle( + Style(), item_style, grid_direction, + AutoRepeatCountForDirection(grid_direction)); + // TODO(janewman): indefinite positions should be resolved with the auto + // placement algorithm. + if (span.IsIndefinite()) + return; + + wtf_size_t explicit_start = (grid_direction == kForColumns) + ? explicit_column_start_ + : explicit_row_start_; + wtf_size_t start = span.UntranslatedStartLine() + explicit_start; + wtf_size_t end = span.UntranslatedEndLine() + explicit_start; + + switch (grid_direction) { + case kForColumns: + block_column_track_collection_.EnsureTrackCoverage(start, end - start); + break; + case kForRows: + block_row_track_collection_.EnsureTrackCoverage(start, end - start); + break; + } } -void NGGridLayoutAlgorithm::EnsureTrackCoverageForGridPositions( - const GridPosition& start_position, - const GridPosition& end_position, - NGGridBlockTrackCollection& track_collection) { - // For now, we only support adding tracks if they were specified. - // TODO(janewman): Implement support for position types other than Explicit. - if (start_position.GetType() == GridPositionType::kExplicitPosition && - end_position.GetType() == GridPositionType::kExplicitPosition) { - track_collection.EnsureTrackCoverage( - start_position.IntegerPosition(), - end_position.IntegerPosition() - start_position.IntegerPosition() + 1); +void NGGridLayoutAlgorithm::DetermineExplicitTrackStarts() { + DCHECK_EQ(0u, explicit_column_start_); + DCHECK_EQ(0u, explicit_row_start_); + + NGGridChildIterator iterator(Node()); + for (NGBlockNode child = iterator.NextChild(); child; + child = iterator.NextChild()) { + GridSpan column_span = GridPositionsResolver::ResolveGridPositionsFromStyle( + Style(), child.Style(), kForColumns, + AutoRepeatCountForDirection(kForColumns)); + GridSpan row_span = GridPositionsResolver::ResolveGridPositionsFromStyle( + Style(), child.Style(), kForRows, + AutoRepeatCountForDirection(kForRows)); + if (!column_span.IsIndefinite()) { + explicit_column_start_ = std::max<int>( + explicit_column_start_, -column_span.UntranslatedStartLine()); + } + if (!row_span.IsIndefinite()) { + explicit_row_start_ = + std::max<int>(explicit_row_start_, -row_span.UntranslatedStartLine()); + } } } @@ -252,8 +281,13 @@ void NGGridLayoutAlgorithm::SetAutomaticTrackRepetitionsForTesting( wtf_size_t auto_column, wtf_size_t auto_row) { - automatic_column_repetitions_for_testing = auto_column; - automatic_row_repetitions_for_testing = auto_row; + automatic_column_repetitions_ = auto_column; + automatic_row_repetitions_ = auto_row; +} +wtf_size_t NGGridLayoutAlgorithm::AutoRepeatCountForDirection( + GridTrackSizingDirection direction) const { + return (direction == kForColumns) ? automatic_column_repetitions_ + : automatic_row_repetitions_; } } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h index 16cc742c..b81802f 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm.h
@@ -55,12 +55,10 @@ // Sets the specified tracks for row and column track lists. void SetSpecifiedTracks(); // Ensures a range boundary will exist on the start and end of the grid item. - void EnsureTrackCoverageForGridItem(const NGBlockNode& grid_item); - // Helper for EnsureTrackCoverageForGridItem. - static void EnsureTrackCoverageForGridPositions( - const GridPosition& start_position, - const GridPosition& end_position, - NGGridBlockTrackCollection& track_list); + void EnsureTrackCoverageForGridItem(const NGBlockNode& grid_item, + GridTrackSizingDirection grid_direction); + // Determines the explicit column and row track starts. + void DetermineExplicitTrackStarts(); // Calculates from the min and max track sizing functions the used track size. void ComputeUsedTrackSizes(GridTrackSizingDirection track_direction); @@ -68,6 +66,8 @@ // Allows a test to set the value for automatic track repetition. void SetAutomaticTrackRepetitionsForTesting(wtf_size_t auto_column, wtf_size_t auto_row); + wtf_size_t AutoRepeatCountForDirection( + GridTrackSizingDirection direction) const; Vector<GridItemData> items_; GridLayoutAlgorithmState state_; @@ -79,9 +79,12 @@ NGGridLayoutAlgorithmTrackCollection algorithm_column_track_collection_; NGGridLayoutAlgorithmTrackCollection algorithm_row_track_collection_; - wtf_size_t automatic_column_repetitions_for_testing = + wtf_size_t explicit_column_start_ = 0; + wtf_size_t explicit_row_start_ = 0; + + wtf_size_t automatic_column_repetitions_ = NGGridBlockTrackCollection::kInvalidRangeIndex; - wtf_size_t automatic_row_repetitions_for_testing = + wtf_size_t automatic_row_repetitions_ = NGGridBlockTrackCollection::kInvalidRangeIndex; };
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc index 32e10187..36240d5 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_layout_algorithm_test.cc
@@ -8,7 +8,18 @@ #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" namespace blink { - +namespace { +#define EXPECT_RANGE(expected_start, expected_count, iterator) \ + EXPECT_EQ(expected_count, iterator.RepeatCount()); \ + EXPECT_EQ(expected_start, iterator.RangeTrackStart()); \ + EXPECT_EQ(expected_start + expected_count - 1, iterator.RangeTrackEnd()); \ + EXPECT_FALSE(iterator.IsRangeCollapsed()); +#define EXPECT_COLLAPSED_RANGE(expected_start, expected_count, iterator) \ + EXPECT_EQ(expected_start, iterator.RangeTrackStart()); \ + EXPECT_EQ(expected_count, iterator.RepeatCount()); \ + EXPECT_EQ(expected_start + expected_count - 1, iterator.RangeTrackEnd()); \ + EXPECT_TRUE(iterator.IsRangeCollapsed()); +} // namespace class NGGridLayoutAlgorithmTest : public NGBaseLayoutAlgorithmTest, private ScopedLayoutNGGridForTest, @@ -315,16 +326,12 @@ NGGridTrackCollectionBase::RangeRepeatIterator row_iterator( &algorithm.RowTrackCollection(), 0u); - EXPECT_EQ(1u, row_iterator.RangeTrackStart()); - EXPECT_EQ(1000u, row_iterator.RangeTrackEnd()); - EXPECT_EQ(1000u, row_iterator.RepeatCount()); + EXPECT_RANGE(0u, 1000u, row_iterator); EXPECT_FALSE(row_iterator.MoveToNextRange()); NGGridTrackCollectionBase::RangeRepeatIterator column_iterator( &algorithm.ColumnTrackCollection(), 0u); - EXPECT_EQ(1u, column_iterator.RangeTrackStart()); - EXPECT_EQ(8u, column_iterator.RangeTrackEnd()); - EXPECT_EQ(8u, column_iterator.RepeatCount()); + EXPECT_RANGE(0u, 8u, column_iterator); EXPECT_FALSE(column_iterator.MoveToNextRange()); } @@ -359,35 +366,25 @@ NGGridLayoutAlgorithm algorithm({node, fragment_geometry, space}); EXPECT_EQ(GridItemCount(algorithm), 0U); - SetAutoTrackRepeat(algorithm, 5, 5); + SetAutoTrackRepeat(algorithm, 3, 3); algorithm.Layout(); EXPECT_EQ(GridItemCount(algorithm), 4U); NGGridTrackCollectionBase::RangeRepeatIterator row_iterator( &algorithm.RowTrackCollection(), 0u); - EXPECT_EQ(1u, row_iterator.RangeTrackStart()); - EXPECT_EQ(20u, row_iterator.RangeTrackEnd()); - EXPECT_EQ(20u, row_iterator.RepeatCount()); + EXPECT_RANGE(0u, 20u, row_iterator); EXPECT_FALSE(row_iterator.MoveToNextRange()); NGGridTrackCollectionBase::RangeRepeatIterator column_iterator( &algorithm.ColumnTrackCollection(), 0u); - EXPECT_EQ(1u, column_iterator.RangeTrackStart()); - EXPECT_EQ(1u, column_iterator.RangeTrackEnd()); - EXPECT_EQ(1u, column_iterator.RepeatCount()); - EXPECT_FALSE(column_iterator.IsRangeCollapsed()); + + EXPECT_RANGE(0u, 1u, column_iterator); EXPECT_TRUE(column_iterator.MoveToNextRange()); - EXPECT_EQ(2u, column_iterator.RangeTrackStart()); - EXPECT_EQ(6u, column_iterator.RangeTrackEnd()); - EXPECT_EQ(5u, column_iterator.RepeatCount()); - EXPECT_TRUE(column_iterator.IsRangeCollapsed()); + EXPECT_COLLAPSED_RANGE(1u, 3u, column_iterator); EXPECT_TRUE(column_iterator.MoveToNextRange()); - EXPECT_EQ(7u, column_iterator.RangeTrackStart()); - EXPECT_EQ(9u, column_iterator.RangeTrackEnd()); - EXPECT_EQ(3u, column_iterator.RepeatCount()); - EXPECT_FALSE(column_iterator.IsRangeCollapsed()); + EXPECT_RANGE(4u, 3u, column_iterator); EXPECT_FALSE(column_iterator.MoveToNextRange()); } @@ -401,23 +398,23 @@ display: grid; } #cell1 { - grid-column: 1 / 1; - grid-row: 1 / 1; + grid-column: 1 / 2; + grid-row: 1 / 2; width: 50px; } #cell2 { - grid-column: 2 / 2; - grid-row: 1 / 1; + grid-column: 2 / 3; + grid-row: 1 / 2; width: 50px; } #cell3 { - grid-column: 1 / 1; - grid-row: 2 / 2; + grid-column: 1 / 2; + grid-row: 2 / 3; width: 50px; } #cell4 { grid-column: 2 / 5; - grid-row: 2 / 2; + grid-row: 2 / 3; width: 50px; } </style> @@ -440,37 +437,89 @@ NGGridLayoutAlgorithm algorithm({node, fragment_geometry, space}); EXPECT_EQ(GridItemCount(algorithm), 0U); - SetAutoTrackRepeat(algorithm, 5, 5); + SetAutoTrackRepeat(algorithm, 0, 0); algorithm.Layout(); EXPECT_EQ(GridItemCount(algorithm), 4U); NGGridTrackCollectionBase::RangeRepeatIterator column_iterator( &algorithm.ColumnTrackCollection(), 0u); - EXPECT_EQ(1u, column_iterator.RangeTrackStart()); - EXPECT_EQ(1u, column_iterator.RangeTrackEnd()); - EXPECT_EQ(1u, column_iterator.RepeatCount()); + EXPECT_RANGE(0u, 1u, column_iterator); EXPECT_TRUE(column_iterator.MoveToNextRange()); - EXPECT_EQ(2u, column_iterator.RangeTrackStart()); - EXPECT_EQ(2u, column_iterator.RangeTrackEnd()); - EXPECT_EQ(1u, column_iterator.RepeatCount()); + EXPECT_RANGE(1u, 1u, column_iterator); EXPECT_TRUE(column_iterator.MoveToNextRange()); - EXPECT_EQ(3u, column_iterator.RangeTrackStart()); - EXPECT_EQ(5u, column_iterator.RangeTrackEnd()); - EXPECT_EQ(3u, column_iterator.RepeatCount()); + EXPECT_RANGE(2u, 2u, column_iterator); EXPECT_FALSE(column_iterator.MoveToNextRange()); NGGridTrackCollectionBase::RangeRepeatIterator row_iterator( &algorithm.RowTrackCollection(), 0u); - EXPECT_EQ(1u, row_iterator.RangeTrackStart()); - EXPECT_EQ(1u, row_iterator.RangeTrackEnd()); - EXPECT_EQ(1u, row_iterator.RepeatCount()); + EXPECT_RANGE(0u, 1u, row_iterator); EXPECT_TRUE(row_iterator.MoveToNextRange()); - EXPECT_EQ(2u, row_iterator.RangeTrackStart()); - EXPECT_EQ(2u, row_iterator.RangeTrackEnd()); - EXPECT_EQ(1u, row_iterator.RepeatCount()); + EXPECT_RANGE(1u, 1u, row_iterator); + EXPECT_FALSE(row_iterator.MoveToNextRange()); +} + +TEST_F(NGGridLayoutAlgorithmTest, NGGridLayoutAlgorithmGridPositions) { + if (!RuntimeEnabledFeatures::LayoutNGGridEnabled()) + return; + + SetBodyInnerHTML(R"HTML( + <style> + #grid { + display: grid; + height: 200px; + grid-template-columns: 200px; + grid-template-rows: repeat(6, 1fr); + } + + #item2 { + background-color: yellow; + grid-row: -2 / 4; + } + + #item3 { + background-color: blue; + grid-row: span 2 / 7; + } + </style> + <div id="grid"> + <div id="item1"></div> + <div id="item2"></div> + <div id="item3"></div> + </div> + )HTML"); + + NGBlockNode node(ToLayoutBox(GetLayoutObjectByElementId("grid"))); + + NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace( + WritingMode::kHorizontalTb, TextDirection::kLtr, + LogicalSize(LayoutUnit(500), LayoutUnit(500)), false, true); + + NGFragmentGeometry fragment_geometry = + CalculateInitialFragmentGeometry(space, node); + + NGGridLayoutAlgorithm algorithm({node, fragment_geometry, space}); + EXPECT_EQ(GridItemCount(algorithm), 0U); + SetAutoTrackRepeat(algorithm, 0, 0); + algorithm.Layout(); + EXPECT_EQ(GridItemCount(algorithm), 3U); + + NGGridTrackCollectionBase::RangeRepeatIterator column_iterator( + &algorithm.ColumnTrackCollection(), 0u); + EXPECT_RANGE(0u, 1u, column_iterator); + EXPECT_FALSE(column_iterator.MoveToNextRange()); + + NGGridTrackCollectionBase::RangeRepeatIterator row_iterator( + &algorithm.RowTrackCollection(), 0u); + EXPECT_RANGE(0u, 3u, row_iterator); + EXPECT_TRUE(row_iterator.MoveToNextRange()); + EXPECT_RANGE(3u, 1u, row_iterator); + EXPECT_TRUE(row_iterator.MoveToNextRange()); + EXPECT_RANGE(4u, 1u, row_iterator); + EXPECT_TRUE(row_iterator.MoveToNextRange()); + EXPECT_RANGE(5u, 1u, row_iterator); EXPECT_FALSE(row_iterator.MoveToNextRange()); }
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc index 7729f32..a30216b 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.cc
@@ -153,13 +153,12 @@ wtf_size_t total_track_count = 0; for (wtf_size_t i = 0; i < repeater_count; ++i) { - wtf_size_t repeater_track_start = total_track_count + 1; wtf_size_t repeater_track_count = explicit_tracks_->RepeatCount(i, auto_repeat_count_) * explicit_tracks_->RepeatSize(i); if (repeater_track_count != 0) { - starting_tracks_.push_back(repeater_track_start); - ending_tracks_.push_back(repeater_track_start + repeater_track_count - 1); + starting_tracks_.push_back(total_track_count); + ending_tracks_.push_back(total_track_count + repeater_track_count); } total_track_count += repeater_track_count; } @@ -171,7 +170,7 @@ DCHECK_NE(kInvalidRangeIndex, span_length); track_indices_need_sort_ = true; starting_tracks_.push_back(track_number); - ending_tracks_.push_back(track_number + span_length - 1); + ending_tracks_.push_back(track_number + span_length); } void NGGridBlockTrackCollection::FinalizeRanges() { @@ -183,21 +182,19 @@ std::stable_sort(ending_tracks_.begin(), ending_tracks_.end()); } - wtf_size_t current_range_track_start = 1u; - if (starting_tracks_.size() > 0 && starting_tracks_[0] == 0) - current_range_track_start = 0; + wtf_size_t current_range_track_start = 0u; // Indices into the starting and ending track vectors. - wtf_size_t starting_tracks_index = 0; - wtf_size_t ending_tracks_index = 0; + wtf_size_t starting_tracks_index = 0u; + wtf_size_t ending_tracks_index = 0u; wtf_size_t repeater_index = kInvalidRangeIndex; wtf_size_t repeater_track_start = kInvalidRangeIndex; - wtf_size_t next_repeater_track_start = 1u; - wtf_size_t current_repeater_track_count = 0; + wtf_size_t next_repeater_track_start = 0u; + wtf_size_t current_repeater_track_count = 0u; wtf_size_t total_repeater_count = explicit_tracks_->RepeaterCount(); - wtf_size_t open_items_or_repeaters = 0; + wtf_size_t open_items_or_repeaters = 0u; bool is_in_auto_fit_range = false; while (true) { @@ -211,7 +208,7 @@ // Identify ending tracks index. while (ending_tracks_index < ending_tracks_.size() && - current_range_track_start > ending_tracks_[ending_tracks_index]) { + current_range_track_start >= ending_tracks_[ending_tracks_index]) { ++ending_tracks_index; --open_items_or_repeaters; DCHECK_GE(open_items_or_repeaters, 0u); @@ -251,13 +248,10 @@ // Determine track number and count of the range. Range range; range.starting_track_number = current_range_track_start; - if (next_starting_track != kInvalidRangeIndex) { - range.track_count = - std::min(next_ending_track + 1u, next_starting_track) - - current_range_track_start; - } else { - range.track_count = next_ending_track + 1u - current_range_track_start; - } + DCHECK(next_starting_track != kInvalidRangeIndex || + next_ending_track < next_starting_track); + range.track_count = std::min(next_ending_track, next_starting_track) - + current_range_track_start; // Compute repeater index and offset. if (repeater_index == kInvalidRangeIndex) {
diff --git a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc index f55865b1..4784f18 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection_test.cc
@@ -187,10 +187,10 @@ NGGridTrackCollectionBase::RangeRepeatIterator iterator(&block_collection, 0u); - EXPECT_RANGE(1u, 8u, iterator); + EXPECT_RANGE(0u, 8u, iterator); EXPECT_TRUE(iterator.MoveToNextRange()); - EXPECT_RANGE(9u, 9u, iterator); + EXPECT_RANGE(8u, 9u, iterator); EXPECT_FALSE(iterator.MoveToNextRange()); } @@ -208,13 +208,13 @@ NGGridTrackCollectionBase::RangeRepeatIterator iterator(&block_collection, 0u); - EXPECT_RANGE(1u, 8u, iterator); + EXPECT_RANGE(0u, 8u, iterator); EXPECT_TRUE(iterator.MoveToNextRange()); - EXPECT_COLLAPSED_RANGE(9u, 9u, iterator); + EXPECT_COLLAPSED_RANGE(8u, 9u, iterator); EXPECT_TRUE(iterator.MoveToNextRange()); - EXPECT_RANGE(18u, 21u, iterator); + EXPECT_RANGE(17u, 21u, iterator); EXPECT_FALSE(iterator.MoveToNextRange()); } @@ -236,24 +236,24 @@ block_collection.FinalizeRanges(); NGGridTrackCollectionBase::RangeRepeatIterator iterator(&block_collection, 0u); - EXPECT_RANGE(1u, 2u, iterator); - EXPECT_FALSE(block_collection.RangeAtTrackNumber(1u).is_implicit_range); + EXPECT_RANGE(0u, 3u, iterator); + EXPECT_FALSE(block_collection.RangeAtTrackNumber(0u).is_implicit_range); EXPECT_TRUE(iterator.MoveToNextRange()); - EXPECT_RANGE(3u, 6u, iterator); - EXPECT_FALSE(block_collection.RangeAtTrackNumber(4).is_implicit_range); + EXPECT_RANGE(3u, 5u, iterator); + EXPECT_FALSE(block_collection.RangeAtTrackNumber(3).is_implicit_range); EXPECT_TRUE(iterator.MoveToNextRange()); - EXPECT_RANGE(9u, 9u, iterator); - EXPECT_FALSE(block_collection.RangeAtTrackNumber(7).is_implicit_range); + EXPECT_RANGE(8u, 9u, iterator); + EXPECT_FALSE(block_collection.RangeAtTrackNumber(11).is_implicit_range); EXPECT_TRUE(iterator.MoveToNextRange()); - EXPECT_RANGE(18u, 21u, iterator); EXPECT_FALSE(block_collection.RangeAtTrackNumber(20).is_implicit_range); + EXPECT_RANGE(17u, 21u, iterator); EXPECT_TRUE(iterator.MoveToNextRange()); EXPECT_TRUE(block_collection.RangeAtTrackNumber(40).is_implicit_range); - EXPECT_RANGE(39u, 4u, iterator); + EXPECT_RANGE(38u, 5u, iterator); EXPECT_FALSE(iterator.MoveToNextRange()); } @@ -344,7 +344,7 @@ wtf_size_t range_count = 0; for (auto range_iterator = algorithm_collection.RangeIterator(); !range_iterator.IsAtEnd(); range_iterator.MoveToNextRange()) { - EXPECT_RANGE(1u + set_count, set_counts[range_count], range_iterator); + EXPECT_RANGE(set_count, set_counts[range_count], range_iterator); wtf_size_t current_range_set_count = 0; for (auto set_iterator = @@ -381,10 +381,10 @@ NGGridBlockTrackCollection block_collection; block_collection.SetSpecifiedTracks(&explicit_tracks, &implicit_tracks, /* auto_repeat_count */ 5); - block_collection.EnsureTrackCoverage(3, 4); - block_collection.EnsureTrackCoverage(13, 4); - block_collection.EnsureTrackCoverage(18, 3); - block_collection.EnsureTrackCoverage(23, 5); + block_collection.EnsureTrackCoverage(2, 4); + block_collection.EnsureTrackCoverage(12, 4); + block_collection.EnsureTrackCoverage(17, 3); + block_collection.EnsureTrackCoverage(22, 5); block_collection.FinalizeRanges(); NGGridLayoutAlgorithmTrackCollection algorithm_collection( @@ -392,7 +392,7 @@ NGGridTrackCollectionBase::RangeRepeatIterator range_iterator = algorithm_collection.RangeIterator(); - EXPECT_RANGE(1u, 2u, range_iterator); + EXPECT_RANGE(0u, 2u, range_iterator); NGGridLayoutAlgorithmTrackCollection::SetIterator set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator); @@ -401,7 +401,7 @@ EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(3u, 4u, range_iterator); + EXPECT_RANGE(2u, 4u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(3)), 2u, set_iterator); @@ -412,7 +412,7 @@ EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(7u, 3u, range_iterator); + EXPECT_RANGE(6u, 3u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator); @@ -423,14 +423,14 @@ EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_COLLAPSED_RANGE(10u, 3u, range_iterator); + EXPECT_COLLAPSED_RANGE(9u, 3u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(0)), 3u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(13u, 4u, range_iterator); + EXPECT_RANGE(12u, 4u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(5)), 2u, set_iterator); @@ -439,14 +439,14 @@ EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_COLLAPSED_RANGE(17u, 1u, range_iterator); + EXPECT_COLLAPSED_RANGE(16u, 1u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(0)), 1u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(18u, 2u, range_iterator); + EXPECT_RANGE(17u, 2u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(4)), 1u, set_iterator); @@ -455,21 +455,21 @@ EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(20u, 1u, range_iterator); + EXPECT_RANGE(19u, 1u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Auto()), 1u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(21u, 2u, range_iterator); + EXPECT_RANGE(20u, 2u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Auto()), 2u, set_iterator); EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(23u, 5u, range_iterator); + EXPECT_RANGE(22u, 5u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Auto()), 5u, set_iterator); @@ -499,8 +499,8 @@ NGGridBlockTrackCollection block_collection; block_collection.SetSpecifiedTracks(&explicit_tracks, &implicit_tracks, /* auto_repeat_count */ 0); - block_collection.EnsureTrackCoverage(3, 13); - block_collection.EnsureTrackCoverage(24, 2); + block_collection.EnsureTrackCoverage(2, 13); + block_collection.EnsureTrackCoverage(23, 2); block_collection.FinalizeRanges(); NGGridLayoutAlgorithmTrackCollection algorithm_collection( @@ -508,7 +508,7 @@ NGGridTrackCollectionBase::RangeRepeatIterator range_iterator = algorithm_collection.RangeIterator(); - EXPECT_RANGE(1u, 2u, range_iterator); + EXPECT_RANGE(0u, 2u, range_iterator); NGGridLayoutAlgorithmTrackCollection::SetIterator set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator); @@ -517,7 +517,7 @@ EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(3u, 2u, range_iterator); + EXPECT_RANGE(2u, 2u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(3)), 1u, set_iterator); @@ -526,7 +526,7 @@ EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(5u, 11u, range_iterator); + EXPECT_RANGE(4u, 11u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(5)), 4u, set_iterator); @@ -537,7 +537,7 @@ EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(16u, 8u, range_iterator); + EXPECT_RANGE(15u, 8u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(7)), 3u, set_iterator); @@ -548,7 +548,7 @@ EXPECT_FALSE(set_iterator.MoveToNextSet()); EXPECT_TRUE(range_iterator.MoveToNextRange()); - EXPECT_RANGE(24u, 2u, range_iterator); + EXPECT_RANGE(23u, 2u, range_iterator); set_iterator = algorithm_collection.IteratorForRange(range_iterator.RangeIndex()); EXPECT_SET(GridTrackSize(Length::Fixed(6)), 1u, set_iterator);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc index 872323e..e0e666d0 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -53,6 +53,8 @@ #include "third_party/blink/renderer/core/layout/ng/ng_page_layout_algorithm.h" #include "third_party/blink/renderer/core/layout/ng/ng_simplified_layout_algorithm.h" #include "third_party/blink/renderer/core/layout/ng/ng_space_utils.h" +#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h" #include "third_party/blink/renderer/core/layout/shapes/shape_outside_info.h" #include "third_party/blink/renderer/core/layout/text_autosizer.h" #include "third_party/blink/renderer/core/mathml/mathml_element.h" @@ -965,6 +967,24 @@ return NGBlockNode(ToLayoutBox(child)); } +bool NGBlockNode::IsFixedTableLayout() const { + DCHECK(IsNGTable()); + return To<LayoutNGTable>(box_)->IsFixedTableLayout(); +} + +const NGBoxStrut& NGBlockNode::GetTableBorders() const { + DCHECK(IsTable()); + DCHECK(box_->IsLayoutNGMixin()); + LayoutNGTable* layout_table = To<LayoutNGTable>(box_); + scoped_refptr<const NGTableBorders> table_borders = + layout_table->GetCachedTableBorders(); + if (!table_borders) { + table_borders = NGTableBorders::ComputeTableBorders(*this); + layout_table->SetCachedTableBorders(table_borders.get()); + } + return table_borders->TableBorder(); +} + bool NGBlockNode::CanUseNewLayout(const LayoutBox& box) { DCHECK(RuntimeEnabledFeatures::LayoutNGEnabled()); if (box.ForceLegacyLayout())
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.h b/third_party/blink/renderer/core/layout/ng/ng_block_node.h index 24421c27..2b4ff0e 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.h +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.h
@@ -94,6 +94,10 @@ NGBlockNode GetRenderedLegend() const; NGBlockNode GetFieldsetContent() const; + bool IsNGTable() const { return IsTable() && box_->IsLayoutNGMixin(); } + bool IsFixedTableLayout() const; + const NGBoxStrut& GetTableBorders() const; + // Return true if this block node establishes an inline formatting context. // This will only be the case if there is actual inline content. Empty nodes // or nodes consisting purely of block-level, floats, and/or out-of-flow
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc index 08fea248..4c88cd00 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -925,6 +925,9 @@ if (constraint_space.IsTableCell()) return constraint_space.TableCellBorders(); + if (node.IsNGTable()) + return node.GetTableBorders(); + return ComputeBordersInternal(node.Style()); } @@ -963,6 +966,13 @@ if (!style.MayHavePadding() || constraint_space.IsAnonymous()) return NGBoxStrut(); + // Tables with collapsed borders don't have any padding. + if ((style.Display() == EDisplay::kTable || + style.Display() == EDisplay::kInlineTable) && + style.BorderCollapse() == EBorderCollapse::kCollapse) { + return NGBoxStrut(); + } + LayoutUnit percentage_resolution_size = constraint_space.PercentageResolutionInlineSizeForParentWritingMode(); NGBoxStrut padding = {
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc index 90f2147d..23f2a36 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
@@ -7,10 +7,17 @@ #include "third_party/blink/renderer/core/layout/layout_analyzer.h" #include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/layout/layout_view.h" +#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h" +#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h" +#include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h" +#include "third_party/blink/renderer/core/style/border_edge.h" namespace blink { @@ -31,9 +38,29 @@ : LayoutNGMixin<LayoutBlock>(element) {} wtf_size_t LayoutNGTable::ColumnCount() const { - // TODO(atotic) land implementation. - NOTIMPLEMENTED(); - return 0; + const NGLayoutResult* cached_layout_result = GetCachedLayoutResult(); + if (!cached_layout_result) + return 0; + return cached_layout_result->TableColumnCount(); +} + +void LayoutNGTable::SetCachedTableBorders(const NGTableBorders* table_borders) { + cached_table_borders_ = table_borders; +} + +void LayoutNGTable::InvalidateCachedTableBorders() { + // When cached borders are invalidated, we could do a special kind of relayout + // where fragments can replace only TableBorders, keep the geometry, and + // repaint. + cached_table_borders_.reset(); +} + +void LayoutNGTable::GridBordersChanged() { + InvalidateCachedTableBorders(); +} + +void LayoutNGTable::TableGridStructureChanged() { + InvalidateCachedTableBorders(); } void LayoutNGTable::UpdateBlockLayout(bool relayout_children) { @@ -47,6 +74,7 @@ } void LayoutNGTable::AddChild(LayoutObject* child, LayoutObject* before_child) { + TableGridStructureChanged(); bool wrap_in_anonymous_section = !child->IsTableCaption() && !child->IsLayoutTableCol() && !child->IsTableSection(); @@ -96,9 +124,19 @@ section->AddChild(child); } -LayoutBox* LayoutNGTable::CreateAnonymousBoxWithSameTypeAs( - const LayoutObject* parent) const { - return LayoutObjectFactory::CreateAnonymousTableWithParent(*parent); +void LayoutNGTable::RemoveChild(LayoutObject* child) { + TableGridStructureChanged(); + LayoutNGMixin<LayoutBlock>::RemoveChild(child); +} + +void LayoutNGTable::StyleDidChange(StyleDifference diff, + const ComputedStyle* old_style) { + // TODO(1115800) Make border invalidation more precise. + if (NGTableBorders::HasBorder(old_style) || + NGTableBorders::HasBorder(Style())) { + GridBordersChanged(); + } + LayoutNGMixin<LayoutBlock>::StyleDidChange(diff, old_style); } bool LayoutNGTable::IsFirstCell(const LayoutNGTableCellInterface& cell) const { @@ -108,10 +146,12 @@ const LayoutNGTableSectionInterface* section = row->SectionInterface(); if (section->FirstRowInterface() != row) return false; - // TODO(atotic) Should be TopNonEmptyInterface? - if (TopSectionInterface() != section) - return false; - return true; + NGTableGroupedChildren grouped_children( + NGBlockNode(const_cast<LayoutNGTable*>(this))); + auto first_section = grouped_children.begin(); + return first_section != grouped_children.end() && + ToInterface<LayoutNGTableSectionInterface>( + (*first_section).GetLayoutBox()) == section; } // Only called from AXLayoutObject::IsDataTable() @@ -126,7 +166,13 @@ // Called from many AXLayoutObject methods. LayoutNGTableSectionInterface* LayoutNGTable::TopSectionInterface() const { - // TODO(atotic) implement. + NGTableGroupedChildren grouped_children( + NGBlockNode(const_cast<LayoutNGTable*>(this))); + auto first_section = grouped_children.begin(); + if (first_section != grouped_children.end()) { + return ToInterface<LayoutNGTableSectionInterface>( + (*first_section).GetLayoutBox()); + } return nullptr; } @@ -134,7 +180,17 @@ LayoutNGTableSectionInterface* LayoutNGTable::SectionBelowInterface( const LayoutNGTableSectionInterface* target, SkipEmptySectionsValue skip) const { - // TODO(atotic) implement. + NGTableGroupedChildren grouped_children( + NGBlockNode(const_cast<LayoutNGTable*>(this))); + bool found = false; + for (NGBlockNode section : grouped_children) { + if (found && + ((skip == kDoNotSkipEmptySections) || (!section.IsEmptyTableSection()))) + return To<LayoutNGTableSection>(section.GetLayoutBox()); + if (target == To<LayoutNGTableSection>(section.GetLayoutBox()) + ->ToLayoutNGTableSectionInterface()) + found = true; + } return nullptr; }
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h index e82945e..debbade9 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h
@@ -12,6 +12,8 @@ namespace blink { +class NGTableBorders; + class CORE_EXPORT LayoutNGTable : public LayoutNGMixin<LayoutBlock>, public LayoutNGTableInterface { public: @@ -27,6 +29,19 @@ wtf_size_t ColumnCount() const; + const NGTableBorders* GetCachedTableBorders() const { + return cached_table_borders_.get(); + } + + void SetCachedTableBorders(const NGTableBorders* table_borders); + + // Any borders in table grid have changed. + void GridBordersChanged(); + + // Table descendants have been added/removed, and number of rows/columns + // might have changed. + void TableGridStructureChanged(); + // LayoutBlock methods start. const char* GetName() const override { return "LayoutNGTable"; } @@ -36,8 +51,10 @@ void AddChild(LayoutObject* child, LayoutObject* before_child = nullptr) override; - LayoutBox* CreateAnonymousBoxWithSameTypeAs( - const LayoutObject* parent) const override; + void RemoveChild(LayoutObject*) override; + + void StyleDidChange(StyleDifference diff, + const ComputedStyle* old_style) override; // LayoutBlock methods end. @@ -46,17 +63,22 @@ const LayoutNGTableInterface* ToLayoutNGTableInterface() const final { return this; } + const LayoutObject* ToLayoutObject() const final { return this; } + // Non-const version required by TextAutosizer, AXLayoutObject. LayoutObject* ToMutableLayoutObject() final { return this; } + bool ShouldCollapseBorders() const final { return StyleRef().BorderCollapse() == EBorderCollapse::kCollapse; } + // Used in table painting for invalidation. Should not be needed by NG. bool HasCollapsedBorders() const final { NOTREACHED(); return false; } + bool HasColElements() const final { NOTREACHED(); return false; @@ -83,6 +105,7 @@ // Legacy caches sections. Might not be needed by NG. void RecalcSectionsIfNeeded() const final {} + // Legacy caches sections. Might not be needed by NG. void ForceSectionsRecalc() final {} @@ -130,6 +153,12 @@ return type == kLayoutObjectTable || LayoutNGMixin<LayoutBlock>::IsOfType(type); } + + private: + void InvalidateCachedTableBorders(); + + // Table borders are cached because computing collapsed borders is expensive. + scoped_refptr<const NGTableBorders> cached_table_borders_; }; // wtf/casting.h helper.
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc index cca5eb81..0ef8329 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc
@@ -13,7 +13,9 @@ #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" #include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" +#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h" +#include "third_party/blink/renderer/core/style/border_edge.h" namespace blink { @@ -22,6 +24,15 @@ UpdateColAndRowSpanFlags(); } +LayoutNGTable* LayoutNGTableCell::Table() const { + if (LayoutObject* parent = Parent()) { + if (LayoutObject* grandparent = parent->Parent()) { + return To<LayoutNGTable>(grandparent->Parent()); + } + } + return nullptr; +} + void LayoutNGTableCell::UpdateBlockLayout(bool relayout_children) { LayoutAnalyzer::BlockScope analyzer(*this); @@ -32,9 +43,21 @@ UpdateInFlowBlockLayout(); } +void LayoutNGTableCell::StyleDidChange(StyleDifference diff, + const ComputedStyle* old_style) { + if (LayoutNGTable* table = Table()) { + if (NGTableBorders::HasBorder(old_style) || + NGTableBorders::HasBorder(Style())) + table->GridBordersChanged(); + } + LayoutNGBlockFlowMixin<LayoutBlockFlow>::StyleDidChange(diff, old_style); +} + void LayoutNGTableCell::ColSpanOrRowSpanChanged() { // TODO(atotic) Invalidate layout? UpdateColAndRowSpanFlags(); + if (LayoutNGTable* table = Table()) + table->TableGridStructureChanged(); } LayoutBox* LayoutNGTableCell::CreateAnonymousBoxWithSameTypeAs( @@ -59,15 +82,9 @@ return ParsedRowSpan(); } -// TODO(crbug.com/1079133): Used by AXLayoutObject, -// verify behaviour is correct. unsigned LayoutNGTableCell::AbsoluteColumnIndex() const { - unsigned index = 0; - for (LayoutObject* child = Parent()->SlowFirstChild(); child; - child = child->NextSibling()) { - if (child == this) - return index; - ++index; + if (PhysicalFragmentCount() > 0) { + return GetPhysicalFragment(0)->TableCellColumnIndex(); } NOTREACHED() << "AbsoluteColumnIndex did not find cell"; return 0;
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h index c1295a4..d64bc25 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h
@@ -13,6 +13,8 @@ namespace blink { +class LayoutNGTable; + class CORE_EXPORT LayoutNGTableCell : public LayoutNGBlockFlowMixin<LayoutBlockFlow>, public LayoutNGTableCellInterface { @@ -28,10 +30,15 @@ return rowspan; } + LayoutNGTable* Table() const; + // LayoutBlockFlow methods start. void UpdateBlockLayout(bool relayout_children) override; + void StyleDidChange(StyleDifference diff, + const ComputedStyle* old_style) final; + // TODO(atotic) Remove "New" from name. // Currently, LayoutNGTableCellLegacy is named LayoutNGTableCell for test // compat.
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.cc index ae92132..f1c8235 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/renderer/core/html/html_table_col_element.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h" namespace blink { @@ -17,24 +18,20 @@ void LayoutNGTableColumn::StyleDidChange(StyleDifference diff, const ComputedStyle* old_style) { if (diff.NeedsPaintInvalidation() && old_style) { - // Could also call SetShouldDoFullPaintInvalidationWithoutGeometryChange? - // TODO(atotic+paint_team) Need paint team review. - // Is this how to invalidate background only? if (LayoutNGTable* table = Table()) { - table->SetShouldDoFullPaintInvalidationWithoutGeometryChange( - PaintInvalidationReason::kBackground); + if (NGTableBorders::HasBorder(old_style) || + NGTableBorders::HasBorder(Style())) + table->GridBordersChanged(); } } LayoutBoxModelObject::StyleDidChange(diff, old_style); } void LayoutNGTableColumn::ImageChanged(WrappedImagePtr, CanDeferInvalidation) { - // TODO(atotic+paint_team) Need paint team review. - // LayoutBox::ImageChanged is a lot more sophisticated. - // Should I call SetShouldDoFullPaintInvalidationWithoutGeometryChange - // instead? - if (LayoutNGTable* table = Table()) - table->SetShouldDoFullPaintInvalidation(PaintInvalidationReason::kImage); + if (LayoutNGTable* table = Table()) { + table->SetShouldDoFullPaintInvalidationWithoutGeometryChange( + PaintInvalidationReason::kImage); + } } bool LayoutNGTableColumn::IsChildAllowed(LayoutObject* child,
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc index d790450..13b2e70d 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.cc
@@ -4,13 +4,11 @@ #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h" -#include "third_party/blink/renderer/core/layout/layout_analyzer.h" #include "third_party/blink/renderer/core/layout/layout_object_factory.h" -#include "third_party/blink/renderer/core/layout/layout_view.h" +#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h" -#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row_interface.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h" -#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section_interface.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h" namespace blink { @@ -21,8 +19,19 @@ return !FirstChild(); } +LayoutNGTable* LayoutNGTableRow::Table() const { + if (LayoutObject* section = Parent()) { + if (LayoutObject* table = section->Parent()) + return To<LayoutNGTable>(table); + } + return nullptr; +} + void LayoutNGTableRow::AddChild(LayoutObject* child, LayoutObject* before_child) { + if (LayoutNGTable* table = Table()) + table->TableGridStructureChanged(); + if (!child->IsTableCell()) { LayoutObject* last = before_child; if (!last) @@ -67,6 +76,22 @@ LayoutNGMixin<LayoutBlock>::AddChild(child, before_child); } +void LayoutNGTableRow::RemoveChild(LayoutObject* child) { + if (LayoutNGTable* table = Table()) + table->TableGridStructureChanged(); + LayoutNGMixin<LayoutBlock>::RemoveChild(child); +} + +void LayoutNGTableRow::StyleDidChange(StyleDifference diff, + const ComputedStyle* old_style) { + if (LayoutNGTable* table = Table()) { + if (NGTableBorders::HasBorder(old_style) || + NGTableBorders::HasBorder(Style())) + table->GridBordersChanged(); + } + LayoutNGMixin<LayoutBlock>::StyleDidChange(diff, old_style); +} + LayoutBox* LayoutNGTableRow::CreateAnonymousBoxWithSameTypeAs( const LayoutObject* parent) const { return LayoutObjectFactory::CreateAnonymousTableRowWithParent(*parent);
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h index 14048ea9..046fede 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h
@@ -12,6 +12,8 @@ namespace blink { class LayoutNGTableCell; +class LayoutNGTable; + // NOTE: // Legacy table row inherits from LayoutBox, not LayoutBlock. // Every child of LayoutNGTableRow must be LayoutNGTableCell. @@ -22,6 +24,8 @@ bool IsEmpty() const; + LayoutNGTable* Table() const; + // LayoutBlock methods start. void UpdateBlockLayout(bool relayout_children) override { NOTREACHED(); } @@ -31,6 +35,11 @@ void AddChild(LayoutObject* child, LayoutObject* before_child = nullptr) override; + void RemoveChild(LayoutObject*) override; + + void StyleDidChange(StyleDifference diff, + const ComputedStyle* old_style) override; + LayoutBox* CreateAnonymousBoxWithSameTypeAs( const LayoutObject* parent) const override;
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc index 65b2c1f..2cec8b3 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.cc
@@ -4,13 +4,10 @@ #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h" -#include "third_party/blink/renderer/core/layout/layout_analyzer.h" #include "third_party/blink/renderer/core/layout/layout_object_factory.h" -#include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h" -#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h" -#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_interface.h" #include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_row.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h" namespace blink { @@ -26,8 +23,15 @@ return true; } +LayoutNGTable* LayoutNGTableSection::Table() const { + return To<LayoutNGTable>(Parent()); +} + void LayoutNGTableSection::AddChild(LayoutObject* child, LayoutObject* before_child) { + if (LayoutNGTable* table = Table()) + table->TableGridStructureChanged(); + if (!child->IsTableRow()) { LayoutObject* last = before_child; if (!last) @@ -73,6 +77,23 @@ LayoutNGMixin<LayoutBlock>::AddChild(child, before_child); } +void LayoutNGTableSection::RemoveChild(LayoutObject* child) { + if (LayoutNGTable* table = Table()) + table->TableGridStructureChanged(); + LayoutNGMixin<LayoutBlock>::RemoveChild(child); +} + +void LayoutNGTableSection::StyleDidChange(StyleDifference diff, + const ComputedStyle* old_style) { + if (LayoutNGTable* table = Table()) { + if (NGTableBorders::HasBorder(old_style) || + NGTableBorders::HasBorder(Style())) { + table->GridBordersChanged(); + } + } + LayoutNGMixin<LayoutBlock>::StyleDidChange(diff, old_style); +} + LayoutBox* LayoutNGTableSection::CreateAnonymousBoxWithSameTypeAs( const LayoutObject* parent) const { return LayoutObjectFactory::CreateAnonymousTableSectionWithParent(*parent);
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h index 8e94203..1f83b54 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_section.h
@@ -12,6 +12,8 @@ namespace blink { +class LayoutNGTable; + // NOTE: // Every child of LayoutNGTableSection must be LayoutNGTableRow. class CORE_EXPORT LayoutNGTableSection : public LayoutNGMixin<LayoutBlock>, @@ -21,6 +23,8 @@ bool IsEmpty() const; + LayoutNGTable* Table() const; + // LayoutBlock methods start. void UpdateBlockLayout(bool relayout_children) override { NOTREACHED(); } @@ -30,6 +34,11 @@ void AddChild(LayoutObject* child, LayoutObject* before_child = nullptr) override; + void RemoveChild(LayoutObject*) override; + + void StyleDidChange(StyleDifference diff, + const ComputedStyle* old_style) override; + LayoutBox* CreateAnonymousBoxWithSameTypeAs( const LayoutObject* parent) const override; @@ -47,13 +56,16 @@ DCHECK(false); return nullptr; } + const LayoutNGTableSectionInterface* ToLayoutNGTableSectionInterface() const final { return this; } + LayoutNGTableSectionInterface* ToLayoutNGTableSectionInterface() { return this; } + const LayoutObject* ToLayoutObject() const final { return this; } LayoutObject* ToMutableLayoutObject() final { return this; }
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc index 88c8605..22a51e2 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.cc
@@ -8,6 +8,11 @@ #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h" #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" +#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h" +#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column_visitor.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h" +#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h" #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { @@ -38,17 +43,285 @@ return source_style > edge_border_style; } +// Side of the style the collapsed border belongs to. +enum class LogicalEdgeSide { kInlineStart, kInlineEnd, kBlockStart, kBlockEnd }; + +NGTableBorders::EdgeSide LogicalEdgeToPhysical( + LogicalEdgeSide logical_side, + WritingDirectionMode table_writing_direction) { + // https://www.w3.org/TR/css-writing-modes-4/#logical-to-physical + switch (logical_side) { + case LogicalEdgeSide::kInlineStart: + switch (table_writing_direction.GetWritingMode()) { + case WritingMode::kHorizontalTb: + return table_writing_direction.Direction() == TextDirection::kLtr + ? NGTableBorders::EdgeSide::kLeft + : NGTableBorders::EdgeSide::kRight; + case WritingMode::kVerticalLr: + case WritingMode::kVerticalRl: + case WritingMode::kSidewaysRl: + return table_writing_direction.Direction() == TextDirection::kLtr + ? NGTableBorders::EdgeSide::kTop + : NGTableBorders::EdgeSide::kBottom; + case WritingMode::kSidewaysLr: + return table_writing_direction.Direction() == TextDirection::kLtr + ? NGTableBorders::EdgeSide::kBottom + : NGTableBorders::EdgeSide::kTop; + } + case LogicalEdgeSide::kInlineEnd: + switch (table_writing_direction.GetWritingMode()) { + case WritingMode::kHorizontalTb: + return table_writing_direction.Direction() == TextDirection::kLtr + ? NGTableBorders::EdgeSide::kRight + : NGTableBorders::EdgeSide::kLeft; + case WritingMode::kVerticalLr: + case WritingMode::kVerticalRl: + case WritingMode::kSidewaysRl: + return table_writing_direction.Direction() == TextDirection::kLtr + ? NGTableBorders::EdgeSide::kBottom + : NGTableBorders::EdgeSide::kTop; + case WritingMode::kSidewaysLr: + return table_writing_direction.Direction() == TextDirection::kLtr + ? NGTableBorders::EdgeSide::kTop + : NGTableBorders::EdgeSide::kBottom; + } + case LogicalEdgeSide::kBlockStart: + switch (table_writing_direction.GetWritingMode()) { + case WritingMode::kHorizontalTb: + return NGTableBorders::EdgeSide::kTop; + case WritingMode::kVerticalLr: + case WritingMode::kSidewaysLr: + return NGTableBorders::EdgeSide::kLeft; + case WritingMode::kVerticalRl: + case WritingMode::kSidewaysRl: + return NGTableBorders::EdgeSide::kRight; + } + case LogicalEdgeSide::kBlockEnd: + switch (table_writing_direction.GetWritingMode()) { + case WritingMode::kHorizontalTb: + return NGTableBorders::EdgeSide::kBottom; + case WritingMode::kVerticalLr: + case WritingMode::kSidewaysLr: + return NGTableBorders::EdgeSide::kRight; + case WritingMode::kVerticalRl: + case WritingMode::kSidewaysRl: + return NGTableBorders::EdgeSide::kLeft; + } + } +} + +class ColBordersMarker { + STACK_ALLOCATED(); + + public: + void VisitCol(const NGLayoutInputNode& column, + wtf_size_t start_column_index, + wtf_size_t span) { + for (wtf_size_t i = 0; i < span; ++i) { + wtf_size_t current_column_index = start_column_index + i; + borders.MergeBorders(0, current_column_index, table_row_count, 1, + &column.Style(), NGTableBorders::EdgeSource::kColumn, + table_writing_direction); + } + } + void EnterColgroup(const NGLayoutInputNode& colgroup, + wtf_size_t start_column_index) {} + void LeaveColgroup(const NGLayoutInputNode& colgroup, + wtf_size_t start_column_index, + wtf_size_t span, + bool has_children) {} + ColBordersMarker(wtf_size_t table_row_count, + WritingDirectionMode table_writing_direction, + NGTableBorders& borders) + : table_row_count(table_row_count), + table_writing_direction(table_writing_direction), + borders(borders) {} + wtf_size_t table_row_count; + WritingDirectionMode table_writing_direction; + NGTableBorders& borders; +}; + +class ColgroupBordersMarker { + STACK_ALLOCATED(); + + public: + void VisitCol(const NGLayoutInputNode& column, + wtf_size_t start_column_index, + wtf_size_t span) {} + void EnterColgroup(const NGLayoutInputNode& colgroup, + wtf_size_t start_column_index) {} + void LeaveColgroup(const NGLayoutInputNode& colgroup, + wtf_size_t start_column_index, + wtf_size_t span, + bool has_children) { + borders.MergeBorders(0, start_column_index, table_row_count, span, + &colgroup.Style(), NGTableBorders::EdgeSource::kColumn, + table_writing_direction); + } + ColgroupBordersMarker(wtf_size_t table_row_count, + WritingDirectionMode table_writing_direction, + NGTableBorders& borders) + : table_row_count(table_row_count), + table_writing_direction(table_writing_direction), + borders(borders) {} + wtf_size_t table_row_count; + WritingDirectionMode table_writing_direction; + NGTableBorders& borders; +}; + } // namespace +scoped_refptr<NGTableBorders> NGTableBorders::ComputeTableBorders( + const NGBlockNode& table) { + const ComputedStyle& table_style = table.Style(); + NGBoxStrut intrinsic_borders(LayoutUnit(table_style.BorderStartWidth()), + LayoutUnit(table_style.BorderEndWidth()), + LayoutUnit(table_style.BorderBeforeWidth()), + LayoutUnit(table_style.BorderAfterWidth())); + scoped_refptr<NGTableBorders> table_borders = + base::MakeRefCounted<NGTableBorders>(table_style, intrinsic_borders); + + if (table_style.BorderCollapse() != EBorderCollapse::kCollapse) + return table_borders; + + NGTableGroupedChildren grouped_children(table); + bool hide_empty_cells = table_style.EmptyCells() == EEmptyCells::kHide; + WritingDirectionMode table_writing_direction = + table.Style().GetWritingDirection(); + wtf_size_t table_column_count = 0; + wtf_size_t table_row_index = 0; + + // Mark cell borders. + bool found_multispan_cells = false; + for (const NGBlockNode section : grouped_children) { + wtf_size_t section_start_row = table_row_index; + NGColspanCellTabulator tabulator; + for (NGBlockNode row = To<NGBlockNode>(section.FirstChild()); row; + row = To<NGBlockNode>(row.NextSibling())) { + tabulator.StartRow(); + for (NGBlockNode cell = To<NGBlockNode>(row.FirstChild()); cell; + cell = To<NGBlockNode>(cell.NextSibling())) { + tabulator.FindNextFreeColumn(); + // https://stackoverflow.com/questions/18758373/why-do-the-css-property-border-collapse-and-empty-cells-conflict + if (hide_empty_cells && !To<NGBlockNode>(cell).FirstChild()) { + tabulator.ProcessCell(cell); + continue; + } + wtf_size_t cell_colspan = cell.TableCellColspan(); + found_multispan_cells |= + cell.TableCellRowspan() > 1 || cell_colspan > 1; + // Rowspan has to be limited by section size. Since we do not know + // section size, we have to rerun cell distribution with limited + // rowspans. + table_column_count = std::max( + table_column_count, NGTableAlgorithmHelpers::ComputeMaxColumn( + tabulator.CurrentColumn(), cell_colspan, + table.IsFixedTableLayout())); + if (!found_multispan_cells) { + table_borders->MergeBorders( + table_row_index, tabulator.CurrentColumn(), + cell.TableCellRowspan(), cell_colspan, &cell.Style(), + NGTableBorders::EdgeSource::kCell, table_writing_direction); + } + tabulator.ProcessCell(cell); + } + tabulator.EndRow(); + ++table_row_index; + } + table_borders->AddSection(section_start_row, + table_row_index - section_start_row); + } + table_borders->SetLastColumnIndex(table_column_count); + + wtf_size_t table_row_count = table_row_index; + table_row_index = 0; + + // Mark cell borders again with limited rowspan. + // If any cells have rowspan, need to redistribute cell borders. + if (found_multispan_cells) { + wtf_size_t section_index = 0; + for (NGBlockNode section : grouped_children) { + NGColspanCellTabulator tabulator; + for (NGBlockNode row = To<NGBlockNode>(section.FirstChild()); row; + row = To<NGBlockNode>(row.NextSibling())) { + tabulator.StartRow(); + for (NGBlockNode cell = To<NGBlockNode>(row.FirstChild()); cell; + cell = To<NGBlockNode>(cell.NextSibling())) { + tabulator.FindNextFreeColumn(); + if (hide_empty_cells && !To<NGBlockNode>(cell).FirstChild()) { + tabulator.ProcessCell(cell); + continue; + } + table_borders->MergeBorders( + table_row_index, tabulator.CurrentColumn(), + cell.TableCellRowspan(), cell.TableCellColspan(), &cell.Style(), + NGTableBorders::EdgeSource::kCell, table_writing_direction, + section_index); + tabulator.ProcessCell(cell); + } + tabulator.EndRow(); + ++table_row_index; + } + ++section_index; + } + } + + // Mark row borders. + table_row_index = 0; + for (NGBlockNode section : grouped_children) { + for (NGBlockNode row = To<NGBlockNode>(section.FirstChild()); row; + row = To<NGBlockNode>(row.NextSibling())) { + table_borders->MergeBorders( + table_row_index, 0, 1, table_column_count, &row.Style(), + NGTableBorders::EdgeSource::kRow, table_writing_direction); + ++table_row_index; + } + } + + // Mark section borders. + // It is tempting to traverse sections at the same time as rows, + // but it would cause precedence errors. + wtf_size_t section_index = 0; + for (NGBlockNode section : grouped_children) { + NGTableBorders::Section section_info = + table_borders->GetSection(section_index); + table_borders->MergeBorders( + section_info.start_row, 0, section_info.row_count, table_column_count, + §ion.Style(), NGTableBorders::EdgeSource::kSection, + table_writing_direction); + ++section_index; + } + + // Mark column borders. + // COL borders have precedence over COLGROUP borders. + // We have to traverse COL first, then COLGROUP. + ColBordersMarker col_borders_marker(table_row_count, table_writing_direction, + *table_borders.get()); + VisitLayoutNGTableColumn( + const_cast<Vector<NGBlockNode>&>(grouped_children.columns), + table_column_count, &col_borders_marker); + ColgroupBordersMarker colgroup_borders_marker( + table_row_count, table_writing_direction, *table_borders.get()); + VisitLayoutNGTableColumn( + const_cast<Vector<NGBlockNode>&>(grouped_children.columns), + table_column_count, &colgroup_borders_marker); + + // Mark table borders. + table_borders->MergeBorders(0, 0, table_row_count, table_column_count, + &table_style, NGTableBorders::EdgeSource::kTable, + table_writing_direction); + + table_borders->ComputeCollapsedTableBorderPadding(table_row_count, + table_column_count); + return table_borders; +} + NGTableBorders::NGTableBorders(const ComputedStyle& table_style, - const NGBoxStrut& table_border, - const NGBoxStrut& table_padding) - : writing_direction_(table_style.GetWritingDirection()), - is_collapsed_(table_style.BorderCollapse() == + const NGBoxStrut& table_border) + : is_collapsed_(table_style.BorderCollapse() == EBorderCollapse::kCollapse) { if (!is_collapsed_) { cached_table_border_ = table_border; - cached_table_padding_ = table_padding; } } @@ -184,18 +457,20 @@ cached_table_border_ = borders; } -NGBoxStrut NGTableBorders::CellBorder(const NGBlockNode& cell, - wtf_size_t row, - wtf_size_t column, - wtf_size_t section) const { +NGBoxStrut NGTableBorders::CellBorder( + const NGBlockNode& cell, + wtf_size_t row, + wtf_size_t column, + wtf_size_t section, + WritingDirectionMode table_writing_direction) const { if (is_collapsed_) { return GetCellBorders(row, column, ClampRowspan(section, row, cell.TableCellRowspan()), ClampColspan(column, cell.TableCellColspan())); } return ComputeBorders( - NGConstraintSpaceBuilder(writing_direction_.GetWritingMode(), - writing_direction_.GetWritingMode(), + NGConstraintSpaceBuilder(table_writing_direction.GetWritingMode(), + table_writing_direction.GetWritingMode(), /* is_new_fc */ false) .ToConstraintSpace(), cell); @@ -204,12 +479,13 @@ // As we are determining the intrinsic size of the table at this stage, // %-padding resolves against an indefinite size. NGBoxStrut NGTableBorders::CellPaddingForMeasure( - const ComputedStyle& cell_style) const { + const ComputedStyle& cell_style, + WritingDirectionMode table_writing_direction) const { if (!cell_style.MayHavePadding()) return NGBoxStrut(); return ComputePadding( - NGConstraintSpaceBuilder(writing_direction_.GetWritingMode(), - writing_direction_.GetWritingMode(), + NGConstraintSpaceBuilder(table_writing_direction.GetWritingMode(), + table_writing_direction.GetWritingMode(), /* is_new_fc */ false) .ToConstraintSpace(), cell_style); @@ -221,6 +497,7 @@ wtf_size_t colspan, const ComputedStyle* source_style, EdgeSource source, + WritingDirectionMode table_writing_direction, wtf_size_t section_index) { DCHECK(is_collapsed_); // Can be 0 in empty table parts. @@ -240,9 +517,10 @@ EnsureCellRowFits(cell_start_row + clamped_rowspan - 1); } else { PhysicalToLogical<EBorderStyle> border_style( - writing_direction_.GetWritingMode(), writing_direction_.Direction(), - source_style->BorderTopStyle(), source_style->BorderRightStyle(), - source_style->BorderBottomStyle(), source_style->BorderLeftStyle()); + table_writing_direction.GetWritingMode(), + table_writing_direction.Direction(), source_style->BorderTopStyle(), + source_style->BorderRightStyle(), source_style->BorderBottomStyle(), + source_style->BorderLeftStyle()); if (border_style.InlineStart() == EBorderStyle::kNone && border_style.InlineEnd() == EBorderStyle::kNone && border_style.BlockStart() == EBorderStyle::kNone && @@ -266,14 +544,21 @@ } } MergeRowAxisBorder(cell_start_row, cell_start_column, clamped_colspan, - source_style, LogicalEdgeSide::kBlockStart); + source_style, + LogicalEdgeToPhysical(LogicalEdgeSide::kBlockStart, + table_writing_direction)); MergeRowAxisBorder(cell_start_row + clamped_rowspan, cell_start_column, - clamped_colspan, source_style, LogicalEdgeSide::kBlockEnd); + clamped_colspan, source_style, + LogicalEdgeToPhysical(LogicalEdgeSide::kBlockEnd, + table_writing_direction)); MergeColumnAxisBorder(cell_start_row, cell_start_column, clamped_rowspan, - source_style, LogicalEdgeSide::kInlineStart); + source_style, + LogicalEdgeToPhysical(LogicalEdgeSide::kInlineStart, + table_writing_direction)); MergeColumnAxisBorder(cell_start_row, cell_start_column + clamped_colspan, clamped_rowspan, source_style, - LogicalEdgeSide::kInlineEnd); + LogicalEdgeToPhysical(LogicalEdgeSide::kInlineEnd, + table_writing_direction)); if (mark_inner_borders) { MarkInnerBordersAsDoNotFill(cell_start_row, cell_start_column, clamped_rowspan, clamped_colspan); @@ -284,8 +569,7 @@ wtf_size_t start_column, wtf_size_t colspan, const ComputedStyle* source_style, - LogicalEdgeSide logical_side) { - EdgeSide physical_side = LogicalToPhysical(logical_side); + EdgeSide physical_side) { EBorderStyle source_border_style = BorderStyle(source_style, physical_side); if (source_border_style == EBorderStyle::kNone) return; @@ -307,8 +591,7 @@ wtf_size_t start_column, wtf_size_t rowspan, const ComputedStyle* source_style, - LogicalEdgeSide logical_side) { - EdgeSide physical_side = LogicalToPhysical(logical_side); + EdgeSide physical_side) { EBorderStyle source_border_style = BorderStyle(source_style, physical_side); if (source_border_style == EBorderStyle::kNone) return;
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h index f43d91c..5f250f3d 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h
@@ -57,23 +57,17 @@ class NGTableBorders : public RefCounted<NGTableBorders> { public: + static scoped_refptr<NGTableBorders> ComputeTableBorders(const NGBlockNode&); + // |table_border_padding| as computed from css values. NGTableBorders(const ComputedStyle& table_style, - const NGBoxStrut& table_border, - const NGBoxStrut& table_padding); + const NGBoxStrut& table_border); #if DCHECK_IS_ON() String DumpEdges(); void ShowEdges(); #endif - // Side of the style the collapsed border belongs to. - enum class LogicalEdgeSide { - kInlineStart, - kInlineEnd, - kBlockStart, - kBlockEnd - }; enum class EdgeSource { kNone, kCell, kRow, kSection, kColumn, kTable }; @@ -140,6 +134,15 @@ } } + static bool HasBorder(const ComputedStyle* style) { + if (!style) + return false; + return style->BorderLeftStyle() != EBorderStyle::kNone || + style->BorderRightStyle() != EBorderStyle::kNone || + style->BorderTopStyle() != EBorderStyle::kNone || + style->BorderBottomStyle() != EBorderStyle::kNone; + } + LayoutUnit BorderWidth(wtf_size_t edge_index) const { return BorderWidth(edges_[edge_index].style.get(), edges_[edge_index].edge_side); @@ -168,20 +171,11 @@ wtf_size_t EdgesPerRow() const { return edges_per_row_; } - NGBoxStrut TableBorderPadding() const { - DCHECK(cached_table_border_); - return *cached_table_border_ + cached_table_padding_; - } - - NGBoxStrut TableBorder() const { + const NGBoxStrut& TableBorder() const { DCHECK(cached_table_border_); return *cached_table_border_; } - WritingDirectionMode TableWritingDirection() const { - return writing_direction_; - } - // This method is necessary because collapsed table's border rect and // visual overflow rect use different borders. // Border rect uses inline start/end of the first row. @@ -195,9 +189,12 @@ NGBoxStrut CellBorder(const NGBlockNode& cell, wtf_size_t row, wtf_size_t column, - wtf_size_t section) const; + wtf_size_t section, + WritingDirectionMode table_writing_direction) const; - NGBoxStrut CellPaddingForMeasure(const ComputedStyle& cell_style) const; + NGBoxStrut CellPaddingForMeasure( + const ComputedStyle& cell_style, + WritingDirectionMode table_writing_direction) const; void ComputeCollapsedTableBorderPadding(wtf_size_t table_row_count, wtf_size_t table_column_count); @@ -210,6 +207,7 @@ wtf_size_t colspan, const ComputedStyle* source_style, EdgeSource source, + WritingDirectionMode table_writing_direction, wtf_size_t section_index = kNotFound); void AddSection(wtf_size_t start_row, wtf_size_t row_count) { @@ -274,97 +272,31 @@ wtf_size_t start_column, wtf_size_t colspan, const ComputedStyle* source_style, - LogicalEdgeSide side); + EdgeSide side); void MergeColumnAxisBorder(wtf_size_t start_row, wtf_size_t start_column, wtf_size_t rowspan, const ComputedStyle* source_style, - LogicalEdgeSide side); + EdgeSide side); void MarkInnerBordersAsDoNotFill(wtf_size_t start_row, wtf_size_t start_column, wtf_size_t rowspan, wtf_size_t colspan); - EdgeSide LogicalToPhysical(LogicalEdgeSide logical_side) const { - // https://www.w3.org/TR/css-writing-modes-4/#logical-to-physical - switch (logical_side) { - case LogicalEdgeSide::kInlineStart: - switch (writing_direction_.GetWritingMode()) { - case WritingMode::kHorizontalTb: - return writing_direction_.Direction() == TextDirection::kLtr - ? EdgeSide::kLeft - : EdgeSide::kRight; - case WritingMode::kVerticalLr: - case WritingMode::kVerticalRl: - case WritingMode::kSidewaysRl: - return writing_direction_.Direction() == TextDirection::kLtr - ? EdgeSide::kTop - : EdgeSide::kBottom; - case WritingMode::kSidewaysLr: - return writing_direction_.Direction() == TextDirection::kLtr - ? EdgeSide::kBottom - : EdgeSide::kTop; - } - case LogicalEdgeSide::kInlineEnd: - switch (writing_direction_.GetWritingMode()) { - case WritingMode::kHorizontalTb: - return writing_direction_.Direction() == TextDirection::kLtr - ? EdgeSide::kRight - : EdgeSide::kLeft; - case WritingMode::kVerticalLr: - case WritingMode::kVerticalRl: - case WritingMode::kSidewaysRl: - return writing_direction_.Direction() == TextDirection::kLtr - ? EdgeSide::kBottom - : EdgeSide::kTop; - case WritingMode::kSidewaysLr: - return writing_direction_.Direction() == TextDirection::kLtr - ? EdgeSide::kTop - : EdgeSide::kBottom; - } - case LogicalEdgeSide::kBlockStart: - switch (writing_direction_.GetWritingMode()) { - case WritingMode::kHorizontalTb: - return EdgeSide::kTop; - case WritingMode::kVerticalLr: - return EdgeSide::kLeft; - case WritingMode::kVerticalRl: - case WritingMode::kSidewaysRl: - return EdgeSide::kRight; - case WritingMode::kSidewaysLr: - return EdgeSide::kLeft; - } - case LogicalEdgeSide::kBlockEnd: - switch (writing_direction_.GetWritingMode()) { - case WritingMode::kHorizontalTb: - return EdgeSide::kBottom; - case WritingMode::kVerticalLr: - return EdgeSide::kRight; - case WritingMode::kVerticalRl: - case WritingMode::kSidewaysRl: - return EdgeSide::kLeft; - case WritingMode::kSidewaysLr: - return EdgeSide::kRight; - } - } - } - Edges edges_; Vector<Section> sections_; wtf_size_t edges_per_row_ = 0; // Table border/padding are expensive to compute for collapsed tables. // We compute them once, and cache them. base::Optional<NGBoxStrut> cached_table_border_; - NGBoxStrut cached_table_padding_; // Collapsed tables use first border to compute inline start/end. // Visual overflow use enclosing rectangle of all borders // to compute inline start/end. // |collapsed_visual_inline_start/end| are the visual rectangle values. LayoutUnit collapsed_visual_inline_start_; LayoutUnit collapsed_visual_inline_end_; - WritingDirectionMode writing_direction_; // Cells cannot extrude beyond table grid size. // Rowspan and colspan sizes must be clamped to enforce this. wtf_size_t last_column_index_ = UINT_MAX;
diff --git a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc index 5069156..99cb30b 100644 --- a/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.cc
@@ -35,10 +35,10 @@ NGTableTypes::CellBlockConstraints* cell_block_constraints, NGTableTypes::RowspanCells* rowspan_cells, NGColspanCellTabulator* colspan_cell_tabulator) { - const WritingMode table_writing_mode = - table_borders.TableWritingDirection().GetWritingMode(); + const WritingDirectionMode table_writing_direction = + row.Style().GetWritingDirection(); - auto CreateCellConstraintSpace = [&column_locations, &table_writing_mode, + auto CreateCellConstraintSpace = [&column_locations, &table_writing_direction, &is_restricted_block_size_table, &cell_percentage_inline_size]( const NGBlockNode& cell, @@ -52,10 +52,9 @@ column_locations[start_column].offset; // TODO(crbug.com/736072): Support orthogonal table cells. // See http://wpt.live/css/css-writing-modes/table-cell-001.html - NGConstraintSpaceBuilder builder(table_writing_mode, + NGConstraintSpaceBuilder builder(table_writing_direction.GetWritingMode(), cell.Style().GetWritingMode(), /* is_new_fc */ true); - DCHECK_EQ(table_writing_mode, cell.Style().GetWritingMode()); builder.SetTextDirection(cell.Style().Direction()); builder.SetTableCellBorders(cell_borders); builder.SetAvailableSize(LogicalSize(cell_inline_size, kIndefiniteSize)); @@ -89,14 +88,15 @@ colspan_cell_tabulator->FindNextFreeColumn(); const ComputedStyle& cell_style = cell.Style(); const NGBoxStrut cell_borders = table_borders.CellBorder( - cell, row_index, colspan_cell_tabulator->CurrentColumn(), - section_index); + cell, row_index, colspan_cell_tabulator->CurrentColumn(), section_index, + table_writing_direction); const NGConstraintSpace cell_constraint_space = CreateCellConstraintSpace( cell, colspan_cell_tabulator->CurrentColumn(), cell_borders); scoped_refptr<const NGLayoutResult> layout_result = cell.Layout(cell_constraint_space); const NGBoxFragment fragment( - table_writing_mode, table_borders.TableWritingDirection().Direction(), + table_writing_direction.GetWritingMode(), + table_writing_direction.Direction(), To<NGPhysicalBoxFragment>(layout_result->PhysicalFragment())); LayoutUnit baseline; @@ -265,6 +265,8 @@ wtf_size_t* row_index, NGTableTypes::CellInlineConstraints* cell_inline_constraints, NGTableTypes::ColspanCells* colspan_cell_inline_constraints) { + WritingDirectionMode table_writing_direction = + section.Style().GetWritingDirection(); NGColspanCellTabulator colspan_cell_tabulator; bool is_first_row = true; for (NGBlockNode row = To<NGBlockNode>(section.FirstChild()); row; @@ -288,9 +290,9 @@ if (!ignore_because_of_fixed_layout) { NGBoxStrut cell_border = table_borders.CellBorder( cell, *row_index, colspan_cell_tabulator.CurrentColumn(), - section_index); - NGBoxStrut cell_padding = - table_borders.CellPaddingForMeasure(cell.Style()); + section_index, table_writing_direction); + NGBoxStrut cell_padding = table_borders.CellPaddingForMeasure( + cell.Style(), table_writing_direction); NGTableTypes::CellInlineConstraint cell_constraint = NGTableTypes::CreateCellInlineConstraint( cell, table_writing_mode, is_fixed_layout, cell_border,
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index bf4be9e..73e1a9f 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -889,7 +889,7 @@ .value_or(DocumentPolicy::ParsedDocumentPolicy{}) .feature_state; frame_->SetRequiredDocumentPolicy(DocumentPolicy::MergeFeatureState( - frame_policy_.required_document_policy, header_required_policy)); + header_required_policy, frame_policy_.required_document_policy)); } document_policy_parsing_messages_.AppendVector(header_logger.GetMessages());
diff --git a/third_party/blink/renderer/core/page/chrome_client.h b/third_party/blink/renderer/core/page/chrome_client.h index 228ba34..aa7bbe6 100644 --- a/third_party/blink/renderer/core/page/chrome_client.h +++ b/third_party/blink/renderer/core/page/chrome_client.h
@@ -100,6 +100,8 @@ class WebDragData; class WebViewImpl; +enum class FullscreenRequestType; + struct DateTimeChooserParameters; struct FrameLoadRequest; struct ViewportDescription; @@ -368,7 +370,7 @@ virtual void EnterFullscreen(LocalFrame&, const FullscreenOptions*, - bool for_cross_process_descendant) {} + FullscreenRequestType) {} virtual void ExitFullscreen(LocalFrame&) {} virtual void FullscreenElementChanged(Element* old_element, Element* new_element) {}
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc index 263d668..05cb3ab 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.cc +++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -238,10 +238,10 @@ const SkBitmap& drag_image, const gfx::Point& drag_image_offset) { WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame); - network::mojom::ReferrerPolicy policy = - web_frame->GetDocument().GetReferrerPolicy(); - web_frame->LocalRootFrameWidget()->StartDragging( - policy, drag_data, mask, drag_image, drag_image_offset); + WebDragData drag = drag_data; + drag.SetReferrerPolicy(web_frame->GetDocument().GetReferrerPolicy()); + web_frame->LocalRootFrameWidget()->StartDragging(drag, mask, drag_image, + drag_image_offset); } bool ChromeClientImpl::AcceptsLoadDrops() const { @@ -806,8 +806,8 @@ void ChromeClientImpl::EnterFullscreen(LocalFrame& frame, const FullscreenOptions* options, - bool for_cross_process_descendant) { - web_view_->EnterFullscreen(frame, options, for_cross_process_descendant); + FullscreenRequestType request_type) { + web_view_->EnterFullscreen(frame, options, request_type); } void ChromeClientImpl::ExitFullscreen(LocalFrame& frame) {
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.h b/third_party/blink/renderer/core/page/chrome_client_impl.h index b578c0a..12b9513 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.h +++ b/third_party/blink/renderer/core/page/chrome_client_impl.h
@@ -190,7 +190,7 @@ void EnterFullscreen(LocalFrame&, const FullscreenOptions*, - bool for_cross_process_descendant) override; + FullscreenRequestType) override; void ExitFullscreen(LocalFrame&) override; void FullscreenElementChanged(Element* old_element, Element* new_element) override;
diff --git a/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc b/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc index 79654db..5b47884 100644 --- a/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/main_thread_scrolling_reasons_test.cc
@@ -397,14 +397,17 @@ cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText); } +#if 0 +// TODO(crbug.com/1113269): Temporarily disabled. TEST_F(NonCompositedMainThreadScrollingReasonsTest, ClipTest) { TestNonCompositedReasons("clip", cc::MainThreadScrollingReason::kNotScrollingOnMain); } +#endif TEST_F(NonCompositedMainThreadScrollingReasonsTest, ClipPathTest) { - TestNonCompositedReasons("clip-path", - cc::MainThreadScrollingReason::kNotScrollingOnMain); + TestNonCompositedReasons( + "clip-path", cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText); } TEST_F(NonCompositedMainThreadScrollingReasonsTest, BoxShadowTest) { @@ -424,8 +427,9 @@ } TEST_F(NonCompositedMainThreadScrollingReasonsTest, BorderRadiusTest) { - TestNonCompositedReasons("border-radius", - cc::MainThreadScrollingReason::kNotScrollingOnMain); + TestNonCompositedReasons( + "border-radius", + cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText); } TEST_F(NonCompositedMainThreadScrollingReasonsTest,
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 0857f7e..a00feb2 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -1834,6 +1834,8 @@ // embedded in an iframe, by loading a document with an iframe that has a // scroller with an inset box shadow, and ensuring that scroller generates a // compositor scroll node with the proper noncomposited reasons set. +// TODO(crbug.com/1113269): Temporarily disabled. +#if 0 TEST_P(UnifiedScrollingSimTest, ScrollNodeForEmbeddedScrollers) { SimRequest request("https://example.com/test.html", "text/html"); LoadURL("https://example.com/test.html"); @@ -1914,6 +1916,7 @@ ->property_trees() ->scroll_tree.IsComposited(*child_scroll_node)); } +#endif // Similar to the above test, but for deeper nesting iframes to ensure we // generate scroll nodes that are deeper than the main frame's children.
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc index 587595d..042c6038 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc
@@ -1623,6 +1623,8 @@ UpdateAllLifecyclePhasesForTest(); + ASSERT_EQ(kPaintsIntoGroupedBacking, squashed->GetCompositingState()); + // 100px down from squashing's main graphics layer. EXPECT_EQ(IntPoint(0, 100), squashed->GraphicsLayerBacking()->GetOffsetFromTransformNode());
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc index 41808e0..8dec2a15 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
@@ -29,7 +29,10 @@ PaintLayer* root_layer, PaintLayer* compositing_inputs_root) : root_layer_(root_layer), - compositing_inputs_root_(compositing_inputs_root) {} + compositing_inputs_root_(compositing_inputs_root) { + if (!RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) + geometry_map_.emplace(); +} CompositingInputsUpdater::~CompositingInputsUpdater() = default; @@ -88,7 +91,8 @@ // update this information). ApplyAncestorInfoToSelfAndAncestorsRecursively(layer->Parent(), update_type, info); - geometry_map_.PushMappingsToAncestor(layer, layer->Parent()); + if (!RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) + geometry_map_->PushMappingsToAncestor(layer, layer->Parent()); UpdateAncestorInfo(layer, update_type, info); if (layer != compositing_inputs_root_ && (layer->IsRootLayer() || layer->GetLayoutObject().HasOverflowClip())) @@ -140,7 +144,8 @@ // UpdateAncestorInfo has been already computed in ApplyAncestorInfo() for // layers from root_layer_ down to compositing_inputs_root_ both included. if (layer != root_layer_ && layer != compositing_inputs_root_) { - geometry_map_.PushMappingsToAncestor(layer, layer->Parent()); + if (!RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) + geometry_map_->PushMappingsToAncestor(layer, layer->Parent()); UpdateAncestorInfo(layer, update_type, info); } if (layer->IsRootLayer() || layout_object.HasOverflowClip()) @@ -215,7 +220,8 @@ if (!recursion_blocked_by_display_lock) layer->ClearChildNeedsCompositingInputsUpdate(); - geometry_map_.PopMappingsToAncestor(layer->Parent()); + if (!RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) + geometry_map_->PopMappingsToAncestor(layer->Parent()); if (layer->SelfPaintingStatusChanged()) { layer->ClearSelfPaintingStatusChanged(); @@ -441,51 +447,54 @@ PaintLayer::AncestorDependentCompositingInputs properties; LayoutBoxModelObject& layout_object = layer->GetLayoutObject(); - // The final value for |unclipped_absolute_bounding_box| needs to be - // in absolute, unscrolled space, without any scroll applied. - properties.unclipped_absolute_bounding_box = - EnclosingIntRect(geometry_map_.AbsoluteRect( - layer->BoundingBoxForCompositingOverlapTest())); + if (!RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) { + // The final value for |unclipped_absolute_bounding_box| needs to be + // in absolute, unscrolled space, without any scroll applied. - bool affected_by_scroll = root_layer_->GetScrollableArea() && - layer->IsAffectedByScrollOf(root_layer_); + properties.unclipped_absolute_bounding_box = + EnclosingIntRect(geometry_map_->AbsoluteRect( + layer->BoundingBoxForCompositingOverlapTest())); - // At ths point, |unclipped_absolute_bounding_box| is in viewport space. - // To convert to absolute space, add scroll offset for non-fixed layers. - if (affected_by_scroll) { - properties.unclipped_absolute_bounding_box.Move( - RoundedIntSize(root_layer_->GetScrollableArea()->GetScrollOffset())); - } + bool affected_by_scroll = root_layer_->GetScrollableArea() && + layer->IsAffectedByScrollOf(root_layer_); - // For sticky-positioned elements, the scroll offset is sometimes included and - // sometimes not, depending on whether the sticky element is affixed or still - // scrolling. This makes caching difficult, as compared to Fixed position - // elements which have consistent behavior. So we disable caching for - // sticky-positioned subtrees. - ClipRectsCacheSlot cache_slot = info.is_under_position_sticky - ? kUncachedClipRects + // At ths point, |unclipped_absolute_bounding_box| is in viewport space. + // To convert to absolute space, add scroll offset for non-fixed layers. + if (affected_by_scroll) { + properties.unclipped_absolute_bounding_box.Move( + RoundedIntSize(root_layer_->GetScrollableArea()->GetScrollOffset())); + } + + // For sticky-positioned elements, the scroll offset is sometimes included + // and sometimes not, depending on whether the sticky element is affixed or + // still scrolling. This makes caching difficult, as compared to Fixed + // position elements which have consistent behavior. So we disable caching + // for sticky-positioned subtrees. + ClipRectsCacheSlot cache_slot = + info.is_under_position_sticky ? kUncachedClipRects : kAbsoluteClipRectsIgnoringViewportClip; - ClipRect clip_rect; - layer->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper) - .CalculateBackgroundClipRect( - ClipRectsContext(root_layer_, - &root_layer_->GetLayoutObject().FirstFragment(), - cache_slot, kIgnorePlatformOverlayScrollbarSize, - kIgnoreOverflowClipAndScroll), - clip_rect); - IntRect snapped_clip_rect = PixelSnappedIntRect(clip_rect.Rect()); - // |snapped_clip_rect| is in absolute space space, but with scroll applied. - // To convert to absolute, unscrolled space, subtract scroll offsets for - // fixed layers. - if (root_layer_->GetScrollableArea() && !affected_by_scroll) { - snapped_clip_rect.Move( - RoundedIntSize(-root_layer_->GetScrollableArea()->GetScrollOffset())); - } + ClipRect clip_rect; + layer->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper) + .CalculateBackgroundClipRect( + ClipRectsContext(root_layer_, + &root_layer_->GetLayoutObject().FirstFragment(), + cache_slot, kIgnorePlatformOverlayScrollbarSize, + kIgnoreOverflowClipAndScroll), + clip_rect); + IntRect snapped_clip_rect = PixelSnappedIntRect(clip_rect.Rect()); + // |snapped_clip_rect| is in absolute space space, but with scroll applied. + // To convert to absolute, unscrolled space, subtract scroll offsets for + // fixed layers. + if (root_layer_->GetScrollableArea() && !affected_by_scroll) { + snapped_clip_rect.Move( + RoundedIntSize(-root_layer_->GetScrollableArea()->GetScrollOffset())); + } - properties.clipped_absolute_bounding_box = - properties.unclipped_absolute_bounding_box; - properties.clipped_absolute_bounding_box.Intersect(snapped_clip_rect); + properties.clipped_absolute_bounding_box = + properties.unclipped_absolute_bounding_box; + properties.clipped_absolute_bounding_box.Intersect(snapped_clip_rect); + } const PaintLayer* parent = layer->Parent(); properties.opacity_ancestor =
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h index d965351..5f351fd 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h +++ b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h
@@ -88,7 +88,7 @@ bool NeedsPaintOffsetTranslationForCompositing(PaintLayer*); - LayoutGeometryMap geometry_map_; + base::Optional<LayoutGeometryMap> geometry_map_; PaintLayer* root_layer_; PaintLayer* compositing_inputs_root_; };
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater_test.cc index 51eb893..e011815 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater_test.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater_test.cc
@@ -141,10 +141,18 @@ ->SetNeedsCompositingInputsUpdate(); UpdateAllLifecyclePhasesForTest(); - EXPECT_EQ(IntRect(8, 8, 200, 200), - target->Layer()->ClippedAbsoluteBoundingBox()); - EXPECT_EQ(IntRect(8, 8, 200, 200), - target->Layer()->UnclippedAbsoluteBoundingBox()); + if (RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) { + EXPECT_EQ(IntRect(8, 33, 200, 200), + target->Layer()->ClippedAbsoluteBoundingBox()); + EXPECT_EQ(IntRect(8, 33, 200, 200), + target->Layer()->UnclippedAbsoluteBoundingBox()); + + } else { + EXPECT_EQ(IntRect(8, 8, 200, 200), + target->Layer()->ClippedAbsoluteBoundingBox()); + EXPECT_EQ(IntRect(8, 8, 200, 200), + target->Layer()->UnclippedAbsoluteBoundingBox()); + } } TEST_F(CompositingInputsUpdaterTest, ClipPathAncestor) {
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc index c983a14..146072d 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
@@ -304,6 +304,8 @@ if (can_be_composited) reasons_to_composite |= direct_reasons; + const LayoutObject& layout_object = layer->GetLayoutObject(); + // Next, accumulate reasons related to overlap. // If overlap testing is used, this reason will be overridden. If overlap // testing is not used, we must assume we overlap if there is anything @@ -323,7 +325,7 @@ // should opt in. Unfortunately we can't easily remove from the list // while we're iterating, so we have to store it for later removal. if (unclipped_descendant->GetLayoutObject().ContainingBlock() == - &layer->GetLayoutObject()) { + &layout_object) { unclipped_descendants_to_remove.push_back(i); continue; } @@ -350,16 +352,19 @@ IntRect abs_bounds = use_clipped_bounding_rect ? layer->ClippedAbsoluteBoundingBox() : layer->UnclippedAbsoluteBoundingBox(); - PaintLayer* root_layer = layout_view_.Layer(); - // |abs_bounds| does not include root scroller offset. For the purposes - // of overlap, this only matters for fixed-position objects, and their - // relative position to other elements. Therefore, it's still correct to, - // instead of adding scroll to all non-fixed elements, add a reverse scroll - // to ones that are fixed. - if (root_layer->GetScrollableArea() && - !layer->IsAffectedByScrollOf(root_layer)) { - abs_bounds.Move( - RoundedIntSize(root_layer->GetScrollableArea()->GetScrollOffset())); + + if (!RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) { + PaintLayer* root_layer = layout_view_.Layer(); + // |abs_bounds| does not include root scroller offset. For the purposes + // of overlap, this only matters for fixed-position objects, and their + // relative position to other elements. Therefore, it's still correct to, + // instead of adding scroll to all non-fixed elements, add a reverse scroll + // to ones that are fixed. + if (root_layer->GetScrollableArea() && + !layer->IsAffectedByScrollOf(root_layer)) { + abs_bounds.Move( + RoundedIntSize(root_layer->GetScrollableArea()->GetScrollOffset())); + } } absolute_descendant_bounding_box = abs_bounds;
diff --git a/third_party/blink/renderer/core/paint/paint_event.h b/third_party/blink/renderer/core/paint/paint_event.h index 72a6100..5662e4b 100644 --- a/third_party/blink/renderer/core/paint/paint_event.h +++ b/third_party/blink/renderer/core/paint/paint_event.h
@@ -11,7 +11,6 @@ // SwapPromise swap times for. enum class PaintEvent { kFirstPaint, - kFirstPaintAfterBackForwardCacheRestore, kFirstContentfulPaint, kProvisionalFirstMeaningfulPaint, kFirstImagePaint,
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index 839b7c4..72ae58a 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -48,7 +48,6 @@ #include "base/allocator/partition_allocator/partition_alloc.h" #include "base/containers/adapters.h" -#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/css/css_property_names.h" @@ -166,6 +165,7 @@ previous_paint_result_(kFullyPainted), needs_paint_phase_descendant_outlines_(false), needs_paint_phase_float_(false), + has_descendant_with_clip_path_(false), has_non_isolated_descendant_with_blend_mode_(false), has_fixed_position_descendant_(false), has_sticky_position_descendant_(false), @@ -612,6 +612,7 @@ has_non_isolated_descendant_with_blend_mode_; has_visible_descendant_ = false; has_non_isolated_descendant_with_blend_mode_ = false; + has_descendant_with_clip_path_ = false; has_fixed_position_descendant_ = false; has_sticky_position_descendant_ = false; has_non_contained_absolute_position_descendant_ = false; @@ -645,6 +646,9 @@ child->HasNonIsolatedDescendantWithBlendMode()) || child_style.HasBlendMode(); + has_descendant_with_clip_path_ |= child->HasDescendantWithClipPath() || + child->GetLayoutObject().HasClipPath(); + has_fixed_position_descendant_ |= child->HasFixedPositionDescendant() || child_style.GetPosition() == EPosition::kFixed; @@ -1086,6 +1090,28 @@ ancestor->child_needs_compositing_inputs_update_ = true; } +const IntRect PaintLayer::ClippedAbsoluteBoundingBox() const { + if (RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) { + PhysicalRect mapping_rect = BoundingBoxForCompositingOverlapTest(); + GetLayoutObject().MapToVisualRectInAncestorSpace( + GetLayoutObject().View(), mapping_rect, kUseGeometryMapper); + return EnclosingIntRect(mapping_rect); + } else { + return GetAncestorDependentCompositingInputs() + .clipped_absolute_bounding_box; + } +} +const IntRect PaintLayer::UnclippedAbsoluteBoundingBox() const { + if (RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) { + return EnclosingIntRect(GetLayoutObject().LocalToAbsoluteRect( + BoundingBoxForCompositingOverlapTest(), + kUseGeometryMapperMode | kIgnoreScrollOffset)); + } else { + return GetAncestorDependentCompositingInputs() + .unclipped_absolute_bounding_box; + } +} + void PaintLayer::SetNeedsCompositingInputsUpdateInternal() { if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) return; @@ -2620,32 +2646,29 @@ style.BackdropFilter().MapRect(FloatRect(bounding_box))); } - if (FixedToViewport()) { - if (base::FeatureList::IsEnabled(features::kMaxOverlapBoundsForFixed) && - !bounding_box.IsEmpty()) { - DCHECK_EQ(style.GetPosition(), EPosition::kFixed); - // Note that we only expand the bounding box for overlap testing when the - // fixed's containing block is the viewport. This keeps us from expanding - // the bounds when the fixed is a child of an ancestor with transform, - // filters, etc. and the fixed is no longer scroll position dependent. + if (FixedToViewport() && !bounding_box.IsEmpty()) { + DCHECK_EQ(style.GetPosition(), EPosition::kFixed); + // Note that we only expand the bounding box for overlap testing when the + // fixed's containing block is the viewport. This keeps us from expanding + // the bounds when the fixed is a child of an ancestor with transform, + // filters, etc. and the fixed is no longer scroll position dependent. - // Expand the bounding box by the amount that scrolling the - // viewport can expand the area that this fixed-pos element could - // cover. Compute how much we could still scroll in each direction. - // |max_scroll_delta| is the amount we could still scroll in - // increasing offset direction. |min_scroll_delta| is the amount we - // can still scroll in a decreasing scroll offset direction. - PaintLayerScrollableArea* scrollable_area = - GetLayoutObject().View()->GetScrollableArea(); - ScrollOffset current_scroll_offset = scrollable_area->GetScrollOffset(); - ScrollOffset max_scroll_delta = - scrollable_area->MaximumScrollOffset() - current_scroll_offset; - ScrollOffset min_scroll_delta = - current_scroll_offset - scrollable_area->MinimumScrollOffset(); - bounding_box.Expand(LayoutRectOutsets( - min_scroll_delta.Height(), max_scroll_delta.Width(), - max_scroll_delta.Height(), min_scroll_delta.Width())); - } + // Expand the bounding box by the amount that scrolling the + // viewport can expand the area that this fixed-pos element could + // cover. Compute how much we could still scroll in each direction. + // |max_scroll_delta| is the amount we could still scroll in + // increasing offset direction. |min_scroll_delta| is the amount we + // can still scroll in a decreasing scroll offset direction. + PaintLayerScrollableArea* scrollable_area = + GetLayoutObject().View()->GetScrollableArea(); + ScrollOffset current_scroll_offset = scrollable_area->GetScrollOffset(); + ScrollOffset max_scroll_delta = + scrollable_area->MaximumScrollOffset() - current_scroll_offset; + ScrollOffset min_scroll_delta = + current_scroll_offset - scrollable_area->MinimumScrollOffset(); + bounding_box.Expand( + LayoutRectOutsets(min_scroll_delta.Height(), max_scroll_delta.Width(), + max_scroll_delta.Height(), min_scroll_delta.Width())); } return bounding_box; }
diff --git a/third_party/blink/renderer/core/paint/paint_layer.h b/third_party/blink/renderer/core/paint/paint_layer.h index 7fc945ea..8db75e8 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.h +++ b/third_party/blink/renderer/core/paint/paint_layer.h
@@ -852,16 +852,10 @@ return EnsureAncestorDependentCompositingInputs(); } - // These two do not include any applicable scroll offset of the - // root PaintLayer. - const IntRect& ClippedAbsoluteBoundingBox() const { - return GetAncestorDependentCompositingInputs() - .clipped_absolute_bounding_box; - } - const IntRect& UnclippedAbsoluteBoundingBox() const { - return GetAncestorDependentCompositingInputs() - .unclipped_absolute_bounding_box; - } + // These two do not include any applicable scroll offset of the + // root PaintLayer, unless CompositingOptimizationsEnabled is on. + const IntRect ClippedAbsoluteBoundingBox() const; + const IntRect UnclippedAbsoluteBoundingBox() const; const PaintLayer* OpacityAncestor() const { return GetAncestorDependentCompositingInputs().opacity_ancestor; @@ -901,6 +895,11 @@ const PaintLayer* MaskAncestor() const { return GetAncestorDependentCompositingInputs().mask_ancestor; } + // TODO(crbug.com/1113269): Temporary. + bool HasDescendantWithClipPath() const { + DCHECK(!needs_descendant_dependent_flags_update_); + return has_descendant_with_clip_path_; + } bool HasFixedPositionDescendant() const { DCHECK(!needs_descendant_dependent_flags_update_); return has_fixed_position_descendant_; @@ -1354,6 +1353,9 @@ unsigned needs_paint_phase_descendant_outlines_ : 1; unsigned needs_paint_phase_float_ : 1; + // TODO(crbug.com/1113269): Temporary. + unsigned has_descendant_with_clip_path_ : 1; + // These bitfields are part of ancestor/descendant dependent compositing // inputs. unsigned has_non_isolated_descendant_with_blend_mode_ : 1;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc b/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc index dc220a7f..b547f76 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc
@@ -429,6 +429,8 @@ // logic does not apply. if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) return; + if (RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) + return; SetBodyInnerHTML(R"HTML( <style> @@ -464,6 +466,8 @@ // logic does not apply. if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) return; + if (RuntimeEnabledFeatures::CompositingOptimizationsEnabled()) + return; SetBodyInnerHTML(R"HTML( <style>
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index f3bd433..a12399b 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -2441,15 +2441,12 @@ LocalFrame* frame = GetLayoutBox()->GetFrame(); if (frame && frame->View()) { LocalFrameView* view = frame->View(); - // When kMaxOverlapBoundsForFixed is enabled, the maximum possible - // overlap (for all possible scroll offsets) of the fixed content has - // been included in the overlap test, so we can skip the compositing - // update on scroll changes for fixed content. - bool requires_compositing_inputs_update = - !base::FeatureList::IsEnabled(features::kMaxOverlapBoundsForFixed) - ? view->HasViewportConstrainedObjects() - : view->HasStickyViewportConstrainedObject(); - if (requires_compositing_inputs_update) + // The maximum possible overlap (for all possible scroll offsets) of the + // fixed content has been included in the overlap test, so we can skip + // the compositing update on scroll changes for fixed content. + // Sticky-pos content still needs a compositing inputs update for + // overlap testing. + if (view->HasStickyViewportConstrainedObject()) Layer()->SetNeedsCompositingInputsUpdate(); } } @@ -2547,6 +2544,18 @@ return needs_composited_scrolling; } +static bool IsOpaqueForLCDText(const PaintLayer& layer, const LayoutBox& box) { + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) + return box.TextIsKnownToBeOnOpaqueBackground(); + + // TODO(crbug.com/1113269): TextIsKnownToBeOnOpaqueBackground() is temporarily + // replaced with BackgroundIsKnownToBeOpaqueInRect() to evaluate the + // performance improvement. Will restore after 1 or 2 canary builds. + DisableCompositingQueryAsserts disabler; + return layer.BackgroundIsKnownToBeOpaqueInRect(box.PhysicalPaddingBoxRect(), + true); +} + bool PaintLayerScrollableArea::ComputeNeedsCompositedScrollingInternal( BackgroundPaintLocation background_paint_location_if_composited, bool force_prefer_compositing_to_lcd_text) { @@ -2592,7 +2601,8 @@ cc::MainThreadScrollingReason::kHasTransformAndLCDText; needs_composited_scrolling = false; } - if (!box->TextIsKnownToBeOnOpaqueBackground()) { + + if (!IsOpaqueForLCDText(*layer_, *box)) { non_composited_main_thread_scrolling_reasons_ |= cc::MainThreadScrollingReason::kNotOpaqueForTextAndLCDText; needs_composited_scrolling = false; @@ -2606,6 +2616,15 @@ } } + // TODO(crbug.com/1113269): Temporary. + if (box->HasClip() || layer_->HasDescendantWithClipPath() || + !!layer_->ClipPathAncestor()) { + non_composited_main_thread_scrolling_reasons_ |= + // Just a random flag to disable composited scrolling. + cc::MainThreadScrollingReason::kCantPaintScrollingBackgroundAndLCDText; + needs_composited_scrolling = false; + } + DCHECK(!(non_composited_main_thread_scrolling_reasons_ & ~cc::MainThreadScrollingReason::kNonCompositedReasons)); return needs_composited_scrolling;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc index c7bb3b7..7b3bed8 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -319,7 +319,8 @@ GetBackgroundPaintLocation("scroller15")); // css-clip doesn't affect background paint location. - EXPECT_EQ(kBackgroundPaintInScrollingContents, + // TODO(crbug.com/1113269): Temporary. + EXPECT_EQ(kBackgroundPaintInGraphicsLayer, GetBackgroundPaintLocation("css-clip")); // #scroller17 can only be painted once as it is translucent, and it must @@ -888,10 +889,7 @@ } TEST_P(PaintLayerScrollableAreaTest, - ScrollWithFixedNeedsCompositingInputsUpdate) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatureState(blink::features::kMaxOverlapBoundsForFixed, - false); + ScrollWithStickyNeedsCompositingInputsUpdate) { SetBodyInnerHTML(R"HTML( <style> * { @@ -901,23 +899,22 @@ height: 610px; width: 820px; } - #fixed { + #sticky { height: 10px; left: 50px; - position: fixed; + position: sticky; top: 50px; width: 10px; } </style> - <div id=fixed></div> + <div id=sticky></div> )HTML"); auto* scrollable_area = GetLayoutView().GetScrollableArea(); EXPECT_EQ(FloatSize(0, 0), scrollable_area->GetScrollOffset()); - // Changing the scroll offset requires a compositing inputs update when - // kMaxOverlapBoundsForFixed is disabled as changing the scroll offset can - // require updates to overlap testing. + // Changing the scroll offset requires a compositing inputs update to rerun + // overlap testing. scrollable_area->SetScrollOffset(ScrollOffset(0, 1), mojom::blink::ScrollType::kProgrammatic); if (GetParam() & kCompositeAfterPaint) { @@ -932,9 +929,6 @@ TEST_P(PaintLayerScrollableAreaTest, ScrollWithFixedDoesNotNeedCompositingInputsUpdate) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatureState(blink::features::kMaxOverlapBoundsForFixed, - true); SetBodyInnerHTML(R"HTML( <style> * {
diff --git a/third_party/blink/renderer/core/paint/paint_layer_test.cc b/third_party/blink/renderer/core/paint/paint_layer_test.cc index 86f7ad95..0e4b65e 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -4,9 +4,7 @@ #include "third_party/blink/renderer/core/paint/paint_layer.h" -#include "base/test/scoped_feature_list.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/core/dom/pseudo_element.h" #include "third_party/blink/renderer/core/html/html_iframe_element.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" @@ -2604,52 +2602,7 @@ EXPECT_NE(nullptr, paint_layer); } -TEST_P(PaintLayerTest, FixedDoesNotUseExpandedBoundingBoxForOverlap) { - // TODO(samfort): Remove this test after kMaxOverlapBoundsForFixed ships. - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatureState(blink::features::kMaxOverlapBoundsForFixed, - false); - - SetBodyInnerHTML(R"HTML( - <style> - * { - margin: 0; - } - body { - height: 610px; - width: 820px; - } - #fixed { - height: 10px; - left: 50px; - position: fixed; - top: 50px; - width: 10px; - } - </style> - <div id=fixed></div> - )HTML"); - - PaintLayer* fixed = - ToLayoutBoxModelObject(GetLayoutObjectByElementId("fixed"))->Layer(); - EXPECT_EQ(fixed->BoundingBoxForCompositingOverlapTest(), - PhysicalRect(0, 0, 10, 10)); - - // Modify the scroll offset and ensure that the bounding box is still the - // same. - GetDocument().View()->LayoutViewport()->SetScrollOffset( - ScrollOffset(10, 10), mojom::blink::ScrollType::kProgrammatic); - UpdateAllLifecyclePhasesForTest(); - - EXPECT_EQ(fixed->BoundingBoxForCompositingOverlapTest(), - PhysicalRect(0, 0, 10, 10)); -} - TEST_P(PaintLayerTest, FixedUsesExpandedBoundingBoxForOverlap) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatureState(blink::features::kMaxOverlapBoundsForFixed, - true); - SetBodyInnerHTML(R"HTML( <style> * { @@ -2686,10 +2639,6 @@ } TEST_P(PaintLayerTest, FixedInScrollerUsesExpandedBoundingBoxForOverlap) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatureState(blink::features::kMaxOverlapBoundsForFixed, - true); - SetBodyInnerHTML(R"HTML( <style> * { @@ -2752,10 +2701,6 @@ } TEST_P(PaintLayerTest, FixedUnderTransformDoesNotExpandBoundingBoxForOverlap) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatureState(blink::features::kMaxOverlapBoundsForFixed, - true); - SetBodyInnerHTML(R"HTML( <style> .anim { @@ -2800,10 +2745,6 @@ } TEST_P(PaintLayerTest, NestedFixedUsesExpandedBoundingBoxForOverlap) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatureState(blink::features::kMaxOverlapBoundsForFixed, - true); - SetBodyInnerHTML(R"HTML( <style> * {
diff --git a/third_party/blink/renderer/core/paint/paint_timing.cc b/third_party/blink/renderer/core/paint/paint_timing.cc index 3aaf3158..9c5e52f 100644 --- a/third_party/blink/renderer/core/paint/paint_timing.cc +++ b/third_party/blink/renderer/core/paint/paint_timing.cc
@@ -211,6 +211,13 @@ WrapCrossThreadWeakPersistent(this), event)); } +void PaintTiming::RegisterNotifyFirstPaintAfterBackForwardCacheRestoreSwapTime( + size_t index) { + RegisterNotifySwapTime(CrossThreadBindOnce( + &PaintTiming::ReportFirstPaintAfterBackForwardCacheRestoreSwapTime, + WrapCrossThreadWeakPersistent(this), index)); +} + void PaintTiming::RegisterNotifySwapTime(ReportTimeCallback callback) { // ReportSwapTime will queue a swap-promise, the callback is called when the // compositor submission of the current render frame completes or fails to @@ -242,9 +249,6 @@ case PaintEvent::kFirstPaint: SetFirstPaintSwap(timestamp); return; - case PaintEvent::kFirstPaintAfterBackForwardCacheRestore: - SetFirstPaintAfterBackForwardCacheRestoreSwap(timestamp); - return; case PaintEvent::kFirstContentfulPaint: SetFirstContentfulPaintSwap(timestamp); return; @@ -259,6 +263,15 @@ } } +void PaintTiming::ReportFirstPaintAfterBackForwardCacheRestoreSwapTime( + size_t index, + WebSwapResult result, + base::TimeTicks timestamp) { + DCHECK(IsMainThread()); + ReportSwapResultHistogram(result); + SetFirstPaintAfterBackForwardCacheRestoreSwap(timestamp, index); +} + void PaintTiming::SetFirstPaintSwap(base::TimeTicks stamp) { DCHECK(first_paint_swap_.is_null()); first_paint_swap_ = stamp; @@ -306,12 +319,12 @@ } void PaintTiming::SetFirstPaintAfterBackForwardCacheRestoreSwap( - base::TimeTicks stamp) { - // The last element is already allocated when the page is restored from the - // cache. - DCHECK(!first_paints_after_back_forward_cache_restore_swap_.IsEmpty()); - DCHECK(first_paints_after_back_forward_cache_restore_swap_.back().is_null()); - first_paints_after_back_forward_cache_restore_swap_.back() = stamp; + base::TimeTicks stamp, + size_t index) { + // The elements are allocated when the page is restored from the cache. + DCHECK_GE(first_paints_after_back_forward_cache_restore_swap_.size(), index); + DCHECK(first_paints_after_back_forward_cache_restore_swap_[index].is_null()); + first_paints_after_back_forward_cache_restore_swap_[index] = stamp; NotifyPaintTimingChanged(); } @@ -326,9 +339,10 @@ void PaintTiming::OnRestoredFromBackForwardCache() { // Allocate the last element with 0, which indicates that the first paint // after this navigation doesn't happen yet. + size_t index = first_paints_after_back_forward_cache_restore_swap_.size(); first_paints_after_back_forward_cache_restore_swap_.push_back( base::TimeTicks()); - RegisterNotifySwapTime(PaintEvent::kFirstPaintAfterBackForwardCacheRestore); + RegisterNotifyFirstPaintAfterBackForwardCacheRestoreSwapTime(index); } } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/paint_timing.h b/third_party/blink/renderer/core/paint/paint_timing.h index 0df1001..e44bd67 100644 --- a/third_party/blink/renderer/core/paint/paint_timing.h +++ b/third_party/blink/renderer/core/paint/paint_timing.h
@@ -130,6 +130,10 @@ void RegisterNotifySwapTime(ReportTimeCallback); void ReportSwapTime(PaintEvent, WebSwapResult, base::TimeTicks timestamp); + void ReportFirstPaintAfterBackForwardCacheRestoreSwapTime( + size_t index, + WebSwapResult, + base::TimeTicks timestamp); void ReportSwapResultHistogram(WebSwapResult); @@ -165,9 +169,15 @@ void SetFirstContentfulPaintSwap(base::TimeTicks stamp); void SetFirstImagePaintSwap(base::TimeTicks stamp); - void SetFirstPaintAfterBackForwardCacheRestoreSwap(base::TimeTicks stamp); + // When quickly navigating back and forward between the pages in the cache + // paint events might race with navigations. Pass explicit bfcache restore + // index to avoid confusing the data from different navigations. + void SetFirstPaintAfterBackForwardCacheRestoreSwap(base::TimeTicks stamp, + size_t index); void RegisterNotifySwapTime(PaintEvent); + void RegisterNotifyFirstPaintAfterBackForwardCacheRestoreSwapTime( + size_t index); base::TimeTicks FirstPaintRendered() const { return first_paint_; }
diff --git a/third_party/blink/renderer/core/probe/core_probes.pidl b/third_party/blink/renderer/core/probe/core_probes.pidl index 0804815..b6276f8 100644 --- a/third_party/blink/renderer/core/probe/core_probes.pidl +++ b/third_party/blink/renderer/core/probe/core_probes.pidl
@@ -170,7 +170,7 @@ void DidCloseAudioContext(Document*); void DidResumeAudioContext(Document*); void DidSuspendAudioContext(Document*); - void ProduceCompilationCache(LocalFrame*, const ScriptSourceCode& source, v8::Local<v8::Script> script); + void ProduceCompilationCache(CoreProbeSink*, const ScriptSourceCode& source, v8::Local<v8::Script> script); void ConsumeCompilationCache(ExecutionContext*, const ScriptSourceCode& source, v8::ScriptCompiler::CachedData** cached_data); void NodeCreated([Keep] Node* node); void PortalRemoteFrameCreated(Document*, HTMLPortalElement* portal_element);
diff --git a/third_party/blink/renderer/core/style/grid_positions_resolver.cc b/third_party/blink/renderer/core/style/grid_positions_resolver.cc index e3be95b..41ada54 100644 --- a/third_party/blink/renderer/core/style/grid_positions_resolver.cc +++ b/third_party/blink/renderer/core/style/grid_positions_resolver.cc
@@ -163,16 +163,15 @@ } static void InitialAndFinalPositionsFromStyle( - const LayoutBox& grid_item, + const ComputedStyle& grid_item_style, GridTrackSizingDirection direction, GridPosition& initial_position, GridPosition& final_position) { initial_position = (direction == kForColumns) - ? grid_item.Style()->GridColumnStart() - : grid_item.Style()->GridRowStart(); - final_position = (direction == kForColumns) - ? grid_item.Style()->GridColumnEnd() - : grid_item.Style()->GridRowEnd(); + ? grid_item_style.GridColumnStart() + : grid_item_style.GridRowStart(); + final_position = (direction == kForColumns) ? grid_item_style.GridColumnEnd() + : grid_item_style.GridRowEnd(); // We must handle the placement error handling code here instead of in the // StyleAdjuster because we don't want to overwrite the specified values. @@ -353,11 +352,11 @@ } size_t GridPositionsResolver::SpanSizeForAutoPlacedItem( - const LayoutBox& grid_item, + const ComputedStyle& grid_item_style, GridTrackSizingDirection direction) { GridPosition initial_position, final_position; - InitialAndFinalPositionsFromStyle(grid_item, direction, initial_position, - final_position); + InitialAndFinalPositionsFromStyle(grid_item_style, direction, + initial_position, final_position); // This method will only be used when both positions need to be resolved // against the opposite one. @@ -460,12 +459,12 @@ GridSpan GridPositionsResolver::ResolveGridPositionsFromStyle( const ComputedStyle& grid_container_style, - const LayoutBox& grid_item, + const ComputedStyle& grid_item_style, GridTrackSizingDirection direction, size_t auto_repeat_tracks_count) { GridPosition initial_position, final_position; - InitialAndFinalPositionsFromStyle(grid_item, direction, initial_position, - final_position); + InitialAndFinalPositionsFromStyle(grid_item_style, direction, + initial_position, final_position); GridPositionSide initial_side = InitialPositionSide(direction); GridPositionSide final_side = FinalPositionSide(direction);
diff --git a/third_party/blink/renderer/core/style/grid_positions_resolver.h b/third_party/blink/renderer/core/style/grid_positions_resolver.h index bf67244..b4edcf42 100644 --- a/third_party/blink/renderer/core/style/grid_positions_resolver.h +++ b/third_party/blink/renderer/core/style/grid_positions_resolver.h
@@ -66,11 +66,11 @@ static GridPositionSide InitialPositionSide(GridTrackSizingDirection); static GridPositionSide FinalPositionSide(GridTrackSizingDirection); - static size_t SpanSizeForAutoPlacedItem(const LayoutBox&, + static size_t SpanSizeForAutoPlacedItem(const ComputedStyle&, GridTrackSizingDirection); static GridSpan ResolveGridPositionsFromStyle( const ComputedStyle&, - const LayoutBox&, + const ComputedStyle&, GridTrackSizingDirection, size_t auto_repeat_tracks_count); };
diff --git a/third_party/blink/renderer/core/style/grid_track_list.cc b/third_party/blink/renderer/core/style/grid_track_list.cc index 61876e25..a484c44 100644 --- a/third_party/blink/renderer/core/style/grid_track_list.cc +++ b/third_party/blink/renderer/core/style/grid_track_list.cc
@@ -190,6 +190,7 @@ : legacy_track_list_(std::move(legacy_tracks)) { if (RuntimeEnabledFeatures::LayoutNGGridEnabled()) { ng_track_list_ = std::make_unique<NGGridTrackList>(); + ng_track_list_->AddRepeater(legacy_track_list_, 1); } }
diff --git a/third_party/blink/renderer/core/testing/fake_local_frame_host.cc b/third_party/blink/renderer/core/testing/fake_local_frame_host.cc index b381726..0a62884 100644 --- a/third_party/blink/renderer/core/testing/fake_local_frame_host.cc +++ b/third_party/blink/renderer/core/testing/fake_local_frame_host.cc
@@ -49,8 +49,6 @@ void FakeLocalFrameHost::SetVirtualKeyboardOverlayPolicy( bool vk_overlays_content) {} -void FakeLocalFrameHost::EvictFromBackForwardCache() {} - void FakeLocalFrameHost::VisibilityChanged( mojom::blink::FrameVisibility visibility) {}
diff --git a/third_party/blink/renderer/core/testing/fake_local_frame_host.h b/third_party/blink/renderer/core/testing/fake_local_frame_host.h index a34a906c..ff39690 100644 --- a/third_party/blink/renderer/core/testing/fake_local_frame_host.h +++ b/third_party/blink/renderer/core/testing/fake_local_frame_host.h
@@ -41,7 +41,6 @@ void DocumentAvailableInMainFrame(bool uses_temporary_zoom_level) override; void SetNeedsOcclusionTracking(bool needs_tracking) override; void SetVirtualKeyboardOverlayPolicy(bool vk_overlays_content) override; - void EvictFromBackForwardCache() override; void VisibilityChanged(mojom::blink::FrameVisibility visibility) override; void DidChangeThemeColor( const base::Optional<::SkColor>& theme_color) override;
diff --git a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl index 22c0268..7465e550 100644 --- a/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl +++ b/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl
@@ -9,7 +9,6 @@ RuntimeEnabled=TrustedDOMTypes ] interface TrustedTypePolicyFactory : EventTarget { [RaisesException] TrustedTypePolicy createPolicy(DOMString policyName, TrustedTypePolicyOptions policyOptions); - readonly attribute TrustedTypePolicy defaultPolicy; // All the policy object names that have been created [CallWith=ScriptState] boolean isHTML(any checkedObject); [CallWith=ScriptState] boolean isScript(any checkedObject); @@ -19,10 +18,12 @@ // Trusted Types metadata, following the proposal in: // https://github.com/WICG/trusted-types/pull/149/commits/ecd9ab0b6993674951bfc7b44a04530fce7468a7 - DOMString? getPropertyType(DOMString tagName, DOMString property, - optional DOMString elementNS); DOMString? getAttributeType(DOMString tagName, DOMString attribute, optional DOMString elementNS, optional DOMString attrNs); + DOMString? getPropertyType(DOMString tagName, DOMString property, + optional DOMString elementNS); + + readonly attribute TrustedTypePolicy defaultPolicy; [CallWith=ScriptState] object? getTypeMapping(optional DOMString ns); [RuntimeEnabled=TrustedTypeBeforePolicyCreationEvent] attribute EventHandler onbeforecreatepolicy;
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 4a7a526..7c146cc 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -110,6 +110,7 @@ #include "ui/events/keycodes/dom/keycode_converter.h" namespace { + bool IsNeutralWithinTable(blink::AXObject* obj) { if (!obj) return false; @@ -2465,9 +2466,9 @@ return !aria_owns.IsEmpty(); } -// TODO : Aria-dropeffect and aria-grabbed are deprecated in aria 1.1 -// Also those properties are expected to be replaced by a new feature in -// a future version of WAI-ARIA. After that we will re-implement them +// TODO(accessibility): Aria-dropeffect and aria-grabbed are deprecated in +// aria 1.1 Also those properties are expected to be replaced by a new feature +// in a future version of WAI-ARIA. After that we will re-implement them // following new spec. bool AXNodeObject::SupportsARIADragging() const { const AtomicString& grabbed = GetAttribute(html_names::kAriaGrabbedAttr); @@ -3138,9 +3139,9 @@ return; if (GetLayoutObject()->NeedsLayout()) { - // If a LayoutText needs layout, its inline text boxes are either - // nonexistent or invalid, so defer until the layout happens and - // the layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. + // If a LayoutText or a LayoutBR needs layout, its inline text boxes are + // either nonexistent or invalid, so defer until the layout happens and the + // layoutObject calls AXObjectCacheImpl::inlineTextBoxesUpdated. return; } @@ -3148,9 +3149,16 @@ for (scoped_refptr<AbstractInlineTextBox> box = layout_text->FirstAbstractInlineTextBox(); box.get(); box = box->NextInlineTextBox()) { - AXObject* ax_object = AXObjectCache().GetOrCreate(box.get()); - if (ax_object->AccessibilityIsIncludedInTree()) - children_.push_back(ax_object); + AXObject* ax_box = AXObjectCache().GetOrCreate(box.get()); + if (!ax_box || !ax_box->AccessibilityIsIncludedInTree()) + continue; + + children_.push_back(ax_box); + // If |force| is set to true, it means that we are forcing the children to + // be added without going through the normal tree building mechanism, which + // would have also set the parent of each child to |this|. + if (force) + ax_box->SetParent(this); } } @@ -3230,12 +3238,12 @@ AXObject* obj = AXObjectCache().GetOrCreate(&area); if (obj) { auto* area_object = To<AXImageMapLink>(obj); - area_object->SetParent(this); DCHECK_NE(area_object->AXObjectID(), 0U); - if (area_object->AccessibilityIsIncludedInTree()) + if (area_object->AccessibilityIsIncludedInTree()) { children_.push_back(area_object); - else + } else { AXObjectCache().Remove(area_object->AXObjectID()); + } } } } @@ -3269,8 +3277,6 @@ if (!root) return; - root->SetParent(this); - if (!root->AccessibilityIsIncludedInTree()) { for (const auto& child : root->ChildrenIncludingIgnored()) children_.push_back(child); @@ -3352,19 +3358,14 @@ for (const auto& owned_child : owned_children) AddChild(owned_child); - bool is_continuation = - GetLayoutObject() && GetLayoutObject()->IsElementContinuation(); for (const auto& child : children_) { - if (!is_continuation && !child->CachedParentObject()) { - // Never set continuations as a parent object. The first layout object - // in the chain must be used instead. + if (!child->CachedParentObject()) child->SetParent(this); - } } } void AXNodeObject::AddChild(AXObject* child) { - unsigned index = children_.size(); + unsigned int index = children_.size(); InsertChild(child, index); } @@ -3373,19 +3374,20 @@ return; // If the parent is asking for this child's children, then either it's the - // first time (and clearing is a no-op), or its visibility has changed. In the - // latter case, this child may have a stale child cached. This can prevent - // aria-hidden changes from working correctly. Hence, whenever a parent is - // getting children, ensure data is not stale. + // first time (and clearing is a no-op), or its visibility has changed. In + // the latter case, this child may have a stale child cached. This can + // prevent aria-hidden changes from working correctly. Hence, whenever a + // parent is getting children, ensure data is not stale. child->ClearChildren(); if (!child->AccessibilityIsIncludedInTree()) { + // Re-computes child's children. const auto& children = child->ChildrenIncludingIgnored(); wtf_size_t length = children.size(); for (wtf_size_t i = 0; i < length; ++i) children_.insert(index + i, children[i]); } else if (!child->IsMenuListOption()) { - // MenuListOptions must only added in AXMenuListPopup::AddChildren + // MenuListOptions must only be added in AXMenuListPopup::AddChildren. children_.insert(index, child); } }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index dc75f654..2a36de59 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -560,6 +560,10 @@ return !ax_object_cache_; } +void AXObject::SetParent(AXObject* parent) { + parent_ = parent; +} + const AtomicString& AXObject::GetAOMPropertyOrARIAAttribute( AOMStringProperty property) const { Element* element = this->GetElement(); @@ -1866,8 +1870,8 @@ // ARIA role at all, because if so then it must be a grid-related // role so it must be selectable. // - // TODO: an ARIA 1.1+ role of "cell", or a role of "row" inside - // an ARIA 1.1 role of "table", should not be selectable. We may + // TODO(accessibility): an ARIA 1.1+ role of "cell", or a role of "row" + // inside an ARIA 1.1 role of "table", should not be selectable. We may // need to create separate role enums for grid cells vs table cells // to implement this. if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown) @@ -2436,7 +2440,7 @@ const AXObjectVector& siblings = ParentObjectIncludedInTree()->ChildrenIncludingIgnored(); wtf_size_t index = siblings.Find(this); - DCHECK(index != kNotFound); + DCHECK_NE(index, kNotFound); return (index == kNotFound) ? 0 : static_cast<int>(index); }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h index e759ca3..bb76671 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -344,7 +344,7 @@ }; protected: - AXObject(AXObjectCacheImpl&); + explicit AXObject(AXObjectCacheImpl&); public: virtual ~AXObject(); @@ -363,9 +363,9 @@ virtual void Detach(); virtual bool IsDetached() const; - // If the parent of this object is known, this can be faster than using - // computeParent(). - virtual void SetParent(AXObject* parent) { parent_ = parent; } + // Sets the parent AXObject directly. If the parent of this object is known, + // this can be faster than using computeParent(). + virtual void SetParent(AXObject* parent); // The AXObjectCacheImpl that owns this object, and its unique ID within this // cache. @@ -546,8 +546,8 @@ bool HasInheritedPresentationalRole() const; bool IsPresentationalChild() const; bool CanBeActiveDescendant() const; - // Some objects, such as table cells, could be the children of more than one - // object but have only one primary parent. + // Some objects, such as table header containers, could be the children of + // more than one object but have only one primary parent. bool HasIndirectChildren() const; // @@ -1007,8 +1007,25 @@ // Low-level accessibility tree exploration, only for use within the // accessibility module. + + // Returns the AXObject's first child, skipping over any children that + // represent continuations in the layout tree. If the AXObject has no + // children, returns the AXObject representing the next in pre-order + // continuation in the layout tree, if any. + // + // In the accessibility tree, this results in continuations becoming + // descendants of the nodes they "continue". virtual AXObject* RawFirstChild() const { return nullptr; } + + // Returns the AXObject's next sibling, skipping over any siblings that + // represent continuations in the layout tree. If this is the last child, + // returns the AXObject representing the next in pre-order continuation in the + // layout tree, if any. + // + // In the accessibility tree, this results in continuations becoming + // descendants of the nodes they "continue". virtual AXObject* RawNextSibling() const { return nullptr; } + virtual void AddChildren() {} virtual bool CanHaveChildren() const { return true; } bool HasChildren() const { return have_children_; }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_test.cc b/third_party/blink/renderer/modules/accessibility/ax_object_test.cc index 03e1805e..fdb60f4 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_test.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_test.cc
@@ -153,13 +153,13 @@ // ++++B // ++C // So that nodes [A, B, C] are siblings - SetBodyInnerHTML(R"HTML(<body> - <p id="A">some text</p> - <div> - <p id="B">nested text</p> - </div> - <p id="C">more text</p> - </body>)HTML"); + SetBodyInnerHTML(R"HTML( + <p id="A">some text</p> + <div> + <p id="B">nested text</p> + </div> + <p id="C">more text</p> + )HTML"); const AXObject* root = GetAXRootObject(); const AXObject* body = GetAXBodyObject(); @@ -230,6 +230,149 @@ EXPECT_EQ(obj_c_text, obj_c->UnignoredNextInPreOrder()); } +TEST_F(AccessibilityTest, TreeNavigationWithContinuations) { + // Continuations found in the layout tree should not appear in the + // accessibility tree. For example, the following accessibility tree should + // result from the following HTML. + // + // WebArea + // ++HTMLElement + // ++++BodyElement + // ++++++Link + // ++++++++StaticText "Before block element." + // ++++++++GenericContainer + // ++++++++++Paragraph + // ++++++++++++StaticText "Inside block element." + // ++++++++StaticText "After block element." + SetBodyInnerHTML(R"HTML( + <a id="link" href="#"> + Before block element. + <div id="div"> + <p id="paragraph"> + Inside block element. + </p> + </div> + After block element. + </a> + )HTML"); + + const AXObject* ax_root = GetAXRootObject(); + ASSERT_NE(nullptr, ax_root); + const AXObject* ax_body = GetAXBodyObject(); + ASSERT_NE(nullptr, ax_body); + const AXObject* ax_link = GetAXObjectByElementId("link"); + ASSERT_NE(nullptr, ax_link); + const AXObject* ax_text_before = ax_link->FirstChildIncludingIgnored(); + ASSERT_NE(nullptr, ax_text_before); + ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text_before->RoleValue()); + ASSERT_FALSE(ax_text_before->AccessibilityIsIgnored()); + const AXObject* ax_div = GetAXObjectByElementId("div"); + ASSERT_NE(nullptr, ax_div); + const AXObject* ax_paragraph = GetAXObjectByElementId("paragraph"); + ASSERT_NE(nullptr, ax_paragraph); + const AXObject* ax_text_inside = ax_paragraph->FirstChildIncludingIgnored(); + ASSERT_NE(nullptr, ax_text_inside); + ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text_inside->RoleValue()); + ASSERT_FALSE(ax_text_inside->AccessibilityIsIgnored()); + const AXObject* ax_text_after = ax_link->LastChildIncludingIgnored(); + ASSERT_NE(nullptr, ax_text_after); + ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text_after->RoleValue()); + ASSERT_FALSE(ax_text_after->AccessibilityIsIgnored()); + + // + // Test parent / child relationships individually. This is easier to debug + // than printing the whole accessibility tree as a string and comparing with + // an expected tree. + // + + EXPECT_EQ(ax_root, ax_link->ParentObjectUnignored()); + EXPECT_EQ(ax_body, ax_link->ParentObjectIncludedInTree()); + + EXPECT_EQ(ax_link, ax_text_before->ParentObjectUnignored()); + EXPECT_EQ(ax_link, ax_text_before->ParentObjectIncludedInTree()); + EXPECT_EQ(ax_link, ax_div->ParentObjectUnignored()); + EXPECT_EQ(ax_link, ax_div->ParentObjectIncludedInTree()); + EXPECT_EQ(ax_link, ax_text_after->ParentObjectUnignored()); + EXPECT_EQ(ax_link, ax_text_after->ParentObjectIncludedInTree()); + + EXPECT_EQ(ax_div, ax_link->ChildAtIncludingIgnored(1)); + EXPECT_EQ(ax_div, ax_link->UnignoredChildAt(1)); + + EXPECT_EQ(nullptr, ax_text_before->PreviousSiblingIncludingIgnored()); + EXPECT_EQ(nullptr, ax_text_before->UnignoredPreviousSibling()); + EXPECT_EQ(ax_div, ax_text_before->NextSiblingIncludingIgnored()); + EXPECT_EQ(ax_div, ax_text_before->UnignoredNextSibling()); + EXPECT_EQ(ax_div, ax_text_after->PreviousSiblingIncludingIgnored()); + EXPECT_EQ(ax_div, ax_text_after->UnignoredPreviousSibling()); + EXPECT_EQ(nullptr, ax_text_after->NextSiblingIncludingIgnored()); + EXPECT_EQ(nullptr, ax_text_after->UnignoredNextSibling()); + + EXPECT_EQ(ax_paragraph, ax_div->ChildAtIncludingIgnored(0)); + EXPECT_EQ(ax_paragraph, ax_div->UnignoredChildAt(0)); + + EXPECT_EQ(ax_div, ax_paragraph->ParentObjectUnignored()); + EXPECT_EQ(ax_div, ax_paragraph->ParentObjectIncludedInTree()); + EXPECT_EQ(ax_paragraph, ax_text_inside->ParentObjectUnignored()); + EXPECT_EQ(ax_paragraph, ax_text_inside->ParentObjectIncludedInTree()); +} + +TEST_F(AccessibilityTest, TreeNavigationWithInlineTextBoxes) { + SetBodyInnerHTML(R"HTML( + Before paragraph element. + <p id="paragraph"> + Inside paragraph element. + </p> + After paragraph element. + )HTML"); + + AXObject* ax_root = GetAXRootObject(); + ASSERT_NE(nullptr, ax_root); + ax_root->LoadInlineTextBoxes(); + + const AXObject* ax_paragraph = GetAXObjectByElementId("paragraph"); + ASSERT_NE(nullptr, ax_paragraph); + const AXObject* ax_text_inside = ax_paragraph->FirstChildIncludingIgnored(); + ASSERT_NE(nullptr, ax_text_inside); + ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text_inside->RoleValue()); + const AXObject* ax_text_before = ax_paragraph->UnignoredPreviousSibling(); + ASSERT_NE(nullptr, ax_text_before); + ASSERT_EQ(ax::mojom::blink::Role::kStaticText, ax_text_before->RoleValue()); + const AXObject* ax_text_after = ax_paragraph->UnignoredNextSibling(); + ASSERT_NE(nullptr, ax_text_after); + ASSERT_EQ(ax::mojom::blink::Role::kStaticText, ax_text_after->RoleValue()); + + // + // Verify parent / child relationships between static text and inline text + // boxes. + // + + EXPECT_EQ(1, ax_text_before->ChildCountIncludingIgnored()); + EXPECT_EQ(1, ax_text_before->UnignoredChildCount()); + const AXObject* ax_inline_before = + ax_text_before->FirstChildIncludingIgnored(); + EXPECT_EQ(ax::mojom::blink::Role::kInlineTextBox, + ax_inline_before->RoleValue()); + EXPECT_EQ(ax_text_before, ax_inline_before->ParentObjectIncludedInTree()); + EXPECT_EQ(ax_text_before, ax_inline_before->ParentObjectUnignored()); + + EXPECT_EQ(1, ax_text_inside->ChildCountIncludingIgnored()); + EXPECT_EQ(1, ax_text_inside->UnignoredChildCount()); + const AXObject* ax_inline_inside = + ax_text_inside->FirstChildIncludingIgnored(); + EXPECT_EQ(ax::mojom::blink::Role::kInlineTextBox, + ax_inline_inside->RoleValue()); + EXPECT_EQ(ax_text_inside, ax_inline_inside->ParentObjectIncludedInTree()); + EXPECT_EQ(ax_text_inside, ax_inline_inside->ParentObjectUnignored()); + + EXPECT_EQ(1, ax_text_after->ChildCountIncludingIgnored()); + EXPECT_EQ(1, ax_text_after->UnignoredChildCount()); + const AXObject* ax_inline_after = ax_text_after->FirstChildIncludingIgnored(); + EXPECT_EQ(ax::mojom::blink::Role::kInlineTextBox, + ax_inline_after->RoleValue()); + EXPECT_EQ(ax_text_after, ax_inline_after->ParentObjectIncludedInTree()); + EXPECT_EQ(ax_text_after, ax_inline_after->ParentObjectUnignored()); +} + TEST_F(AccessibilityTest, AXObjectComparisonOperators) { SetBodyInnerHTML(R"HTML(<input id="input" type="text" value="value"> <p id="paragraph">hello<br id="br">there</p>
diff --git a/third_party/blink/renderer/modules/eventsource/event_source.cc b/third_party/blink/renderer/modules/eventsource/event_source.cc index 963ffbe..ef3b7e9 100644 --- a/third_party/blink/renderer/modules/eventsource/event_source.cc +++ b/third_party/blink/renderer/modules/eventsource/event_source.cc
@@ -75,7 +75,8 @@ connect_timer_(context->GetTaskRunner(TaskType::kRemoteEvent), this, &EventSource::ConnectTimerFired), - reconnect_delay_(kDefaultReconnectDelay) {} + reconnect_delay_(kDefaultReconnectDelay), + world_(context->GetCurrentWorld()) {} EventSource* EventSource::Create(ExecutionContext* context, const String& url, @@ -151,7 +152,7 @@ last_event_id_utf8.length())); } - ResourceLoaderOptions resource_loader_options; + ResourceLoaderOptions resource_loader_options(world_); resource_loader_options.data_buffering_policy = kDoNotBufferData; probe::WillSendEventSourceRequest(&execution_context);
diff --git a/third_party/blink/renderer/modules/eventsource/event_source.h b/third_party/blink/renderer/modules/eventsource/event_source.h index 6b11bdc..914b436a 100644 --- a/third_party/blink/renderer/modules/eventsource/event_source.h +++ b/third_party/blink/renderer/modules/eventsource/event_source.h
@@ -33,6 +33,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_EVENTSOURCE_EVENT_SOURCE_H_ #include <memory> +#include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" @@ -47,6 +48,7 @@ namespace blink { +class DOMWrapperWorld; class EventSourceInit; class ExceptionState; class ResourceResponse; @@ -134,6 +136,10 @@ uint64_t reconnect_delay_; String event_stream_origin_; uint64_t resource_identifier_ = 0; + + // The world in which this EventSource was created. We need to store this + // because EventSource::Connect can be triggered by |connect_timer_|. + scoped_refptr<const DOMWrapperWorld> world_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc b/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc index d43b8e65..56e5448 100644 --- a/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc +++ b/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc
@@ -32,7 +32,7 @@ ? network::mojom::CredentialsMode::kInclude : network::mojom::CredentialsMode::kOmit); - ResourceLoaderOptions resource_loader_options; + ResourceLoaderOptions resource_loader_options(window.GetCurrentWorld()); resource_loader_options.data_buffering_policy = kDoNotBufferData; loader_ = MakeGarbageCollected<ThreadableLoader>(
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc index f5d0eaa..3f0ddf2c 100644 --- a/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc +++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc
@@ -31,7 +31,7 @@ // ChromeClient overrides: void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*, - bool for_cross_process_descendant) override { + FullscreenRequestType) override { Fullscreen::DidResolveEnterFullscreenRequest(*frame.GetDocument(), true /* granted */); }
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc index be4dd86..cd64648 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
@@ -30,7 +30,7 @@ // ChromeClient overrides: void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*, - bool for_cross_process_descendant) override { + FullscreenRequestType) override { Fullscreen::DidResolveEnterFullscreenRequest(*frame.GetDocument(), true /* granted */); }
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc index 61358aa..9ef4ae09 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc
@@ -122,7 +122,7 @@ // async due to IPC, emulate that by posting tasks: void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*, - bool for_cross_process_descendant) override { + FullscreenRequestType) override { Thread::Current()->GetTaskRunner()->PostTask( FROM_HERE, WTF::Bind(DidEnterFullscreen, WrapPersistent(frame.GetDocument())));
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc index 9d9e68a..560e7e0 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc
@@ -64,7 +64,7 @@ } void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*, - bool for_cross_process_descendant) override { + FullscreenRequestType) override { Fullscreen::DidResolveEnterFullscreenRequest(*frame.GetDocument(), true /* granted */); }
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc index e99c7f5..9fce81c 100644 --- a/third_party/blink/renderer/modules/payments/payment_request.cc +++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -442,6 +442,8 @@ } else if (supported_method == kSecurePaymentConfirmationMethod && RuntimeEnabledFeatures::SecurePaymentConfirmationEnabled( &execution_context)) { + UseCounter::Count(&execution_context, + WebFeature::kSecurePaymentConfirmation); SecurePaymentConfirmationHelper::ParseSecurePaymentConfirmationData( input, exception_state); }
diff --git a/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc b/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc index a121fdf..d5858e24 100644 --- a/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc +++ b/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc
@@ -65,7 +65,8 @@ device::mojom::blink::SensorConfigurationPtr configuration) { DCHECK(IsInitialized()); RemoveActiveFrequency(configuration->frequency); - sensor_remote_->RemoveConfiguration(std::move(configuration)); + if (sensor_remote_.is_bound()) + sensor_remote_->RemoveConfiguration(std::move(configuration)); } double SensorProxyImpl::GetDefaultFrequency() const {
diff --git a/third_party/blink/renderer/modules/serial/serial_input_signals.idl b/third_party/blink/renderer/modules/serial/serial_input_signals.idl index 69de095..46959c6 100644 --- a/third_party/blink/renderer/modules/serial/serial_input_signals.idl +++ b/third_party/blink/renderer/modules/serial/serial_input_signals.idl
@@ -6,11 +6,11 @@ dictionary SerialInputSignals { // DCD (Data Carrier Detect) or RLSD (Receive Line Signal Detect) - required boolean dcd; + required boolean dataCarrierDetect; // CTS (Clear to Send) - required boolean cts; + required boolean clearToSend; // RI (Ring Indicator) - required boolean ri; + required boolean ringIndicator; // DSR (Data Set Ready) - required boolean dsr; + required boolean dataSetReady; };
diff --git a/third_party/blink/renderer/modules/serial/serial_options.idl b/third_party/blink/renderer/modules/serial/serial_options.idl index 787e5bc3..479e9d3 100644 --- a/third_party/blink/renderer/modules/serial/serial_options.idl +++ b/third_party/blink/renderer/modules/serial/serial_options.idl
@@ -10,11 +10,16 @@ "odd", }; +enum FlowControlType { + "none", + "hardware", +}; + dictionary SerialOptions { - required [EnforceRange] unsigned long baudrate; - [EnforceRange] octet databits = 8; - [EnforceRange] octet stopbits = 1; + required [EnforceRange] unsigned long baudRate; + [EnforceRange] octet dataBits = 8; + [EnforceRange] octet stopBits = 1; ParityType parity = "none"; - [EnforceRange] unsigned long buffersize = 255; - boolean rtscts = false; + [EnforceRange] unsigned long bufferSize = 255; + FlowControlType flowControl = "none"; };
diff --git a/third_party/blink/renderer/modules/serial/serial_output_signals.idl b/third_party/blink/renderer/modules/serial/serial_output_signals.idl index 7a3aa1aa..7611803 100644 --- a/third_party/blink/renderer/modules/serial/serial_output_signals.idl +++ b/third_party/blink/renderer/modules/serial/serial_output_signals.idl
@@ -6,9 +6,9 @@ dictionary SerialOutputSignals { // DTR (Data Terminal Ready) - boolean dtr; + boolean dataTerminalReady; // RTS (Request to Send) - boolean rts; - // BRK (Break) - boolean brk; + boolean requestToSend; + // BRK (Break), implemented as "brk" because "break" is a C++ keyword + [ImplementedAs=brk] boolean break; };
diff --git a/third_party/blink/renderer/modules/serial/serial_port.cc b/third_party/blink/renderer/modules/serial/serial_port.cc index 8e01d322..989104ef 100644 --- a/third_party/blink/renderer/modules/serial/serial_port.cc +++ b/third_party/blink/renderer/modules/serial/serial_port.cc
@@ -196,14 +196,14 @@ auto mojo_options = device::mojom::blink::SerialConnectionOptions::New(); - if (options->baudrate() == 0) { + if (options->baudRate() == 0) { exception_state.ThrowTypeError( "Requested baud rate must be greater than zero."); return ScriptPromise(); } - mojo_options->bitrate = options->baudrate(); + mojo_options->bitrate = options->baudRate(); - switch (options->databits()) { + switch (options->dataBits()) { case 7: mojo_options->data_bits = device::mojom::blink::SerialDataBits::SEVEN; break; @@ -226,7 +226,7 @@ NOTREACHED(); } - switch (options->stopbits()) { + switch (options->stopBits()) { case 1: mojo_options->stop_bits = device::mojom::blink::SerialStopBits::ONE; break; @@ -239,24 +239,24 @@ return ScriptPromise(); } - if (options->buffersize() == 0) { + if (options->bufferSize() == 0) { exception_state.ThrowTypeError(String::Format( "Requested buffer size (%d bytes) must be greater than zero.", - options->buffersize())); + options->bufferSize())); return ScriptPromise(); } - if (options->buffersize() > kMaxBufferSize) { + if (options->bufferSize() > kMaxBufferSize) { exception_state.ThrowTypeError( String::Format("Requested buffer size (%d bytes) is greater than " "the maximum allowed (%d bytes).", - options->buffersize(), kMaxBufferSize)); + options->bufferSize(), kMaxBufferSize)); return ScriptPromise(); } - buffer_size_ = options->buffersize(); + buffer_size_ = options->bufferSize(); mojo_options->has_cts_flow_control = true; - mojo_options->cts_flow_control = options->rtscts(); + mojo_options->cts_flow_control = options->flowControl() == "hardware"; mojo::PendingRemote<device::mojom::blink::SerialPortClient> client; parent_->GetPort( @@ -360,19 +360,20 @@ return ScriptPromise(); } - if (!signals->hasDtr() && !signals->hasRts() && !signals->hasBrk()) { + if (!signals->hasDataTerminalReady() && !signals->hasRequestToSend() && + !signals->hasBrk()) { exception_state.ThrowTypeError(kNoSignals); return ScriptPromise(); } auto mojo_signals = device::mojom::blink::SerialHostControlSignals::New(); - if (signals->hasDtr()) { + if (signals->hasDataTerminalReady()) { mojo_signals->has_dtr = true; - mojo_signals->dtr = signals->dtr(); + mojo_signals->dtr = signals->dataTerminalReady(); } - if (signals->hasRts()) { + if (signals->hasRequestToSend()) { mojo_signals->has_rts = true; - mojo_signals->rts = signals->rts(); + mojo_signals->rts = signals->requestToSend(); } if (signals->hasBrk()) { mojo_signals->has_brk = true; @@ -611,10 +612,10 @@ } auto* signals = MakeGarbageCollected<SerialInputSignals>(); - signals->setDcd(mojo_signals->dcd); - signals->setCts(mojo_signals->cts); - signals->setRi(mojo_signals->ri); - signals->setDsr(mojo_signals->dsr); + signals->setDataCarrierDetect(mojo_signals->dcd); + signals->setClearToSend(mojo_signals->cts); + signals->setRingIndicator(mojo_signals->ri); + signals->setDataSetReady(mojo_signals->dsr); resolver->Resolve(signals); }
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_event.cc b/third_party/blink/renderer/modules/service_worker/fetch_event.cc index 2db345f..28d7ddd6 100644 --- a/third_party/blink/renderer/modules/service_worker/fetch_event.cc +++ b/third_party/blink/renderer/modules/service_worker/fetch_event.cc
@@ -68,6 +68,19 @@ return preload_response_property_->Promise(script_state->World()); } +ScriptPromise FetchEvent::handled(ScriptState* script_state) { + return handled_property_->Promise(script_state->World()); +} + +void FetchEvent::ResolveHandledPromise() { + handled_property_->ResolveWithUndefined(); +} + +void FetchEvent::RejectHandledPromise(const String& error_message) { + handled_property_->Reject(ServiceWorkerError::GetException( + nullptr, mojom::blink::ServiceWorkerErrorType::kNetwork, error_message)); +} + const AtomicString& FetchEvent::InterfaceName() const { return event_interface_names::kFetchEvent; } @@ -96,6 +109,10 @@ observer_(respond_with_observer), preload_response_property_(MakeGarbageCollected<PreloadResponseProperty>( ExecutionContext::From(script_state))), + handled_property_( + MakeGarbageCollected<ScriptPromiseProperty<ToV8UndefinedGenerator, + Member<DOMException>>>( + ExecutionContext::From(script_state))), worker_timing_remote_(ExecutionContext::From(script_state)) { worker_timing_remote_.Bind(std::move(worker_timing_remote), ExecutionContext::From(script_state) @@ -231,6 +248,7 @@ visitor->Trace(request_); visitor->Trace(preload_response_property_); visitor->Trace(body_completion_notifier_); + visitor->Trace(handled_property_); visitor->Trace(worker_timing_remote_); ExtendableEvent::Trace(visitor); ExecutionContextClient::Trace(visitor);
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_event.h b/third_party/blink/renderer/modules/service_worker/fetch_event.h index 28b9d6bd..bfaf6b34 100644 --- a/third_party/blink/renderer/modules/service_worker/fetch_event.h +++ b/third_party/blink/renderer/modules/service_worker/fetch_event.h
@@ -71,6 +71,11 @@ void respondWith(ScriptState*, ScriptPromise, ExceptionState&); ScriptPromise preloadResponse(ScriptState*); + ScriptPromise handled(ScriptState*); + + void ResolveHandledPromise(); + void RejectHandledPromise(const String& error_message); + void addPerformanceEntry(PerformanceMark*); void addPerformanceEntry(PerformanceMeasure*); @@ -98,6 +103,8 @@ Member<PreloadResponseProperty> preload_response_property_; std::unique_ptr<WebURLResponse> preload_response_; Member<DataPipeBytesConsumer::CompletionNotifier> body_completion_notifier_; + Member<ScriptPromiseProperty<ToV8UndefinedGenerator, Member<DOMException>>> + handled_property_; // This is currently null for navigation while https://crbug.com/900700 is // being implemented. HeapMojoRemote<mojom::blink::WorkerTimingContainer,
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_event.idl b/third_party/blink/renderer/modules/service_worker/fetch_event.idl index 409e193e..2dc28c1 100644 --- a/third_party/blink/renderer/modules/service_worker/fetch_event.idl +++ b/third_party/blink/renderer/modules/service_worker/fetch_event.idl
@@ -15,6 +15,7 @@ [CallWith=ScriptState, RaisesException] void respondWith(Promise<Response> r); [CallWith=ScriptState] readonly attribute Promise<any> preloadResponse; + [CallWith=ScriptState] readonly attribute Promise<void> handled; // FetchEvent#addPerformanceEntry // https://github.com/wanderview/fetchevent-worker-timing/blob/master/explainer.md [RuntimeEnabled=ServiceWorkerFetchEventWorkerTiming]
diff --git a/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc b/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc index 9b368e0..ba12555 100644 --- a/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc +++ b/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
@@ -198,19 +198,23 @@ void FetchRespondWithObserver::OnResponseRejected( ServiceWorkerResponseError error) { DCHECK(GetExecutionContext()); + const String error_message = GetMessageForResponseError(error, request_url_); GetExecutionContext()->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( mojom::ConsoleMessageSource::kJavaScript, - mojom::ConsoleMessageLevel::kWarning, - GetMessageForResponseError(error, request_url_))); + mojom::ConsoleMessageLevel::kWarning, error_message)); // The default value of FetchAPIResponse's status is 0, which maps to a // network error. auto response = mojom::blink::FetchAPIResponse::New(); response->status_text = ""; response->error = error; - To<ServiceWorkerGlobalScope>(GetExecutionContext()) - ->RespondToFetchEvent(event_id_, request_url_, std::move(response), - event_dispatch_time_, base::TimeTicks::Now()); + ServiceWorkerGlobalScope* service_worker_global_scope = + To<ServiceWorkerGlobalScope>(GetExecutionContext()); + service_worker_global_scope->RespondToFetchEvent( + event_id_, request_url_, std::move(response), event_dispatch_time_, + base::TimeTicks::Now()); + service_worker_global_scope->RejectFetchEventHandledPromise(event_id_, + error_message); } void FetchRespondWithObserver::OnResponseFulfilled( @@ -333,6 +337,7 @@ service_worker_global_scope->RespondToFetchEvent( event_id_, request_url_, std::move(fetch_api_response), event_dispatch_time_, base::TimeTicks::Now()); + service_worker_global_scope->ResolveFetchEventHandledPromise(event_id_); return; } @@ -359,19 +364,22 @@ service_worker_global_scope->RespondToFetchEventWithResponseStream( event_id_, request_url_, std::move(fetch_api_response), std::move(stream_handle), event_dispatch_time_, base::TimeTicks::Now()); + service_worker_global_scope->ResolveFetchEventHandledPromise(event_id_); return; } service_worker_global_scope->RespondToFetchEvent( event_id_, request_url_, std::move(fetch_api_response), event_dispatch_time_, base::TimeTicks::Now()); + service_worker_global_scope->ResolveFetchEventHandledPromise(event_id_); } void FetchRespondWithObserver::OnNoResponse() { DCHECK(GetExecutionContext()); - To<ServiceWorkerGlobalScope>(GetExecutionContext()) - ->RespondToFetchEventWithNoResponse(event_id_, request_url_, - event_dispatch_time_, - base::TimeTicks::Now()); + ServiceWorkerGlobalScope* service_worker_global_scope = + To<ServiceWorkerGlobalScope>(GetExecutionContext()); + service_worker_global_scope->RespondToFetchEventWithNoResponse( + event_id_, request_url_, event_dispatch_time_, base::TimeTicks::Now()); + service_worker_global_scope->ResolveFetchEventHandledPromise(event_id_); } FetchRespondWithObserver::FetchRespondWithObserver(
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index 5a0ab13..84f2915 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -808,6 +808,7 @@ visitor->Trace(payment_response_callbacks_); visitor->Trace(fetch_response_callbacks_); visitor->Trace(pending_preload_fetch_events_); + visitor->Trace(pending_fetch_events_); visitor->Trace(controller_receivers_); WorkerGlobalScope::Trace(visitor); } @@ -822,6 +823,20 @@ return features::kInstallingServiceWorkerOutstandingThrottledLimit.Get(); } +void ServiceWorkerGlobalScope::ResolveFetchEventHandledPromise(int event_id) { + FetchEvent* fetch_event = pending_fetch_events_.Take(event_id); + DCHECK(fetch_event); + fetch_event->ResolveHandledPromise(); +} + +void ServiceWorkerGlobalScope::RejectFetchEventHandledPromise( + int event_id, + const String& error_message) { + FetchEvent* fetch_event = pending_fetch_events_.Take(event_id); + DCHECK(fetch_event); + fetch_event->RejectHandledPromise(error_message); +} + void ServiceWorkerGlobalScope::importScripts(const Vector<String>& urls, ExceptionState& exception_state) { for (const String& string_url : urls) { @@ -1528,6 +1543,8 @@ pending_preload_fetch_events_.insert(event_id, fetch_event); } + pending_fetch_events_.insert(event_id, fetch_event); + NoteNewFetchEvent(request->url()); DispatchExtendableEventWithRespondWith(fetch_event, wait_until_observer,
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h index e4ae567..57beea8 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -316,6 +316,9 @@ int GetOutstandingThrottledLimit() const override; const ServiceWorkerToken& token() const { return token_; } + void ResolveFetchEventHandledPromise(int event_id); + void RejectFetchEventHandledPromise(int event_id, + const String& error_message); protected: // EventTarget @@ -688,6 +691,10 @@ HeapHashMap<int, Member<FetchEvent>> pending_preload_fetch_events_; + // Fetch events that are being handled are stored here and will be removed + // after being handled. + HeapHashMap<int, Member<FetchEvent>> pending_fetch_events_; + // Track outstanding FetchEvent objects still waiting for a response by // request URL. This information can be used as a hint that cache_storage // or fetch requests to the same URL is likely to be used to satisfy a
diff --git a/third_party/blink/renderer/modules/webdatabase/BUILD.gn b/third_party/blink/renderer/modules/webdatabase/BUILD.gn index e590b5ec..67529d0 100644 --- a/third_party/blink/renderer/modules/webdatabase/BUILD.gn +++ b/third_party/blink/renderer/modules/webdatabase/BUILD.gn
@@ -56,10 +56,8 @@ "sql_transaction_state.h", "sql_transaction_state_machine.cc", "sql_transaction_state_machine.h", - "sqlite/sandboxed_vfs.cc", - "sqlite/sandboxed_vfs.h", - "sqlite/sandboxed_vfs_file.cc", - "sqlite/sandboxed_vfs_file.h", + "sqlite/sandboxed_vfs_delegate.cc", + "sqlite/sandboxed_vfs_delegate.h", "sqlite/sql_log.h", "sqlite/sql_value.cc", "sqlite/sql_value.h",
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/DEPS b/third_party/blink/renderer/modules/webdatabase/sqlite/DEPS index 0bdaea5f..64f42078 100644 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/DEPS +++ b/third_party/blink/renderer/modules/webdatabase/sqlite/DEPS
@@ -1,6 +1,8 @@ include_rules = [ "+base/files/file.h", + "+base/files/file_path.h", "+base/threading/platform_thread.h", "+sql/initialization.h", + "+sql/sandboxed_vfs.h", "+third_party/sqlite/sqlite3.h", ]
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.cc deleted file mode 100644 index 656a206..0000000 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.cc +++ /dev/null
@@ -1,323 +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. - -#include "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h" - -#include <algorithm> -#include <cstring> -#include <string> -#include <utility> - -#include "base/check_op.h" -#include "base/files/file.h" -#include "base/notreached.h" -#include "base/threading/platform_thread.h" -#include "build/build_config.h" -#include "sql/initialization.h" -#include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.h" -#include "third_party/blink/renderer/modules/webdatabase/web_database_host.h" -#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" -#include "third_party/sqlite/sqlite3.h" - -#if OS_WIN -#include <windows.h> -#else -#include <unistd.h> -#endif - -namespace blink { - -namespace { - -// Name used to register the VFS with SQLite. Must be unique within Chrome. -constexpr char kSqliteVfsName[] = "renderer_sandboxed_vfs"; - -// Extracts the SandboxedVfs* stashed in a SQLite VFS structure. -SandboxedVfs* SandboxedVfsFromSqliteVfs(sqlite3_vfs* vfs) { - DCHECK(vfs); - return reinterpret_cast<SandboxedVfs*>(vfs->pAppData); -} - -int SandboxedVfsOpen(sqlite3_vfs* vfs, - const char* full_path, - sqlite3_file* result_file, - int requested_flags, - int* granted_flags) { - return SandboxedVfsFromSqliteVfs(vfs)->Open(full_path, result_file, - requested_flags, granted_flags); -} -int SandboxedVfsDelete(sqlite3_vfs* vfs, const char* full_path, int sync_dir) { - return SandboxedVfsFromSqliteVfs(vfs)->Delete(full_path, sync_dir); -} -int SandboxedVfsAccess(sqlite3_vfs* vfs, - const char* full_path, - int flags, - int* result) { - return SandboxedVfsFromSqliteVfs(vfs)->Access(full_path, flags, result); -} -int SandboxedVfsFullPathname(sqlite3_vfs* vfs, - const char* file_path, - int result_size, - char* result) { - return SandboxedVfsFromSqliteVfs(vfs)->FullPathname(file_path, result_size, - result); -} -int SandboxedVfsRandomness(sqlite3_vfs* vfs, int result_size, char* result) { - return SandboxedVfsFromSqliteVfs(vfs)->Randomness(result_size, result); -} -int SandboxedVfsSleep(sqlite3_vfs* vfs, int microseconds) { - return SandboxedVfsFromSqliteVfs(vfs)->Sleep(microseconds); -} -int SandboxedVfsGetLastError(sqlite3_vfs* vfs, - int message_size, - char* message) { - return SandboxedVfsFromSqliteVfs(vfs)->GetLastError(message_size, message); -} -int SandboxedVfsCurrentTimeInt64(sqlite3_vfs* vfs, sqlite3_int64* result_ms) { - return SandboxedVfsFromSqliteVfs(vfs)->CurrentTimeInt64(result_ms); -} - -sqlite3_vfs SqliteVfsFor(SandboxedVfs* sandboxed_vfs) { - DCHECK_EQ(sandboxed_vfs, reinterpret_cast<SandboxedVfs*>( - reinterpret_cast<void*>(sandboxed_vfs))) - << "This implementation round-trips SandboxedVfs* via void*"; - - // VFS API entry points are listed at https://www.sqlite.org/c3ref/vfs.html - static constexpr int kSqliteVfsApiVersion = 3; - - // Maximum file path size. - // TODO(pwnall): Obtain this from //base or some other good place. - static constexpr int kSqliteMaxPathSize = 512; - - return { - kSqliteVfsApiVersion, - sizeof(SandboxedVfsFileSqliteBridge), - kSqliteMaxPathSize, - /*pNext=*/nullptr, - kSqliteVfsName, - /*pAppData=*/reinterpret_cast<void*>(sandboxed_vfs), - SandboxedVfsOpen, - SandboxedVfsDelete, - SandboxedVfsAccess, - SandboxedVfsFullPathname, - /*xDlOpen=*/nullptr, - /*xDlError=*/nullptr, - /*xDlSym=*/nullptr, - /*xDlClose=*/nullptr, - SandboxedVfsRandomness, - SandboxedVfsSleep, - /*xCurrentTime=*/nullptr, // Deprecated in API versions 2 and above. - SandboxedVfsGetLastError, - SandboxedVfsCurrentTimeInt64, - /*xSetSystemCall=*/nullptr, - /*xGetSystemCall=*/nullptr, - /*xNextSystemCall=*/nullptr, - }; -} - -// Converts a SQLite full file path to a Blink string. -// -// The argument is guaranteed to be the result of a FullPathname() call, with -// an optional suffix. The suffix always starts with "-". -String StringFromFullPath(const char* full_path) { - DCHECK(full_path); - return String::FromUTF8(full_path); -} - -// SQLite measures time according to the Julian calendar. -base::Time SqliteEpoch() { - constexpr const double kMicroSecondsPerDay = 24 * 60 * 60 * 1000; - // The ".5" is intentional -- days in the Julian calendar start at noon. - // The offset is in the SQLite source code (os_unix.c) multiplied by 10. - constexpr const double kUnixEpochAsJulianDay = 2440587.5; - - return base::Time::FromJsTime(-kUnixEpochAsJulianDay * kMicroSecondsPerDay); -} - -} // namespace - -// static -SandboxedVfs& SandboxedVfs::GetInstance() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(SandboxedVfs, instance, ()); - return instance; -} - -SandboxedVfs::SandboxedVfs() - : sandboxed_vfs_(SqliteVfsFor(this)), - sqlite_epoch_(SqliteEpoch()), - platform_(Platform::Current()), - last_error_(base::File::FILE_OK) { - sql::EnsureSqliteInitialized(); - - // The register function returns a SQLite status as an int. The status is - // ignored here. If registration fails, we'd want to report the error while - // attempting to open a database. This is exactly what will happen, because - // SQLite won't find the VFS we're asking for. - sqlite3_vfs_register(&sandboxed_vfs_, /*make_default=*/0); -} - -std::tuple<int, sqlite3*> SandboxedVfs::OpenDatabase(const String& filename) { - sqlite3* connection; - constexpr int open_flags = - SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_PRIVATECACHE; - int status = sqlite3_open_v2(filename.Utf8().c_str(), &connection, open_flags, - kSqliteVfsName); - if (status != SQLITE_OK) { - // SQLite creates a connection handle in most cases where open fails. - if (connection) { - sqlite3_close(connection); - connection = nullptr; - } - } - return {status, connection}; -} - -int SandboxedVfs::Open(const char* full_path, - sqlite3_file* result_file, - int requested_flags, - int* granted_flags) { - DCHECK(full_path) << "WebSQL does not support creating temporary file names"; - DCHECK(result_file); - DCHECK_EQ(0, requested_flags & SQLITE_OPEN_DELETEONCLOSE) - << "SQLITE_OPEN_DELETEONCLOSE should not be used by WebSQL"; - DCHECK_EQ(0, requested_flags & SQLITE_OPEN_EXCLUSIVE) - << "SQLITE_OPEN_EXCLUSIVE should not be used by WebSQL"; - - String file_name = StringFromFullPath(full_path); - - // TODO(pwnall): This doesn't have to be synchronous. WebSQL's open sequence - // is asynchronous, so we could open all the needed files (DB, - // journal, etc.) asynchronously, and store them in a hash table - // that would be used here. - base::File file = - WebDatabaseHost::GetInstance().OpenFile(file_name, requested_flags); - - if (!file.IsValid()) { - // TODO(pwnall): Figure out if we can remove the fallback to read-only. - if (!(requested_flags & SQLITE_OPEN_READWRITE)) { - // The SQLite API requires that pMethods is set to null even if the open - // call returns a failure status. - result_file->pMethods = nullptr; - return SQLITE_CANTOPEN; - } - - int new_flags = - (requested_flags & ~SQLITE_OPEN_READWRITE) | SQLITE_OPEN_READONLY; - return Open(full_path, result_file, new_flags, granted_flags); - } - - SandboxedVfsFile::Create(std::move(file), std::move(file_name), this, - result_file); - if (granted_flags) - *granted_flags = requested_flags; - return SQLITE_OK; -} - -int SandboxedVfs::Delete(const char* full_path, int sync_dir) { - DCHECK(full_path); - return WebDatabaseHost::GetInstance().DeleteFile( - StringFromFullPath(full_path), sync_dir); -} - -int SandboxedVfs::Access(const char* full_path, int flags, int* result) { - DCHECK(full_path); - DCHECK(result); - int32_t attributes = WebDatabaseHost::GetInstance().GetFileAttributes( - StringFromFullPath(full_path)); - - // TODO(pwnall): Make the mojo interface portable across OSes, instead of - // messing around with OS-dependent constants here. - -#if defined(OS_WIN) - const bool file_exists = - static_cast<DWORD>(attributes) != INVALID_FILE_ATTRIBUTES; -#else - const bool file_exists = attributes >= 0; -#endif // defined(OS_WIN) - - if (!file_exists) { - *result = 0; - return SQLITE_OK; - } - -#if defined(OS_WIN) - const bool can_read = true; - const bool can_write = (attributes & FILE_ATTRIBUTE_READONLY) == 0; -#else - const bool can_read = (attributes & R_OK) != 0; - const bool can_write = (attributes & W_OK) != 0; -#endif // defined(OS_WIN) - - switch (flags) { - case SQLITE_ACCESS_EXISTS: - *result = 1; - break; - case SQLITE_ACCESS_READ: - *result = can_read ? 1 : 0; - break; - case SQLITE_ACCESS_READWRITE: - *result = (can_read && can_write) ? 1 : 0; - break; - default: - NOTREACHED() << "Unsupported xAccess flags: " << flags; - return SQLITE_ERROR; - } - return SQLITE_OK; -} - -int SandboxedVfs::FullPathname(const char* file_path, - int result_size, - char* result) { - DCHECK(file_path); - DCHECK_GT(result_size, 0); - DCHECK(result); - - // Renderer processes cannot access files directly, so it doesn't make sense - // to expose full paths here. - size_t file_path_size = std::strlen(file_path) + 1; - if (static_cast<size_t>(result_size) < file_path_size) - return SQLITE_CANTOPEN; - std::memcpy(result, file_path, file_path_size); - return SQLITE_OK; -} - -int SandboxedVfs::Randomness(int result_size, char* result) { - DCHECK_GT(result_size, 0); - DCHECK(result); - - // TODO(pwnall): Figure out if we need a real implementation. - std::memset(result, 0, result_size); - return result_size; -} - -int SandboxedVfs::Sleep(int microseconds) { - DCHECK_GE(microseconds, 0); - base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(microseconds)); - return SQLITE_OK; -} - -int SandboxedVfs::GetLastError(int message_size, char* message) const { - DCHECK_GE(message_size, 0); - DCHECK(message_size == 0 || message); - - std::string error_string = base::File::ErrorToString(last_error_); - size_t error_string_size = error_string.length() + 1; - size_t copy_length = - std::min(static_cast<size_t>(message_size), error_string_size); - std::memcpy(message, error_string.c_str(), copy_length); - // The return value is zero if the message fits in the buffer, and non-zero if - // it does not fit. - return copy_length != error_string_size; -} - -int SandboxedVfs::CurrentTimeInt64(sqlite3_int64* result_ms) { - DCHECK(result_ms); - - base::TimeDelta delta = base::Time::Now() - sqlite_epoch_; - *result_ms = delta.InMilliseconds(); - return SQLITE_OK; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h deleted file mode 100644 index 2b2c9ac..0000000 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h +++ /dev/null
@@ -1,71 +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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_H_ - -#include <tuple> - -#include "base/files/file.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -#include "third_party/sqlite/sqlite3.h" - -namespace blink { - -class Platform; - -// SQLite VFS implementation that works in the Chrome renderer sandbox. -// -// Instances are thread-friendly, and expected to be used on Blink's database -// thread. -class SandboxedVfs { - USING_FAST_MALLOC(SandboxedVfs); - - public: - // Factory method for the singleton instance. - static SandboxedVfs& GetInstance(); - - ~SandboxedVfs() = delete; - - // Opens a database file. - // - // Returns a SQLite status and a SQLite connection. If the status is not - // SQLITE_OK, the returned connection is null. - std::tuple<int, sqlite3*> OpenDatabase(const String& filename); - - // sqlite3_vfs implementation. - int Open(const char* full_path, - sqlite3_file* result_file, - int requested_flags, - int* granted_flags); - int Delete(const char* full_path, int sync_dir); - int Access(const char* full_path, int flags, int* result); - int FullPathname(const char* file_path, int result_size, char* result); - int Randomness(int result_size, char* result); - int Sleep(int microseconds); - int GetLastError(int message_size, char* message) const; - int CurrentTimeInt64(sqlite3_int64* result_ms); - - // Used by SandboxedVfsFile. - Platform* GetPlatform() { return platform_; } - void SetLastError(base::File::Error error) { this->last_error_ = error; } - - private: - // Use GetInstance() instead of constructing this directly. - SandboxedVfs(); - - // Registers the VFS with SQLite. Failures are silently ignored. - void RegisterVfs(); - - sqlite3_vfs sandboxed_vfs_; - const base::Time sqlite_epoch_; - Platform* const platform_; - base::File::Error last_error_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_H_
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.cc new file mode 100644 index 0000000..fe6358b --- /dev/null +++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.cc
@@ -0,0 +1,94 @@ +// 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/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.h" + +#include <tuple> + +#include "base/check_op.h" +#include "base/files/file_path.h" +#include "build/build_config.h" +#include "third_party/blink/renderer/modules/webdatabase/web_database_host.h" +#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +#if defined(OS_WIN) +#include <windows.h> +#endif + +namespace blink { + +namespace { + +// Converts a SQLite full file path to a Blink string. +// +// The argument is guaranteed to be the result of a FullPathname() call, with +// an optional suffix. The suffix always starts with "-". +String StringFromFullPath(const base::FilePath& file_path) { + return String::FromUTF8(file_path.AsUTF8Unsafe()); +} + +} // namespace + +SandboxedVfsDelegate::SandboxedVfsDelegate() = default; + +SandboxedVfsDelegate::~SandboxedVfsDelegate() = default; + +base::File SandboxedVfsDelegate::OpenFile(const base::FilePath& file_path, + int sqlite_requested_flags) { + DCHECK(!file_path.empty()) + << "WebSQL does not support creating temporary file names"; + DCHECK_EQ(0, sqlite_requested_flags & SQLITE_OPEN_DELETEONCLOSE) + << "SQLITE_OPEN_DELETEONCLOSE should not be used by WebSQL"; + DCHECK_EQ(0, sqlite_requested_flags & SQLITE_OPEN_EXCLUSIVE) + << "SQLITE_OPEN_EXCLUSIVE should not be used by WebSQL"; + + String file_name = StringFromFullPath(file_path); + return WebDatabaseHost::GetInstance().OpenFile(file_name, + sqlite_requested_flags); +} + +int SandboxedVfsDelegate::DeleteFile(const base::FilePath& file_path, + bool sync_dir) { + return WebDatabaseHost::GetInstance().DeleteFile( + StringFromFullPath(file_path), sync_dir); +} + +base::Optional<sql::SandboxedVfs::PathAccessInfo> +SandboxedVfsDelegate::GetPathAccess(const base::FilePath& file_path) { + int32_t attributes = WebDatabaseHost::GetInstance().GetFileAttributes( + StringFromFullPath(file_path)); + + // TODO(pwnall): Make the mojo interface portable across OSes, instead of + // messing around with OS-dependent constants here. + +#if defined(OS_WIN) + const bool file_exists = + static_cast<DWORD>(attributes) != INVALID_FILE_ATTRIBUTES; +#else + const bool file_exists = attributes >= 0; +#endif // defined(OS_WIN) + + if (!file_exists) + return base::nullopt; + + sql::SandboxedVfs::PathAccessInfo access; +#if defined(OS_WIN) + access.can_read = true; + access.can_write = (attributes & FILE_ATTRIBUTE_READONLY) == 0; +#else + access.can_read = (attributes & R_OK) != 0; + access.can_write = (attributes & W_OK) != 0; +#endif // defined(OS_WIN) + return access; +} + +bool SandboxedVfsDelegate::SetFileLength(const base::FilePath& file_path, + base::File& file, + size_t size) { + return WebDatabaseHost::GetInstance().SetFileSize( + StringFromFullPath(file_path), size); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.h b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.h new file mode 100644 index 0000000..e20696a3 --- /dev/null +++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.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 THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_DELEGATE_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_DELEGATE_H_ + +#include "sql/sandboxed_vfs.h" + +namespace blink { + +class SandboxedVfsDelegate : public sql::SandboxedVfs::Delegate { + public: + SandboxedVfsDelegate(); + ~SandboxedVfsDelegate() override; + + // sql::SandboxedVfs::Delegate implementation: + base::File OpenFile(const base::FilePath& file_path, + int sqlite_requested_flags) override; + int DeleteFile(const base::FilePath& file_path, bool sync_dir) override; + base::Optional<sql::SandboxedVfs::PathAccessInfo> GetPathAccess( + const base::FilePath& file_path) override; + bool SetFileLength(const base::FilePath& file_path, + base::File& file, + size_t size) override; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQLITE_SANDBOXED_VFS_DELEGATE_H_
diff --git a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc index f978632..dedda1b 100644 --- a/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc +++ b/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc
@@ -27,14 +27,41 @@ #include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h" #include "base/notreached.h" +#include "sql/sandboxed_vfs.h" #include "third_party/blink/renderer/modules/webdatabase/database_authorizer.h" -#include "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h" +#include "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_delegate.h" #include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_log.h" #include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.h" #include "third_party/sqlite/sqlite3.h" namespace blink { +namespace { + +constexpr char kSqliteVfsName[] = "renderer_sandboxed_vfs"; + +std::tuple<int, sqlite3*> OpenDatabase(const String& filename) { + sql::SandboxedVfs::Register(kSqliteVfsName, + std::make_unique<SandboxedVfsDelegate>(), + /*make_default=*/false); + + sqlite3* connection; + constexpr int open_flags = + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_PRIVATECACHE; + int status = sqlite3_open_v2(filename.Utf8().c_str(), &connection, open_flags, + kSqliteVfsName); + if (status != SQLITE_OK) { + // SQLite creates a connection handle in most cases where open fails. + if (connection) { + sqlite3_close(connection); + connection = nullptr; + } + } + return {status, connection}; +} + +} // namespace + const int kSQLResultDone = SQLITE_DONE; const int kSQLResultOk = SQLITE_OK; const int kSQLResultRow = SQLITE_ROW; @@ -61,8 +88,11 @@ bool SQLiteDatabase::Open(const String& filename) { Close(); - std::tie(open_error_, db_) = - SandboxedVfs::GetInstance().OpenDatabase(filename); + // TODO(pwnall): This doesn't have to be synchronous. WebSQL's open sequence + // is asynchronous, so we could open all the needed files (DB, + // journal, etc.) asynchronously, and store them in a hash table + // that would be used here. + std::tie(open_error_, db_) = OpenDatabase(filename); if (open_error_ != SQLITE_OK) { DCHECK_EQ(db_, nullptr);
diff --git a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc index 6dc2e5a5..1ceb786 100644 --- a/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc +++ b/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc
@@ -772,15 +772,6 @@ dawn_view.mipLevel = webgpu_view->mipLevel(); dawn_view.origin = AsDawnType(&webgpu_view->origin()); - if (webgpu_view->hasArrayLayer()) { - device->AddConsoleWarning( - "GPUTextureCopyView.arrayLayer deprecated: use .origin.z"); - dawn_view.arrayLayer = webgpu_view->arrayLayer(); - } else { - dawn_view.arrayLayer = dawn_view.origin.z; - dawn_view.origin.z = 0; - } - return dawn_view; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc index 16697b5..d2ea6c7 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc
@@ -26,6 +26,7 @@ // TODO(crbug.com/1048603): We should validate that the extension_set is a // subset of the adapter's extension set. requested_device_properties.textureCompressionBC = + extension_set.Contains("texture-compression-bc") || extension_set.Contains("textureCompressionBC"); return requested_device_properties; @@ -72,6 +73,7 @@ void GPUAdapter::InitializeExtensionNameList() { DCHECK(extension_name_list_.IsEmpty()); if (adapter_properties_.textureCompressionBC) { + extension_name_list_.emplace_back("texture-compression-bc"); extension_name_list_.emplace_back("textureCompressionBC"); } }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl b/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl index 735742c..dbce239 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl
@@ -5,7 +5,9 @@ // https://gpuweb.github.io/gpuweb/ enum GPUExtensionName { - "textureCompressionBC", + "texture-compression-bc", + // Non-standard extension name string. Remove after a transition period. + "textureCompressionBC" }; [
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc b/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc index e0fd1b4..0aa8ed6 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc
@@ -58,13 +58,15 @@ entries = AsDawnType(webgpu_desc->entries()); } + std::string label; WGPUBindGroupDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; dawn_desc.layout = AsDawnType(webgpu_desc->layout()); dawn_desc.entryCount = entry_count; dawn_desc.entries = entries.get(); if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + label = webgpu_desc->label().Utf8(); + dawn_desc.label = label.c_str(); } return MakeGarbageCollected<GPUBindGroup>(
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc b/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc index 66d223d..9069f1de 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc
@@ -70,12 +70,14 @@ entries = AsDawnType(webgpu_desc->entries(), device); } + std::string label; WGPUBindGroupLayoutDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; dawn_desc.entryCount = entry_count; dawn_desc.entries = entries.get(); if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + label = webgpu_desc->label().Utf8(); + dawn_desc.label = label.c_str(); } return MakeGarbageCollected<GPUBindGroupLayout>(
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc b/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc index 5ac9e65b..70354f56e 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc
@@ -59,8 +59,10 @@ return true; } -WGPUBufferDescriptor AsDawnType(const GPUBufferDescriptor* webgpu_desc) { +WGPUBufferDescriptor AsDawnType(const GPUBufferDescriptor* webgpu_desc, + std::string* label) { DCHECK(webgpu_desc); + DCHECK(label); WGPUBufferDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; @@ -68,7 +70,8 @@ dawn_desc.size = webgpu_desc->size(); dawn_desc.mappedAtCreation = webgpu_desc->mappedAtCreation(); if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + *label = webgpu_desc->label().Utf8(); + dawn_desc.label = label->c_str(); } return dawn_desc; @@ -81,7 +84,8 @@ const GPUBufferDescriptor* webgpu_desc) { DCHECK(device); - WGPUBufferDescriptor dawn_desc = AsDawnType(webgpu_desc); + std::string label; + WGPUBufferDescriptor dawn_desc = AsDawnType(webgpu_desc, &label); return MakeGarbageCollected<GPUBuffer>( device, dawn_desc.size, dawn_desc.mappedAtCreation, device->GetProcs().deviceCreateBuffer(device->GetHandle(), &dawn_desc)); @@ -94,7 +98,8 @@ ExceptionState& exception_state) { DCHECK(device); - WGPUBufferDescriptor dawn_desc = AsDawnType(webgpu_desc); + std::string label; + WGPUBufferDescriptor dawn_desc = AsDawnType(webgpu_desc, &label); if (!ValidateRangeCreation(exception_state, "createBufferMapped", 0, dawn_desc.size, kLargestMappableSize)) { @@ -138,34 +143,6 @@ DawnObject<WGPUBuffer>::Trace(visitor); } -void GPUBuffer::setSubData(uint64_t dst_byte_offset, - const FlexibleArrayBufferView& src, - uint64_t src_byte_offset, - uint64_t byte_length, - ExceptionState& exception_state) { - device_->AddConsoleWarning( - "GPUBuffer.setSubData is deprecated: use GPUQueue.writeBuffer instead"); - - const uint8_t* src_base = - reinterpret_cast<const uint8_t*>(src.BaseAddressMaybeOnStack()); - size_t src_byte_length = src.ByteLengthAsSizeT(); - - if (src_byte_offset > src_byte_length) { - exception_state.ThrowRangeError("srcOffset is too large"); - return; - } - - if (byte_length == 0) { - byte_length = src_byte_length - src_byte_offset; - } else if (byte_length > src_byte_length - src_byte_offset) { - exception_state.ThrowRangeError("byteLength is too large"); - return; - } - - const uint8_t* data = &src_base[src_byte_offset]; - GetProcs().bufferSetSubData(GetHandle(), dst_byte_offset, byte_length, data); -} - void GPUBuffer::OnOldMapAsyncCallback(ScriptPromiseResolver* resolver, WGPUBufferMapAsyncStatus status, void* data,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_buffer.h b/third_party/blink/renderer/modules/webgpu/gpu_buffer.h index 28b69c121..fda61ec2 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_buffer.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_buffer.h
@@ -37,11 +37,6 @@ void Trace(Visitor* visitor) const override; // gpu_buffer.idl - void setSubData(uint64_t dst_byte_offset, - const FlexibleArrayBufferView& src, - uint64_t src_byte_offset, - uint64_t byte_length, - ExceptionState& exception_state); ScriptPromise mapAsync(ScriptState* script_state, uint32_t mode, uint64_t offset,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_buffer.idl b/third_party/blink/renderer/modules/webgpu/gpu_buffer.idl index c437769..ec40f85 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_buffer.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_buffer.idl
@@ -7,11 +7,6 @@ [ Exposed(Window WebGPU, Worker WebGPU) ] interface GPUBuffer { - [RaisesException] void setSubData( - GPUSize64 dstOffset, - [AllowShared, FlexibleArrayBufferView] ArrayBufferView src, - optional GPUSize64 srcOffset = 0, - optional GPUSize64 byteLength = 0); [CallWith=ScriptState, RaisesException] Promise<void> mapAsync( GPUMapModeFlags mode, optional GPUSize64 offset = 0,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc index 935c1a8..482c48f2 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
@@ -115,20 +115,23 @@ WGPUBufferCopyView dawn_view = {}; dawn_view.nextInChain = nullptr; dawn_view.buffer = webgpu_view->buffer()->GetHandle(); - dawn_view.offset = webgpu_view->offset(); - dawn_view.bytesPerRow = webgpu_view->bytesPerRow(); - dawn_view.rowsPerImage = webgpu_view->rowsPerImage(); + dawn_view.layout.offset = webgpu_view->offset(); + dawn_view.layout.bytesPerRow = webgpu_view->bytesPerRow(); + dawn_view.layout.rowsPerImage = webgpu_view->rowsPerImage(); return dawn_view; } WGPUCommandEncoderDescriptor AsDawnType( - const GPUCommandEncoderDescriptor* webgpu_desc) { + const GPUCommandEncoderDescriptor* webgpu_desc, + std::string* label) { DCHECK(webgpu_desc); + DCHECK(label); WGPUCommandEncoderDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + *label = webgpu_desc->label().Utf8(); + dawn_desc.label = label->c_str(); } return dawn_desc; @@ -144,10 +147,11 @@ DCHECK(webgpu_desc); ALLOW_UNUSED_LOCAL(webgpu_desc); + std::string label; WGPUCommandEncoderDescriptor dawn_desc = {}; const WGPUCommandEncoderDescriptor* dawn_desc_ptr = nullptr; if (webgpu_desc) { - dawn_desc = AsDawnType(webgpu_desc); + dawn_desc = AsDawnType(webgpu_desc, &label); dawn_desc_ptr = &dawn_desc; } @@ -189,11 +193,13 @@ } } + std::string label; WGPURenderPassDescriptor dawn_desc = {}; dawn_desc.colorAttachmentCount = color_attachment_count; dawn_desc.colorAttachments = nullptr; if (descriptor->hasLabel()) { - dawn_desc.label = descriptor->label().Utf8().data(); + label = descriptor->label().Utf8(); + dawn_desc.label = label.c_str(); } std::unique_ptr<WGPURenderPassColorAttachmentDescriptor[]> color_attachments; @@ -218,9 +224,11 @@ GPUComputePassEncoder* GPUCommandEncoder::beginComputePass( const GPUComputePassDescriptor* descriptor) { + std::string label; WGPUComputePassDescriptor dawn_desc = {}; if (descriptor->hasLabel()) { - dawn_desc.label = descriptor->label().Utf8().data(); + label = descriptor->label().Utf8(); + dawn_desc.label = label.c_str(); } return MakeGarbageCollected<GPUComputePassEncoder>( @@ -302,8 +310,8 @@ } void GPUCommandEncoder::pushDebugGroup(String groupLabel) { - GetProcs().commandEncoderPushDebugGroup(GetHandle(), - groupLabel.Utf8().data()); + std::string label = groupLabel.Utf8(); + GetProcs().commandEncoderPushDebugGroup(GetHandle(), label.c_str()); } void GPUCommandEncoder::popDebugGroup() { @@ -311,15 +319,17 @@ } void GPUCommandEncoder::insertDebugMarker(String markerLabel) { - GetProcs().commandEncoderInsertDebugMarker(GetHandle(), - markerLabel.Utf8().data()); + std::string label = markerLabel.Utf8(); + GetProcs().commandEncoderInsertDebugMarker(GetHandle(), label.c_str()); } GPUCommandBuffer* GPUCommandEncoder::finish( const GPUCommandBufferDescriptor* descriptor) { + std::string label; WGPUCommandBufferDescriptor dawn_desc = {}; if (descriptor->hasLabel()) { - dawn_desc.label = descriptor->label().Utf8().data(); + label = descriptor->label().Utf8(); + dawn_desc.label = label.c_str(); } return MakeGarbageCollected<GPUCommandBuffer>(
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc index 0c875bb..f8baf246 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.cc
@@ -54,8 +54,8 @@ } void GPUComputePassEncoder::pushDebugGroup(String groupLabel) { - GetProcs().computePassEncoderPushDebugGroup(GetHandle(), - groupLabel.Utf8().data()); + std::string label = groupLabel.Utf8(); + GetProcs().computePassEncoderPushDebugGroup(GetHandle(), label.c_str()); } void GPUComputePassEncoder::popDebugGroup() { @@ -63,8 +63,8 @@ } void GPUComputePassEncoder::insertDebugMarker(String markerLabel) { - GetProcs().computePassEncoderInsertDebugMarker(GetHandle(), - markerLabel.Utf8().data()); + std::string label = markerLabel.Utf8(); + GetProcs().computePassEncoderInsertDebugMarker(GetHandle(), label.c_str()); } void GPUComputePassEncoder::setPipeline(GPUComputePipeline* pipeline) {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc b/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc index 46746b71..708ed36 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc
@@ -21,13 +21,15 @@ DCHECK(device); DCHECK(webgpu_desc); + std::string label; WGPUComputePipelineDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; if (webgpu_desc->hasLayout()) { dawn_desc.layout = AsDawnType(webgpu_desc->layout()); } if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + label = webgpu_desc->label().Utf8(); + dawn_desc.label = label.c_str(); } auto compute_stage = AsDawnType(webgpu_desc->computeStage());
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc index 8700565..d028019 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -43,6 +43,7 @@ client_id, dawn_control_client->GetInterface()->GetDevice(client_id)), adapter_(adapter), + extension_name_list_(descriptor->extensions()), queue_(MakeGarbageCollected<GPUQueue>( this, GetProcs().deviceGetDefaultQueue(GetHandle()))), @@ -53,6 +54,12 @@ GetProcs().deviceSetUncapturedErrorCallback( GetHandle(), error_callback_->UnboundRepeatingCallback(), error_callback_->AsUserdata()); + + if (extension_name_list_.Contains("textureCompressionBC")) { + AddConsoleWarning( + "The extension name 'textureCompressionBC' is deprecated: use " + "'texture-compression-bc' instead"); + } } GPUDevice::~GPUDevice() { @@ -117,6 +124,10 @@ return adapter_; } +Vector<String> GPUDevice::extensions() const { + return extension_name_list_; +} + ScriptPromise GPUDevice::lost(ScriptState* script_state) { return lost_property_->Promise(script_state->World()); }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.h b/third_party/blink/renderer/modules/webgpu/gpu_device.h index d0773e3..e7ac2fcc 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.h
@@ -64,6 +64,7 @@ // gpu_device.idl GPUAdapter* adapter() const; + Vector<String> extensions() const; ScriptPromise lost(ScriptState* script_state); GPUQueue* defaultQueue(); @@ -120,6 +121,7 @@ const char* message); Member<GPUAdapter> adapter_; + Vector<String> extension_name_list_; Member<GPUQueue> queue_; Member<LostProperty> lost_property_; std::unique_ptr<
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.idl b/third_party/blink/renderer/modules/webgpu/gpu_device.idl index f6a4b32..c25e421 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.idl
@@ -8,6 +8,7 @@ Exposed(Window WebGPU, Worker WebGPU) ] interface GPUDevice : EventTarget { [SameObject] readonly attribute GPUAdapter adapter; + readonly attribute FrozenArray<GPUExtensionName> extensions; [CallWith=ScriptState] readonly attribute Promise<GPUDeviceLostInfo> lost; [SameObject] readonly attribute GPUQueue defaultQueue;
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc b/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc index bd3760a..146e8214 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc
@@ -25,12 +25,14 @@ bind_group_layout_count != 0 ? AsDawnType(webgpu_desc->bindGroupLayouts()) : nullptr; + std::string label; WGPUPipelineLayoutDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; dawn_desc.bindGroupLayoutCount = bind_group_layout_count; dawn_desc.bindGroupLayouts = bind_group_layouts.get(); if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + label = webgpu_desc->label().Utf8(); + dawn_desc.label = label.c_str(); } return MakeGarbageCollected<GPUPipelineLayout>(
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc index 9041bec..22ec1ed 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -161,11 +161,13 @@ GPUFence* GPUQueue::createFence(const GPUFenceDescriptor* descriptor) { DCHECK(descriptor); + std::string label; WGPUFenceDescriptor desc = {}; desc.nextInChain = nullptr; desc.initialValue = descriptor->initialValue(); if (descriptor->hasLabel()) { - desc.label = descriptor->label().Utf8().data(); + label = descriptor->label().Utf8(); + desc.label = label.c_str(); } return MakeGarbageCollected<GPUFence>( @@ -436,9 +438,9 @@ WGPUBufferCopyView dawn_intermediate = {}; dawn_intermediate.nextInChain = nullptr; dawn_intermediate.buffer = buffer; - dawn_intermediate.offset = 0; - dawn_intermediate.bytesPerRow = info.wgpu_bytes_per_row; - dawn_intermediate.rowsPerImage = image->height(); + dawn_intermediate.layout.offset = 0; + dawn_intermediate.layout.bytesPerRow = info.wgpu_bytes_per_row; + dawn_intermediate.layout.rowsPerImage = image->height(); WGPUCommandEncoder encoder = GetProcs().deviceCreateCommandEncoder(device_->GetHandle(), nullptr);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc index d53a752..cfacee8 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc
@@ -32,6 +32,7 @@ AsDawnEnum<WGPUTextureFormat>(webgpu_desc->depthStencilFormat()); } + std::string label; WGPURenderBundleEncoderDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; dawn_desc.colorFormatsCount = color_formats_count; @@ -39,7 +40,8 @@ dawn_desc.depthStencilFormat = depth_stencil_format; dawn_desc.sampleCount = webgpu_desc->sampleCount(); if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + label = webgpu_desc->label().Utf8(); + dawn_desc.label = label.c_str(); } return MakeGarbageCollected<GPURenderBundleEncoder>( @@ -90,8 +92,8 @@ } void GPURenderBundleEncoder::pushDebugGroup(String groupLabel) { - GetProcs().renderBundleEncoderPushDebugGroup(GetHandle(), - groupLabel.Utf8().data()); + std::string label = groupLabel.Utf8(); + GetProcs().renderBundleEncoderPushDebugGroup(GetHandle(), label.c_str()); } void GPURenderBundleEncoder::popDebugGroup() { @@ -99,8 +101,8 @@ } void GPURenderBundleEncoder::insertDebugMarker(String markerLabel) { - GetProcs().renderBundleEncoderInsertDebugMarker(GetHandle(), - markerLabel.Utf8().data()); + std::string label = markerLabel.Utf8(); + GetProcs().renderBundleEncoderInsertDebugMarker(GetHandle(), label.c_str()); } void GPURenderBundleEncoder::setPipeline(GPURenderPipeline* pipeline) { @@ -154,10 +156,12 @@ GPURenderBundle* GPURenderBundleEncoder::finish( const GPURenderBundleDescriptor* webgpu_desc) { + std::string label; WGPURenderBundleDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + label = webgpu_desc->label().Utf8(); + dawn_desc.label = label.c_str(); } WGPURenderBundle render_bundle =
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc index 5e74e12..fba815fa 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
@@ -58,8 +58,8 @@ } void GPURenderPassEncoder::pushDebugGroup(String groupLabel) { - GetProcs().renderPassEncoderPushDebugGroup(GetHandle(), - groupLabel.Utf8().data()); + std::string label = groupLabel.Utf8(); + GetProcs().renderPassEncoderPushDebugGroup(GetHandle(), label.c_str()); } void GPURenderPassEncoder::popDebugGroup() { @@ -67,8 +67,8 @@ } void GPURenderPassEncoder::insertDebugMarker(String markerLabel) { - GetProcs().renderPassEncoderInsertDebugMarker(GetHandle(), - markerLabel.Utf8().data()); + std::string label = markerLabel.Utf8(); + GetProcs().renderPassEncoderInsertDebugMarker(GetHandle(), label.c_str()); } void GPURenderPassEncoder::setPipeline(GPURenderPipeline* pipeline) {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc b/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc index d22361fc..2b444204 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc
@@ -214,13 +214,15 @@ DCHECK(device); DCHECK(webgpu_desc); + std::string label; WGPURenderPipelineDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; if (webgpu_desc->hasLayout()) { dawn_desc.layout = AsDawnType(webgpu_desc->layout()); } if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + label = webgpu_desc->label().Utf8(); + dawn_desc.label = label.c_str(); } OwnedProgrammableStageDescriptor vertex_stage_info =
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc b/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc index 63b331d..2035143 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc
@@ -12,8 +12,10 @@ namespace { -WGPUSamplerDescriptor AsDawnType(const GPUSamplerDescriptor* webgpu_desc) { +WGPUSamplerDescriptor AsDawnType(const GPUSamplerDescriptor* webgpu_desc, + std::string* label) { DCHECK(webgpu_desc); + DCHECK(label); WGPUSamplerDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; @@ -33,7 +35,8 @@ dawn_desc.compare = AsDawnEnum<WGPUCompareFunction>(webgpu_desc->compare()); } if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + *label = webgpu_desc->label().Utf8(); + dawn_desc.label = label->c_str(); } return dawn_desc; @@ -46,7 +49,8 @@ const GPUSamplerDescriptor* webgpu_desc) { DCHECK(device); DCHECK(webgpu_desc); - WGPUSamplerDescriptor dawn_desc = AsDawnType(webgpu_desc); + std::string label; + WGPUSamplerDescriptor dawn_desc = AsDawnType(webgpu_desc, &label); return MakeGarbageCollected<GPUSampler>( device, device->GetProcs().deviceCreateSampler(device->GetHandle(), &dawn_desc));
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc b/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc index 2733049..234afd70 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc
@@ -18,10 +18,11 @@ DCHECK(device); DCHECK(webgpu_desc); - WGPUShaderModuleDescriptor dawn_desc = {}; + std::string wgsl_code; WGPUShaderModuleWGSLDescriptor wgsl_desc = {}; WGPUShaderModuleSPIRVDescriptor spirv_desc = {}; - std::string wgsl_code; + std::string label; + WGPUShaderModuleDescriptor dawn_desc = {}; auto wgsl_or_spirv = webgpu_desc->code(); if (wgsl_or_spirv.IsUSVString()) { @@ -49,7 +50,6 @@ dawn_desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&spirv_desc); } - std::string label; if (webgpu_desc->hasLabel()) { label = webgpu_desc->label().Utf8(); dawn_desc.label = label.c_str();
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_texture.cc b/third_party/blink/renderer/modules/webgpu/gpu_texture.cc index b4e75fe2..3a23131 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_texture.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_texture.cc
@@ -15,8 +15,11 @@ namespace { WGPUTextureDescriptor AsDawnType(const GPUTextureDescriptor* webgpu_desc, + std::string* label, GPUDevice* device) { DCHECK(webgpu_desc); + DCHECK(label); + DCHECK(device); WGPUTextureDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; @@ -24,30 +27,23 @@ dawn_desc.dimension = AsDawnEnum<WGPUTextureDimension>(webgpu_desc->dimension()); dawn_desc.size = AsDawnType(&webgpu_desc->size()); - - if (webgpu_desc->hasArrayLayerCount()) { - device->AddConsoleWarning("arrayLayerCount is deprecated: use size.depth"); - dawn_desc.arrayLayerCount = webgpu_desc->arrayLayerCount(); - } else { - if (dawn_desc.dimension == WGPUTextureDimension_2D) { - dawn_desc.arrayLayerCount = dawn_desc.size.depth; - dawn_desc.size.depth = 1; - } - } - dawn_desc.format = AsDawnEnum<WGPUTextureFormat>(webgpu_desc->format()); dawn_desc.mipLevelCount = webgpu_desc->mipLevelCount(); dawn_desc.sampleCount = webgpu_desc->sampleCount(); + if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + *label = webgpu_desc->label().Utf8(); + dawn_desc.label = label->c_str(); } return dawn_desc; } WGPUTextureViewDescriptor AsDawnType( - const GPUTextureViewDescriptor* webgpu_desc) { + const GPUTextureViewDescriptor* webgpu_desc, + std::string* label) { DCHECK(webgpu_desc); + DCHECK(label); WGPUTextureViewDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; @@ -60,7 +56,8 @@ dawn_desc.arrayLayerCount = webgpu_desc->arrayLayerCount(); dawn_desc.aspect = AsDawnEnum<WGPUTextureAspect>(webgpu_desc->aspect()); if (webgpu_desc->hasLabel()) { - dawn_desc.label = webgpu_desc->label().Utf8().data(); + *label = webgpu_desc->label().Utf8(); + dawn_desc.label = label->c_str(); } return dawn_desc; @@ -84,7 +81,8 @@ return nullptr; } - WGPUTextureDescriptor dawn_desc = AsDawnType(webgpu_desc, device); + std::string label; + WGPUTextureDescriptor dawn_desc = AsDawnType(webgpu_desc, &label, device); return MakeGarbageCollected<GPUTexture>( device, @@ -108,7 +106,8 @@ const GPUTextureViewDescriptor* webgpu_desc) { DCHECK(webgpu_desc); - WGPUTextureViewDescriptor dawn_desc = AsDawnType(webgpu_desc); + std::string label; + WGPUTextureViewDescriptor dawn_desc = AsDawnType(webgpu_desc, &label); return MakeGarbageCollected<GPUTextureView>( device_, GetProcs().textureCreateView(GetHandle(), &dawn_desc)); }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl b/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl index 1d913ba53..16e2295 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl
@@ -7,6 +7,5 @@ dictionary GPUTextureCopyView { required GPUTexture texture; GPUSize32 mipLevel = 0; - GPUSize32 arrayLayer; GPUOrigin3D origin = {}; };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl b/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl index 54a1fd8..0371a8b0 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl
@@ -6,8 +6,6 @@ dictionary GPUTextureDescriptor : GPUObjectDescriptorBase { required GPUExtent3D size; - // TODO(crbug.com/1069302): arrayLayerCount is deprecated; remove it. - unsigned long arrayLayerCount; GPUIntegerCoordinate mipLevelCount = 1; GPUSize32 sampleCount = 1; GPUTextureDimension dimension = "2d";
diff --git a/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc b/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc index 60aaa74..fa602811 100644 --- a/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc +++ b/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc
@@ -41,11 +41,13 @@ incoming_stream_->OnIncomingStreamClosed(fin_received); // TODO(ricea): Review this behaviour when adding detail to the specification. if (!sent_fin_) { + ScriptState::Scope scope(outgoing_stream_->GetScriptState()); outgoing_stream_->Reset(); } } void BidirectionalStream::Reset() { + ScriptState::Scope scope(outgoing_stream_->GetScriptState()); outgoing_stream_->Reset(); incoming_stream_->Reset(); } @@ -79,6 +81,7 @@ void BidirectionalStream::OnIncomingStreamAbort() { quic_transport_->ForgetStream(stream_id_); + ScriptState::Scope scope(outgoing_stream_->GetScriptState()); outgoing_stream_->Reset(); }
diff --git a/third_party/blink/renderer/modules/webtransport/outgoing_stream.h b/third_party/blink/renderer/modules/webtransport/outgoing_stream.h index aa00451..d24b2d5 100644 --- a/third_party/blink/renderer/modules/webtransport/outgoing_stream.h +++ b/third_party/blink/renderer/modules/webtransport/outgoing_stream.h
@@ -68,6 +68,8 @@ ScriptPromise WritingAborted() const { return writing_aborted_; } + ScriptState* GetScriptState() { return script_state_; } + void AbortWriting(StreamAbortInfo*); // Called from QuicTransport via a WebTransportStream. Expects a JavaScript
diff --git a/third_party/blink/renderer/modules/xr/xr_system.cc b/third_party/blink/renderer/modules/xr/xr_system.cc index 87467611..29b66b61 100644 --- a/third_party/blink/renderer/modules/xr/xr_system.cc +++ b/third_party/blink/renderer/modules/xr/xr_system.cc
@@ -650,7 +650,7 @@ ScopedAllowFullscreen scope(ScopedAllowFullscreen::kXrOverlay); Fullscreen::RequestFullscreen(*element, options, - Fullscreen::RequestType::kUnprefixed); + FullscreenRequestType::kUnprefixed); } void XRSystem::OverlayFullscreenEventManager::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index cd64432..c0b7fd4 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1552,6 +1552,7 @@ ":platform_export", "//mojo/public/cpp/base", "//mojo/public/cpp/bindings", + "//services/network/public/mojom:mojom_headers", "//third_party/blink/renderer/platform/blob", "//third_party/blink/renderer/platform/heap", "//third_party/blink/renderer/platform/instrumentation", @@ -1575,6 +1576,7 @@ "//media/capture:capture_switches", "//media/capture/mojom:video_capture", "//mojo/public/cpp/bindings:wtf_support", + "//services/network/public/mojom:mojom_shared", "//services/service_manager/public/cpp", "//services/viz/public/cpp/gpu", "//skia",
diff --git a/third_party/blink/renderer/platform/fonts/DEPS b/third_party/blink/renderer/platform/fonts/DEPS index 3197d9e..16e13d2 100644 --- a/third_party/blink/renderer/platform/fonts/DEPS +++ b/third_party/blink/renderer/platform/fonts/DEPS
@@ -15,6 +15,7 @@ "+third_party/blink/renderer/platform/instrumentation", "+third_party/blink/renderer/platform/language.h", "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/privacy_budget", "+third_party/blink/renderer/platform/resolution_units.h", "+third_party/blink/renderer/platform/runtime_enabled_features.h", "+third_party/blink/renderer/platform/scheduler/public",
diff --git a/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc b/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc index 6a60395df..23a1e4f67 100644 --- a/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc +++ b/third_party/blink/renderer/platform/fonts/font_matching_metrics.cc
@@ -7,6 +7,8 @@ #include "services/metrics/public/cpp/metrics_utils.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_token.h" +#include "third_party/blink/renderer/platform/privacy_budget/identifiability_digest_helpers.h" namespace { @@ -128,21 +130,20 @@ } void FontMatchingMetrics::PublishIdentifiabilityMetrics() { + IdentifiabilityMetricBuilder builder(source_id_); + for (const auto& entry : font_lookups_) { const LocalFontLookupKey& key = entry.key; const LocalFontLookupResult& result = entry.value; - uint64_t input_digest = blink::IdentifiabilityDigestHelper( - key.name_hash, key.fallback_character, key.font_selection_request_hash); - uint64_t output_digest = blink::IdentifiabilityDigestHelper( - result.hash, result.check_type, result.is_loading_fallback); + IdentifiableToken input_token(key.name_hash, key.fallback_character, + key.font_selection_request_hash); + IdentifiableToken output_token(result.hash, result.check_type, + result.is_loading_fallback); - blink::IdentifiabilityMetricBuilder( - base::UkmSourceId::FromInt64(source_id_)) - .Set(IdentifiableSurface::FromTypeAndInput( - IdentifiableSurface::Type::kLocalFontLookup, input_digest), - output_digest) - .Record(ukm_recorder_); + builder.Set(IdentifiableSurface::FromTypeAndToken( + IdentifiableSurface::Type::kLocalFontLookup, input_token), + output_token); } font_lookups_.clear(); @@ -150,18 +151,17 @@ const GenericFontLookupKey& key = entry.key; const unsigned& result = entry.value; - uint64_t input_digest = blink::IdentifiabilityDigestHelper( - key.generic_font_family_name_hash, key.script, key.generic_family_type); - uint64_t output_digest = blink::IdentifiabilityDigestHelper(result); + IdentifiableToken input_token(key.generic_font_family_name_hash, key.script, + key.generic_family_type); + IdentifiableToken output_token(result); - blink::IdentifiabilityMetricBuilder( - base::UkmSourceId::FromInt64(source_id_)) - .Set(IdentifiableSurface::FromTypeAndInput( - IdentifiableSurface::Type::kGenericFontLookup, input_digest), - output_digest) - .Record(ukm_recorder_); + builder.Set(IdentifiableSurface::FromTypeAndToken( + IdentifiableSurface::Type::kGenericFontLookup, input_token), + output_token); } generic_font_lookups_.clear(); + + builder.Record(ukm_recorder_); } void FontMatchingMetrics::PublishUkmMetrics() {
diff --git a/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/third_party/blink/renderer/platform/graphics/graphics_layer.cc index d5ac3c1..38e5344 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_layer.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -565,7 +565,8 @@ } void GraphicsLayer::SetContentsOpaqueForText(bool opaque) { - CcLayer().SetContentsOpaqueForText(opaque); + // TODO(crbug.com/1113269): Temporarily disable this optimization. + // CcLayer().SetContentsOpaqueForText(opaque); } void GraphicsLayer::SetHitTestable(bool should_hit_test) {
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc index e269afe..49eaf08 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
@@ -90,14 +90,21 @@ }); } +ThreadHeapStatsCollector::Event::Event() { + static std::atomic<size_t> counter{0}; + unique_id = counter.fetch_add(1); +} + void ThreadHeapStatsCollector::NotifyMarkingStarted( BlinkGC::CollectionType collection_type, - BlinkGC::GCReason reason) { + BlinkGC::GCReason reason, + bool is_forced_gc) { DCHECK(!is_started_); DCHECK(current_.marking_time().is_zero()); is_started_ = true; current_.reason = reason; current_.collection_type = collection_type; + current_.is_forced_gc = is_forced_gc; } void ThreadHeapStatsCollector::NotifyMarkingCompleted(size_t marked_bytes) {
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/third_party/blink/renderer/platform/heap/heap_stats_collector.h index ef693eb..081f4f0 100644 --- a/third_party/blink/renderer/platform/heap/heap_stats_collector.h +++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
@@ -220,6 +220,8 @@ // GCs. E.g., |atomic_marking_time()| report the marking time of the atomic // phase, independent of whether the GC was a stand-alone or unified heap GC. struct PLATFORM_EXPORT Event { + Event(); + // Overall time spent in the GC cycle. This includes marking time as well as // sweeping time. base::TimeDelta gc_cycle_time() const; @@ -267,6 +269,7 @@ double marking_time_in_bytes_per_second() const; // Marked bytes collected during sweeping. + size_t unique_id = -1; size_t marked_bytes = 0; size_t compaction_freed_bytes = 0; size_t compaction_freed_pages = 0; @@ -280,10 +283,13 @@ size_t partition_alloc_bytes_before_sweeping = 0; double live_object_rate = 0; base::TimeDelta gc_nested_in_v8; + bool is_forced_gc = true; }; // Indicates a new garbage collection cycle. - void NotifyMarkingStarted(BlinkGC::CollectionType, BlinkGC::GCReason); + void NotifyMarkingStarted(BlinkGC::CollectionType, + BlinkGC::GCReason, + bool is_forced_gc); // Indicates that marking of the current garbage collection cycle is // completed. @@ -437,8 +443,10 @@ ThreadHeapStatsCollector::ScopeContext scope_category> void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::StopTrace() { - TRACE_EVENT_END0(TraceCategory(), - ToString(id_, tracer_->current_.collection_type)); + TRACE_EVENT_END2(TraceCategory(), + ToString(id_, tracer_->current_.collection_type), "epoch", + tracer_->current_.unique_id, "forced", + tracer_->current_.is_forced_gc); } template <ThreadHeapStatsCollector::TraceCategory trace_category,
diff --git a/third_party/blink/renderer/platform/heap/member.h b/third_party/blink/renderer/platform/heap/member.h index 1610b12..5cb57a8 100644 --- a/third_party/blink/renderer/platform/heap/member.h +++ b/third_party/blink/renderer/platform/heap/member.h
@@ -244,9 +244,14 @@ #endif // DCHECK_IS_ON() } + template <TracenessMemberConfiguration = tracenessConfiguration> ALWAYS_INLINE void SetRaw(T* raw) { WTF::AsAtomicPtr(&raw_)->store(raw, std::memory_order_relaxed); } + template <> + ALWAYS_INLINE void SetRaw<TracenessMemberConfiguration::kUntraced>(T* raw) { + raw_ = raw; + } ALWAYS_INLINE T* GetRaw() const { return raw_; } private:
diff --git a/third_party/blink/renderer/platform/heap/test/heap_stats_collector_test.cc b/third_party/blink/renderer/platform/heap/test/heap_stats_collector_test.cc index 050cabb..5ee689e 100644 --- a/third_party/blink/renderer/platform/heap/test/heap_stats_collector_test.cc +++ b/third_party/blink/renderer/platform/heap/test/heap_stats_collector_test.cc
@@ -22,7 +22,8 @@ TEST(ThreadHeapStatsCollectorTest, InitialEmpty) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); for (int i = 0; i < ThreadHeapStatsCollector::kNumScopeIds; i++) { EXPECT_EQ(base::TimeDelta(), stats_collector.current().scope_data[i]); } @@ -33,7 +34,8 @@ TEST(ThreadHeapStatsCollectorTest, IncreaseScopeTime) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStep, base::TimeDelta::FromMilliseconds(1)); @@ -47,7 +49,8 @@ TEST(ThreadHeapStatsCollectorTest, StopMovesCurrentToPrevious) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStep, base::TimeDelta::FromMilliseconds(1)); @@ -61,7 +64,8 @@ TEST(ThreadHeapStatsCollectorTest, StopResetsCurrent) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStep, base::TimeDelta::FromMilliseconds(1)); @@ -76,7 +80,8 @@ ThreadHeapStatsCollector stats_collector; EXPECT_FALSE(stats_collector.is_started()); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); EXPECT_TRUE(stats_collector.is_started()); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); @@ -93,7 +98,8 @@ TEST(ThreadHeapStatsCollectorTest, UpdateReason) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.UpdateReason(BlinkGC::GCReason::kForcedGCForTesting); stats_collector.NotifySweepingCompleted(); @@ -104,7 +110,8 @@ TEST(ThreadHeapStatsCollectorTest, InitialEstimatedObjectSize) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); EXPECT_EQ(0u, stats_collector.object_size_in_bytes()); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); @@ -113,7 +120,8 @@ TEST(ThreadHeapStatsCollectorTest, EstimatedObjectSizeNoMarkedBytes) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseAllocatedObjectSizeForTesting(512); EXPECT_EQ(512u, stats_collector.object_size_in_bytes()); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); @@ -123,11 +131,13 @@ TEST(ThreadHeapStatsCollectorTest, EstimatedObjectSizeWithMarkedBytes) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); stats_collector.NotifySweepingCompleted(); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.IncreaseAllocatedObjectSizeForTesting(512); EXPECT_EQ(640u, stats_collector.object_size_in_bytes()); @@ -138,11 +148,13 @@ EstimatedObjectSizeDoNotCountCurrentlyMarkedBytes) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); stats_collector.NotifySweepingCompleted(); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); // Currently marked bytes should not account to the estimated object size. stats_collector.IncreaseAllocatedObjectSizeForTesting(512); @@ -155,7 +167,8 @@ // garbage collection triggers. ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); } @@ -163,14 +176,16 @@ TEST(ThreadHeapStatsCollectorTest, EstimatedMarkingTime1) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure, base::TimeDelta::FromSeconds(1)); stats_collector.NotifyMarkingCompleted(1024); stats_collector.NotifySweepingCompleted(); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); } @@ -178,14 +193,16 @@ TEST(ThreadHeapStatsCollectorTest, EstimatedMarkingTime2) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure, base::TimeDelta::FromSeconds(1)); stats_collector.NotifyMarkingCompleted(1024); stats_collector.NotifySweepingCompleted(); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseAllocatedObjectSizeForTesting(512); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); @@ -194,7 +211,8 @@ TEST(ThreadHeapStatsCollectorTest, SubMilliSecondMarkingTime) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStartMarking, base::TimeDelta::FromMillisecondsD(.5)); @@ -206,7 +224,8 @@ ThreadHeapStatsCollector stats_collector; EXPECT_EQ(0u, stats_collector.allocated_space_bytes()); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); EXPECT_EQ(0u, stats_collector.allocated_space_bytes()); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); EXPECT_EQ(0u, stats_collector.allocated_space_bytes()); @@ -234,7 +253,8 @@ TEST(ThreadHeapStatsCollectorTest, EventPrevGCMarkedObjectSize) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(1024); stats_collector.NotifySweepingCompleted(); EXPECT_EQ(1024u, stats_collector.previous().marked_bytes); @@ -244,7 +264,8 @@ EventMarkingTimeFromIncrementalStandAloneGC) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStartMarking, base::TimeDelta::FromMilliseconds(7)); @@ -263,7 +284,8 @@ TEST(ThreadHeapStatsCollectorTest, EventMarkingTimeFromIncrementalUnifiedGC) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStartMarking, base::TimeDelta::FromMilliseconds(7)); @@ -291,7 +313,8 @@ TEST(ThreadHeapStatsCollectorTest, EventMarkingTime) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kIncrementalMarkingStep, base::TimeDelta::FromMilliseconds(2)); @@ -307,7 +330,8 @@ TEST(ThreadHeapStatsCollectorTest, EventAtomicMarkingTime) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kAtomicPauseMarkPrologue, base::TimeDelta::FromMilliseconds(5)); @@ -326,7 +350,8 @@ TEST(ThreadHeapStatsCollectorTest, EventAtomicPause) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure, base::TimeDelta::FromMilliseconds(17)); @@ -342,7 +367,8 @@ TEST(ThreadHeapStatsCollectorTest, EventMarkingTimePerByteInS) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseScopeTime( ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure, base::TimeDelta::FromSeconds(1)); @@ -355,7 +381,8 @@ TEST(ThreadHeapStatsCollectorTest, EventSweepingTime) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle, base::TimeDelta::FromMilliseconds(1)); @@ -376,7 +403,8 @@ TEST(ThreadHeapStatsCollectorTest, EventCompactionFreedBytes) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.IncreaseCompactionFreedSize(512); stats_collector.NotifySweepingCompleted(); @@ -386,7 +414,8 @@ TEST(ThreadHeapStatsCollectorTest, EventCompactionFreedPages) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.IncreaseCompactionFreedPages(3); stats_collector.NotifySweepingCompleted(); @@ -396,7 +425,8 @@ TEST(ThreadHeapStatsCollectorTest, EventInitialEstimatedLiveObjectRate) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ(0.0, stats_collector.previous().live_object_rate); @@ -406,11 +436,13 @@ EventEstimatedLiveObjectRateSameMarkedBytes) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); stats_collector.NotifySweepingCompleted(); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ(1.0, stats_collector.previous().live_object_rate); @@ -420,11 +452,13 @@ EventEstimatedLiveObjectRateHalfMarkedBytes) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(256); stats_collector.NotifySweepingCompleted(); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ(0.5, stats_collector.previous().live_object_rate); @@ -433,11 +467,13 @@ TEST(ThreadHeapStatsCollectorTest, EventEstimatedLiveObjectRateNoMarkedBytes) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(256); stats_collector.NotifySweepingCompleted(); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ(0.0, stats_collector.previous().live_object_rate); } @@ -446,12 +482,14 @@ EventEstimatedLiveObjectRateWithAllocatedBytes1) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); stats_collector.NotifySweepingCompleted(); stats_collector.IncreaseAllocatedObjectSize(128); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ(.5, stats_collector.previous().live_object_rate); @@ -461,12 +499,14 @@ EventEstimatedLiveObjectRateWithAllocatedBytes2) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); stats_collector.IncreaseAllocatedObjectSize(128); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ(1.0, stats_collector.previous().live_object_rate); @@ -476,7 +516,8 @@ EventEstimatedLiveObjectRateWithAllocatedBytes3) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ(0, stats_collector.previous().live_object_rate); @@ -486,11 +527,13 @@ EventEstimatedLiveObjectRateWithAllocatedBytes4) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(128); stats_collector.NotifySweepingCompleted(); stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.NotifySweepingCompleted(); EXPECT_DOUBLE_EQ(0, stats_collector.previous().live_object_rate); @@ -499,7 +542,8 @@ TEST(ThreadHeapStatsCollectorTest, EventAllocatedSpaceBeforeSweeping1) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseAllocatedSpace(1024); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.IncreaseAllocatedSpace(2048); @@ -512,7 +556,8 @@ TEST(ThreadHeapStatsCollectorTest, EventAllocatedSpaceBeforeSweeping2) { ThreadHeapStatsCollector stats_collector; stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector.IncreaseAllocatedSpace(1024); stats_collector.NotifyMarkingCompleted(kNoMarkedBytes); stats_collector.DecreaseAllocatedSpace(1024); @@ -539,7 +584,8 @@ void FakeGC(ThreadHeapStatsCollector* stats_collector, size_t marked_bytes) { stats_collector->NotifyMarkingStarted(BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); stats_collector->NotifyMarkingCompleted(marked_bytes); stats_collector->NotifySweepingCompleted(); }
diff --git a/third_party/blink/renderer/platform/heap/test/heap_test.cc b/third_party/blink/renderer/platform/heap/test/heap_test.cc index bd9e06d..a73fad8cb 100644 --- a/third_party/blink/renderer/platform/heap/test/heap_test.cc +++ b/third_party/blink/renderer/platform/heap/test/heap_test.cc
@@ -265,8 +265,8 @@ explicit TestGCScope(BlinkGC::StackState state) : TestGCCollectGarbageScope(state) { ThreadState::Current()->Heap().stats_collector()->NotifyMarkingStarted( - BlinkGC::CollectionType::kMajor, - BlinkGC::GCReason::kForcedGCForTesting); + BlinkGC::CollectionType::kMajor, BlinkGC::GCReason::kForcedGCForTesting, + true /* is_forced_gc */); ThreadState::Current()->AtomicPauseMarkPrologue( BlinkGC::CollectionType::kMajor, state, BlinkGC::kAtomicMarking, BlinkGC::GCReason::kForcedGCForTesting);
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index ec5b224a..e6859a8 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -548,7 +548,7 @@ WTF::CrossThreadBindRepeating(&ThreadState::PerformConcurrentSweep, WTF::CrossThreadUnretained(this))), ConvertToBaseRepeatingCallback(WTF::CrossThreadBindRepeating( - [](ThreadState* state) -> size_t { + [](ThreadState* state, size_t /*worker_count*/) -> size_t { return state->has_unswept_pages_.load(std::memory_order_relaxed) ? 1 : 0; @@ -682,8 +682,7 @@ BlinkGC::GCReason reason) { ThreadHeapStatsCollector::EnabledScope mark_prologue_scope( Heap().stats_collector(), - ThreadHeapStatsCollector::kAtomicPauseMarkPrologue, "epoch", gc_age_, - "forced", IsForcedGC(reason)); + ThreadHeapStatsCollector::kAtomicPauseMarkPrologue); EnterAtomicPause(); EnterNoAllocationScope(); EnterGCForbiddenScope(); @@ -768,8 +767,7 @@ ScriptForbiddenScope script_forbidden; SweepForbiddenScope scope(this); ThreadHeapStatsCollector::EnabledScope stats_scope( - Heap().stats_collector(), ThreadHeapStatsCollector::kCompleteSweep, - "forced", IsForcedGC(current_gc_data_.reason)); + Heap().stats_collector(), ThreadHeapStatsCollector::kCompleteSweep); // Boost priority of sweeping job to complete ASAP and avoid taking time on // the main thread. if (sweeper_handle_) @@ -1114,7 +1112,7 @@ // Sweeping is performed in driver functions. DCHECK(!IsSweepingInProgress()); Heap().stats_collector()->NotifyMarkingStarted( - BlinkGC::CollectionType::kMajor, reason); + BlinkGC::CollectionType::kMajor, reason, IsForcedGC(reason)); { ThreadHeapStatsCollector::EnabledScope stats_scope( Heap().stats_collector(), @@ -1294,7 +1292,8 @@ if (should_do_full_gc) { CompleteSweep(); SetGCState(kNoGCScheduled); - Heap().stats_collector()->NotifyMarkingStarted(collection_type, reason); + Heap().stats_collector()->NotifyMarkingStarted(collection_type, reason, + IsForcedGC(reason)); RunAtomicPause(collection_type, stack_state, marking_type, sweeping_type, reason); } @@ -1333,8 +1332,8 @@ BlinkGC::MarkingType marking_type, BlinkGC::GCReason reason) { ThreadHeapStatsCollector::EnabledScope advance_tracing_scope( - Heap().stats_collector(), ThreadHeapStatsCollector::kAtomicPauseMarkRoots, - "epoch", gc_age_, "forced", IsForcedGC(current_gc_data_.reason)); + Heap().stats_collector(), + ThreadHeapStatsCollector::kAtomicPauseMarkRoots); MarkPhaseVisitRoots(); MarkPhaseVisitNotFullyConstructedObjects(); } @@ -1342,8 +1341,7 @@ void ThreadState::AtomicPauseMarkTransitiveClosure() { ThreadHeapStatsCollector::EnabledScope advance_tracing_scope( Heap().stats_collector(), - ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure, "epoch", - gc_age_, "forced", IsForcedGC(current_gc_data_.reason)); + ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure); // base::TimeTicks::Now() + base::TimeDelta::Max() == base::TimeTicks::Max() CHECK(MarkPhaseAdvanceMarking(base::TimeDelta::Max(), EphemeronProcessing::kFullProcessing)); @@ -1352,8 +1350,7 @@ void ThreadState::AtomicPauseMarkEpilogue(BlinkGC::MarkingType marking_type) { ThreadHeapStatsCollector::EnabledScope stats_scope( Heap().stats_collector(), - ThreadHeapStatsCollector::kAtomicPauseMarkEpilogue, "epoch", gc_age_, - "forced", IsForcedGC(current_gc_data_.reason)); + ThreadHeapStatsCollector::kAtomicPauseMarkEpilogue); MarkPhaseEpilogue(marking_type); LeaveGCForbiddenScope(); LeaveNoAllocationScope(); @@ -1367,8 +1364,7 @@ BlinkGC::SweepingType sweeping_type) { ThreadHeapStatsCollector::EnabledScope stats( Heap().stats_collector(), - ThreadHeapStatsCollector::kAtomicPauseSweepAndCompact, "epoch", gc_age_, - "forced", IsForcedGC(current_gc_data_.reason)); + ThreadHeapStatsCollector::kAtomicPauseSweepAndCompact); AtomicPauseScope atomic_pause_scope(this); ScriptForbiddenScope script_forbidden_scope;
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader.cc index be07c11d..ef07090 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader.cc
@@ -14,6 +14,8 @@ #include "mojo/public/cpp/system/data_pipe_producer.h" #include "services/network/public/mojom/url_loader.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" +#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/shared_buffer.h" @@ -251,7 +253,11 @@ public: WebBundleSubresourceLoaderFactory( mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver, - mojo::ScopedDataPipeConsumerHandle bundle_body) { + mojo::ScopedDataPipeConsumerHandle bundle_body, + scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner, + WebBundleErrorCallback error_callback) + : callback_task_runner_(callback_task_runner), + error_callback_(error_callback) { receivers_.Add(this, std::move(receiver)); receivers_.set_disconnect_handler(base::BindRepeating( &WebBundleSubresourceLoaderFactory::OnMojoDisconnect, @@ -322,6 +328,9 @@ return; auto it = metadata_->requests.find(loader->Url()); if (it == metadata_->requests.end()) { + RunErrorCallback(WebBundleErrorType::kResourceNotFound, + loader->Url().possibly_invalid_spec() + + " is not found in the WebBundle."); loader->OnFail(net::ERR_INVALID_WEB_BUNDLE); return; } @@ -340,7 +349,8 @@ "WebBundleSubresourceLoaderFactory::OnMetadataParsed"); if (error) { metadata_error_ = std::move(error); - // TODO(crbug.com/1082020): Log the error message to console output. + RunErrorCallback(WebBundleErrorType::kMetadataParseError, + metadata_error_->message); for (auto loader : pending_loaders_) { if (loader) loader->OnFail(net::ERR_INVALID_WEB_BUNDLE); @@ -363,7 +373,7 @@ if (!loader) return; if (error) { - // TODO(crbug.com/1082020): Log the error message to console output. + RunErrorCallback(WebBundleErrorType::kResponseParseError, error->message); loader->OnFail(net::ERR_INVALID_WEB_BUNDLE); return; } @@ -383,12 +393,20 @@ loader->GetWeakPtr())); } + void RunErrorCallback(WebBundleErrorType type, const std::string& message) { + PostCrossThreadTask(*callback_task_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(error_callback_, type, + String(message.c_str()))); + } + mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_; std::unique_ptr<LinkWebBundleDataSource> source_; mojo::Remote<web_package::mojom::WebBundleParser> parser_; web_package::mojom::BundleMetadataPtr metadata_; web_package::mojom::BundleMetadataParseErrorPtr metadata_error_; std::vector<base::WeakPtr<WebBundleSubresourceLoader>> pending_loaders_; + scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner_; + WebBundleErrorCallback error_callback_; base::WeakPtrFactory<WebBundleSubresourceLoaderFactory> weak_ptr_factory_{ this}; @@ -397,9 +415,12 @@ // Runs on a background thread. void CreateFactoryOnBackground( mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver, - mojo::ScopedDataPipeConsumerHandle bundle_body) { - new WebBundleSubresourceLoaderFactory(std::move(receiver), - std::move(bundle_body)); + mojo::ScopedDataPipeConsumerHandle bundle_body, + scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner, + WebBundleErrorCallback error_callback) { + new WebBundleSubresourceLoaderFactory( + std::move(receiver), std::move(bundle_body), callback_task_runner, + std::move(error_callback)); } } // namespace @@ -407,13 +428,17 @@ void CreateWebBundleSubresourceLoaderFactory( CrossVariantMojoReceiver<network::mojom::URLLoaderFactoryInterfaceBase> factory_receiver, - mojo::ScopedDataPipeConsumerHandle bundle_body) { + mojo::ScopedDataPipeConsumerHandle bundle_body, + WebBundleErrorCallback error_callback) { auto task_runner = base::ThreadPool::CreateSequencedTaskRunner( {base::TaskPriority::USER_VISIBLE, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}); - task_runner->PostTask(FROM_HERE, base::BindOnce(&CreateFactoryOnBackground, - std::move(factory_receiver), - std::move(bundle_body))); + task_runner->PostTask( + FROM_HERE, + base::BindOnce(&CreateFactoryOnBackground, std::move(factory_receiver), + std::move(bundle_body), + base::ThreadTaskRunnerHandle::Get(), + std::move(error_callback))); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader.h b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader.h index 013cacd..82866299 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader.h +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader.h
@@ -10,14 +10,29 @@ #include "third_party/blink/public/platform/cross_variant_mojo_util.h" #include "third_party/blink/renderer/platform/platform_export.h" +namespace WTF { +class String; +} // namespace WTF + namespace blink { +enum class WebBundleErrorType { + kMetadataParseError, + kResponseParseError, + kResourceNotFound, +}; + +using WebBundleErrorCallback = + base::RepeatingCallback<void(WebBundleErrorType, + const WTF::String& message)>; + // Creates a network::mojom::URLLoaderFactory that can load resources from a // WebBundle, and binds it to |factory_receiver|. PLATFORM_EXPORT void CreateWebBundleSubresourceLoaderFactory( CrossVariantMojoReceiver<network::mojom::URLLoaderFactoryInterfaceBase> factory_receiver, - mojo::ScopedDataPipeConsumerHandle bundle_body); + mojo::ScopedDataPipeConsumerHandle bundle_body, + WebBundleErrorCallback error_callback); } // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader_test.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader_test.cc index f197230..509e231e 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader_test.cc
@@ -13,6 +13,7 @@ #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "services/network/test/test_url_loader_client.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -55,7 +56,10 @@ ASSERT_EQ(CreateDataPipe(nullptr, &bundle_data_destination_, &consumer), MOJO_RESULT_OK); CreateWebBundleSubresourceLoaderFactory( - loader_factory_.BindNewPipeAndPassReceiver(), std::move(consumer)); + loader_factory_.BindNewPipeAndPassReceiver(), std::move(consumer), + base::BindRepeating( + &WebBundleSubresourceLoaderFactoryTest::OnWebBundleError, + base::Unretained(this))); } void WriteBundle(base::span<const uint8_t> data) { @@ -75,6 +79,19 @@ return StartRequestWithLoaderFactory(loader_factory_, url); } + void RunUntilBundleError() { + if (last_bundle_error_.has_value()) + return; + base::RunLoop run_loop; + quit_closure_for_bundle_error_ = run_loop.QuitClosure(); + run_loop.Run(); + } + + const base::Optional<std::pair<WebBundleErrorType, WTF::String>>& + last_bundle_error() const { + return last_bundle_error_; + } + protected: StartRequestResult StartRequestWithLoaderFactory( mojo::Remote<network::mojom::URLLoaderFactory>& factory, @@ -95,8 +112,16 @@ mojo::Remote<network::mojom::URLLoaderFactory> loader_factory_; private: + void OnWebBundleError(WebBundleErrorType type, const WTF::String& message) { + last_bundle_error_ = std::make_pair(type, message); + if (quit_closure_for_bundle_error_) + std::move(quit_closure_for_bundle_error_).Run(); + } + mojo::ScopedDataPipeProducerHandle bundle_data_destination_; base::test::TaskEnvironment task_environment; + base::Optional<std::pair<WebBundleErrorType, WTF::String>> last_bundle_error_; + base::OnceClosure quit_closure_for_bundle_error_; }; TEST_F(WebBundleSubresourceLoaderFactoryTest, Basic) { @@ -107,6 +132,7 @@ request.client->RunUntilComplete(); EXPECT_EQ(net::OK, request.client->completion_status().error_code); + EXPECT_FALSE(last_bundle_error().has_value()); std::string body; EXPECT_TRUE(mojo::BlockingCopyToString( request.client->response_body_release(), &body)); @@ -125,6 +151,7 @@ request.client->RunUntilComplete(); EXPECT_EQ(net::OK, request.client->completion_status().error_code); + EXPECT_FALSE(last_bundle_error().has_value()); } TEST_F(WebBundleSubresourceLoaderFactoryTest, MetadataParseError) { @@ -136,9 +163,13 @@ FinishWritingBundle(); request.client->RunUntilComplete(); + RunUntilBundleError(); EXPECT_EQ(net::ERR_INVALID_WEB_BUNDLE, request.client->completion_status().error_code); + EXPECT_EQ(last_bundle_error()->first, + WebBundleErrorType::kMetadataParseError); + EXPECT_EQ(last_bundle_error()->second, "Wrong magic bytes."); // Requests made after metadata parse error should also fail. auto request2 = StartRequest(GURL(kResourceUrl)); @@ -158,9 +189,14 @@ auto request = StartRequest(GURL(kResourceUrl)); request.client->RunUntilComplete(); + RunUntilBundleError(); EXPECT_EQ(net::ERR_INVALID_WEB_BUNDLE, request.client->completion_status().error_code); + EXPECT_EQ(last_bundle_error()->first, + WebBundleErrorType::kResponseParseError); + EXPECT_EQ(last_bundle_error()->second, + ":status must be 3 ASCII decimal digits."); } TEST_F(WebBundleSubresourceLoaderFactoryTest, ResourceNotFoundInBundle) { @@ -169,9 +205,14 @@ auto request = StartRequest(GURL("https://example.com/no-such-resource")); request.client->RunUntilComplete(); + RunUntilBundleError(); EXPECT_EQ(net::ERR_INVALID_WEB_BUNDLE, request.client->completion_status().error_code); + EXPECT_EQ(last_bundle_error()->first, WebBundleErrorType::kResourceNotFound); + EXPECT_EQ( + last_bundle_error()->second, + "https://example.com/no-such-resource is not found in the WebBundle."); } TEST_F(WebBundleSubresourceLoaderFactoryTest, StartRequestBeforeReadingBundle) { @@ -261,9 +302,13 @@ auto request = StartRequest(GURL(kResourceUrl)); request.client->RunUntilComplete(); + RunUntilBundleError(); EXPECT_EQ(net::ERR_INVALID_WEB_BUNDLE, request.client->completion_status().error_code); + EXPECT_EQ(last_bundle_error()->first, + WebBundleErrorType::kResponseParseError); + EXPECT_EQ(last_bundle_error()->second, "Error reading response header."); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc index 90e979d..fa378e7 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
@@ -7,6 +7,7 @@ #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/loader/network_utils.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_response.h" @@ -306,7 +307,8 @@ redirect_info.new_site_for_cookies, AtomicString::FromUTF8(redirect_info.new_referrer.data(), redirect_info.new_referrer.length()), - NetToMojoReferrerPolicy(redirect_info.new_referrer_policy), + ReferrerUtils::NetToMojoReferrerPolicy( + redirect_info.new_referrer_policy), /*skip_service_worker=*/false); WebURLResponse response; Platform::Current()->PopulateURLResponse(
diff --git a/third_party/blink/renderer/platform/mojo/drag_mojom_traits.cc b/third_party/blink/renderer/platform/mojo/drag_mojom_traits.cc index b315c04..7e12c06 100644 --- a/third_party/blink/renderer/platform/mojo/drag_mojom_traits.cc +++ b/third_party/blink/renderer/platform/mojo/drag_mojom_traits.cc
@@ -9,6 +9,7 @@ #include "base/notreached.h" #include "base/strings/string16.h" #include "mojo/public/cpp/bindings/interface_ptr.h" +#include "services/network/public/mojom/referrer_policy.mojom-shared.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_drag_drop_token.mojom-blink.h" #include "third_party/blink/public/platform/file_path_conversion.h" #include "third_party/blink/public/platform/web_string.h" @@ -247,17 +248,27 @@ } // static +network::mojom::ReferrerPolicy StructTraits< + blink::mojom::DragDataDataView, + blink::WebDragData>::referrer_policy(const blink::WebDragData& drag_data) { + return drag_data.ReferrerPolicy(); +} + +// static bool StructTraits<blink::mojom::DragDataDataView, blink::WebDragData>::Read( blink::mojom::DragDataDataView data, blink::WebDragData* out) { blink::WebVector<blink::WebDragData::Item> items; WTF::String file_system_id; - if (!data.ReadItems(&items) || !data.ReadFileSystemId(&file_system_id)) + network::mojom::ReferrerPolicy referrer_policy; + if (!data.ReadItems(&items) || !data.ReadFileSystemId(&file_system_id) || + !data.ReadReferrerPolicy(&referrer_policy)) return false; blink::WebDragData drag_data; drag_data.SetItems(std::move(items)); drag_data.SetFilesystemId(file_system_id); + drag_data.SetReferrerPolicy(referrer_policy); *out = std::move(drag_data); return true; }
diff --git a/third_party/blink/renderer/platform/mojo/drag_mojom_traits.h b/third_party/blink/renderer/platform/mojo/drag_mojom_traits.h index 1851fe35..c1465c7 100644 --- a/third_party/blink/renderer/platform/mojo/drag_mojom_traits.h +++ b/third_party/blink/renderer/platform/mojo/drag_mojom_traits.h
@@ -15,6 +15,7 @@ #include "mojo/public/cpp/bindings/string_traits_wtf.h" #include "mojo/public/cpp/bindings/struct_traits.h" #include "mojo/public/cpp/bindings/union_traits.h" +#include "services/network/public/mojom/referrer_policy.mojom-forward.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_drag_drop_token.mojom-blink.h" #include "third_party/blink/public/mojom/page/drag.mojom-shared.h" #include "third_party/blink/public/platform/web_drag_data.h" @@ -102,6 +103,8 @@ static blink::WebVector<blink::WebDragData::Item> items( const blink::WebDragData& drag_data); static WTF::String file_system_id(const blink::WebDragData& drag_data); + static network::mojom::ReferrerPolicy referrer_policy( + const blink::WebDragData& drag_data); static bool Read(blink::mojom::DragDataDataView data, blink::WebDragData* out); };
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 6be2a6fa..03b89083 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -333,6 +333,10 @@ name: "CompositeSVG", }, { + name: "CompositingOptimizations", + status: "experimental" + }, + { name: "ComputedAccessibilityInfo", status: "experimental", },
diff --git a/third_party/blink/renderer/platform/scheduler/BUILD.gn b/third_party/blink/renderer/platform/scheduler/BUILD.gn index 6c6ef3b..9833f500 100644 --- a/third_party/blink/renderer/platform/scheduler/BUILD.gn +++ b/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -60,6 +60,8 @@ "common/web_resource_loading_task_runner_handle.cc", "common/web_thread_scheduler.cc", "common/worker_pool.cc", + "main_thread/agent_group_scheduler_impl.cc", + "main_thread/agent_group_scheduler_impl.h", "main_thread/agent_scheduling_strategy.cc", "main_thread/agent_scheduling_strategy.h", "main_thread/attribution_group.h", @@ -116,6 +118,7 @@ "main_thread/web_scoped_virtual_time_pauser.cc", "main_thread/widget_scheduler.cc", "main_thread/widget_scheduler.h", + "public/agent_group_scheduler.h", "public/aggregated_metric_reporter.h", "public/cooperative_scheduling_manager.h", "public/dummy_schedulers.h",
diff --git a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc index e4bc9c9..cb4442a8 100644 --- a/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc +++ b/third_party/blink/renderer/platform/scheduler/common/dummy_schedulers.cc
@@ -81,6 +81,7 @@ base::WeakPtr<FrameScheduler> GetWeakPtr() override { return weak_ptr_factory_.GetWeakPtr(); } + void ReportActiveSchedulerTrackedFeatures() override {} private: PageScheduler* page_scheduler_;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc new file mode 100644 index 0000000..4c9f034 --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.cc
@@ -0,0 +1,32 @@ +// 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/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h" + +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" + +namespace blink { +namespace scheduler { + +static AgentGroupSchedulerImpl* g_current_agent_group_scheduler_impl; + +// static +AgentGroupSchedulerImpl* AgentGroupSchedulerImpl::GetCurrent() { + DCHECK(WTF::IsMainThread()); + return g_current_agent_group_scheduler_impl; +} + +// static +void AgentGroupSchedulerImpl::SetCurrent( + AgentGroupSchedulerImpl* agent_group_scheduler_impl) { + DCHECK(WTF::IsMainThread()); + g_current_agent_group_scheduler_impl = agent_group_scheduler_impl; +} + +AgentGroupSchedulerImpl::AgentGroupSchedulerImpl( + MainThreadSchedulerImpl* main_thread_scheduler) + : main_thread_scheduler_(main_thread_scheduler) {} + +} // namespace scheduler +} // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h new file mode 100644 index 0000000..a373d40 --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h
@@ -0,0 +1,42 @@ +// 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_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AGENT_GROUP_SCHEDULER_IMPL_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AGENT_GROUP_SCHEDULER_IMPL_H_ + +#include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/scheduler/public/agent_group_scheduler.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" + +#include <memory> + +namespace blink { +namespace scheduler { +class MainThreadSchedulerImpl; + +// AgentGroupScheduler implementation which schedules per-AgentSchedulingGroup +// tasks. +class PLATFORM_EXPORT AgentGroupSchedulerImpl + : public blink::AgentGroupScheduler { + public: + static AgentGroupSchedulerImpl* GetCurrent(); + static void SetCurrent(AgentGroupSchedulerImpl*); + + explicit AgentGroupSchedulerImpl( + MainThreadSchedulerImpl* main_thread_scheduler); + AgentGroupSchedulerImpl(const AgentGroupSchedulerImpl&) = delete; + AgentGroupSchedulerImpl& operator=(const AgentGroupSchedulerImpl&) = delete; + ~AgentGroupSchedulerImpl() override = default; + + MainThreadSchedulerImpl* GetMainThreadScheduler() { + return main_thread_scheduler_; + } + + private: + MainThreadSchedulerImpl* main_thread_scheduler_; // Not owned. +}; +} // namespace scheduler +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AGENT_GROUP_SCHEDULER_IMPL_H_
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy_unittest.cc index 6e8303c..d5e6c54 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy_unittest.cc
@@ -66,7 +66,11 @@ class MockFrameScheduler : public FrameSchedulerImpl { public: explicit MockFrameScheduler(FrameScheduler::FrameType frame_type) - : FrameSchedulerImpl(nullptr, nullptr, &delegate_, nullptr, frame_type) {} + : FrameSchedulerImpl(/*main_thread_scheduler=*/nullptr, + /*parent_page_scheduler=*/nullptr, + /*delegate=*/&delegate_, + /*blame_context=*/nullptr, + /*frame_type=*/frame_type) {} private: NiceMock<MockFrameDelegate> delegate_;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc index 2d80885..e22f8234e 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -196,10 +196,10 @@ } FrameSchedulerImpl::FrameSchedulerImpl() - : FrameSchedulerImpl(nullptr, - nullptr, - nullptr, - nullptr, + : FrameSchedulerImpl(/*main_thread_scheduler=*/nullptr, + /*parent_page_scheduler=*/nullptr, + /*delegate=*/nullptr, + /*blame_context=*/nullptr, FrameType::kSubframe) {} namespace { @@ -572,6 +572,12 @@ return main_thread_scheduler_->ControlTaskRunner(); } +AgentGroupSchedulerImpl* FrameSchedulerImpl::GetAgentGroupScheduler() { + return parent_page_scheduler_ + ? parent_page_scheduler_->GetAgentGroupScheduler() + : nullptr; +} + blink::PageScheduler* FrameSchedulerImpl::GetPageScheduler() const { return parent_page_scheduler_; } @@ -704,6 +710,11 @@ return weak_factory_.GetWeakPtr(); } +void FrameSchedulerImpl::ReportActiveSchedulerTrackedFeatures() { + if (delegate_) + ReportFeaturesToDelegate(); +} + void FrameSchedulerImpl::OnAddedAllThrottlingOptOut() { ++all_throttling_opt_out_count_; opted_out_from_all_throttling_ =
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h index e5837715..6bae895a 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
@@ -23,6 +23,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_task_queue_controller.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" @@ -109,6 +110,7 @@ std::unique_ptr<WebResourceLoadingTaskRunnerHandle> CreateResourceLoadingTaskRunnerHandle() override; + AgentGroupSchedulerImpl* GetAgentGroupScheduler(); PageScheduler* GetPageScheduler() const override; void DidStartProvisionalLoad(bool is_main_frame) override; void DidCommitProvisionalLoad(bool is_web_history_inert_commit, @@ -136,6 +138,8 @@ base::WeakPtr<FrameScheduler> GetWeakPtr() override; base::WeakPtr<const FrameSchedulerImpl> GetWeakPtr() const; + void ReportActiveSchedulerTrackedFeatures() override; + scoped_refptr<base::SingleThreadTaskRunner> ControlTaskRunner(); void UpdatePolicy();
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc index ac27142..0f4df582 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -35,6 +35,7 @@ #include "third_party/blink/renderer/platform/scheduler/common/features.h" #include "third_party/blink/renderer/platform/scheduler/common/process_state.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/agent_scheduling_strategy.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" @@ -42,6 +43,7 @@ #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/widget_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/agent_group_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/event_loop.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "v8/include/v8.h" @@ -2346,9 +2348,34 @@ return non_waking_task_runner_; } +AgentGroupSchedulerImpl* MainThreadSchedulerImpl::CreateAgentGroupScheduler() { + std::unique_ptr<AgentGroupSchedulerImpl> agent_group_scheduler = + std::make_unique<AgentGroupSchedulerImpl>(this); + AddAgentGroupScheduler(agent_group_scheduler.get()); + AgentGroupSchedulerImpl* agent_group_scheduler_ptr = + agent_group_scheduler.get(); + // Currently, MainThreadSchedulerImpl has the ownership of + // AgentGroupSchedulerImpl + agent_group_scheduler_set_.insert(std::move(agent_group_scheduler)); + return agent_group_scheduler_ptr; +} + +void MainThreadSchedulerImpl::RemoveAgentGroupScheduler( + AgentGroupSchedulerImpl* agent_group_scheduler) { + DCHECK(agent_group_schedulers_.Contains(agent_group_scheduler)); + agent_group_schedulers_.erase(agent_group_scheduler); + + DCHECK(agent_group_scheduler_set_.Contains(agent_group_scheduler)); + agent_group_scheduler_set_.erase(agent_group_scheduler); +} + std::unique_ptr<PageScheduler> MainThreadSchedulerImpl::CreatePageScheduler( PageScheduler::Delegate* delegate) { - auto page_scheduler = std::make_unique<PageSchedulerImpl>(delegate, this); + // TODO(crbug/1113102): tentatively, we create AgentGroupSchedulerImpl per + // page. + AgentGroupSchedulerImpl* agent_group_scheduler = CreateAgentGroupScheduler(); + auto page_scheduler = + std::make_unique<PageSchedulerImpl>(delegate, agent_group_scheduler); AddPageScheduler(page_scheduler.get()); return page_scheduler; } @@ -2383,6 +2410,13 @@ return helper_.GetClock(); } +void MainThreadSchedulerImpl::AddAgentGroupScheduler( + AgentGroupSchedulerImpl* agent_group_scheduler_impl) { + bool is_new_entry = + agent_group_schedulers_.insert(agent_group_scheduler_impl).is_new_entry; + DCHECK(is_new_entry); +} + void MainThreadSchedulerImpl::AddPageScheduler( PageSchedulerImpl* page_scheduler) { main_thread_only().page_schedulers.insert(page_scheduler); @@ -2414,6 +2448,9 @@ IsAnyMainFrameWaitingForFirstContentfulPaint(); any_thread().waiting_for_any_main_frame_meaningful_paint = IsAnyMainFrameWaitingForFirstMeaningfulPaint(); + // TODO(crbug/1113102): tentatively, we delete AgentGroupScheduler from + // here. + RemoveAgentGroupScheduler(page_scheduler->GetAgentGroupScheduler()); UpdatePolicyLocked(UpdateType::kMayEarlyOutIfPolicyUnchanged); } @@ -2453,6 +2490,13 @@ MainThreadTaskQueue* queue, const base::sequence_manager::Task& task, const TaskQueue::TaskTiming& task_timing) { + if (queue && queue->GetFrameScheduler()) { + AgentGroupSchedulerImpl::SetCurrent( + queue->GetFrameScheduler()->GetAgentGroupScheduler()); + } else { + AgentGroupSchedulerImpl::SetCurrent(nullptr); + } + main_thread_only().running_queues.push(queue); if (main_thread_only().nested_runloop) return; @@ -2513,6 +2557,10 @@ find_in_page_budget_pool_controller_->OnTaskCompleted(queue.get(), task_timing); + + // AgentGroupSchedulerImpl::GetCurrent() should return nullptr when + // it's running thread global task runners. + AgentGroupSchedulerImpl::SetCurrent(nullptr); } void MainThreadSchedulerImpl::RecordTaskUkm(
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h index 01fec36..531d3e1 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -72,6 +72,7 @@ FORWARD_DECLARE_TEST(MainThreadSchedulerImplTest, ShouldIgnoreTaskForUkm); FORWARD_DECLARE_TEST(MainThreadSchedulerImplTest, Tracing); } // namespace main_thread_scheduler_impl_unittest +class AgentGroupSchedulerImpl; class FrameSchedulerImpl; class PageSchedulerImpl; class TaskQueueThrottler; @@ -218,6 +219,7 @@ Thread::IdleTask) override; scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override; scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override; + AgentGroupSchedulerImpl* CreateAgentGroupScheduler(); std::unique_ptr<PageScheduler> CreatePageScheduler( PageScheduler::Delegate*) override; std::unique_ptr<ThreadScheduler::RendererPauseHandle> PauseScheduler() @@ -303,6 +305,7 @@ void DecrementVirtualTimePauseCount(); void MaybeAdvanceVirtualTime(base::TimeTicks new_virtual_time); + void RemoveAgentGroupScheduler(AgentGroupSchedulerImpl*); void RemovePageScheduler(PageSchedulerImpl*); void OnFrameAdded(const FrameSchedulerImpl& frame_scheduler); @@ -466,6 +469,7 @@ static const char* TimeDomainTypeToString(TimeDomainType domain_type); + void AddAgentGroupScheduler(AgentGroupSchedulerImpl*); void AddPageScheduler(PageSchedulerImpl*); bool IsAnyMainFrameWaitingForFirstContentfulPaint() const; @@ -1059,6 +1063,10 @@ PollableThreadSafeFlag policy_may_need_update_; PollableThreadSafeFlag notify_agent_strategy_task_posted_; + WTF::HashSet<AgentGroupSchedulerImpl*> agent_group_schedulers_; + // TODO(crbug/1113102): tentatively, we hold AgentGroupSchedulerImpl here. + WTF::HashSet<std::unique_ptr<AgentGroupSchedulerImpl>> + agent_group_scheduler_set_; base::WeakPtrFactory<MainThreadSchedulerImpl> weak_factory_{this};
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc index 6d0131b..819e008d 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -302,11 +302,11 @@ class MockPageSchedulerImpl : public PageSchedulerImpl { public: - explicit MockPageSchedulerImpl(MainThreadSchedulerImpl* scheduler) - : PageSchedulerImpl(nullptr, scheduler) { + explicit MockPageSchedulerImpl(AgentGroupSchedulerImpl* agent_group_scheduler) + : PageSchedulerImpl(nullptr, agent_group_scheduler) { // This would normally be called by // MainThreadSchedulerImpl::CreatePageScheduler. - scheduler->AddPageScheduler(this); + agent_group_scheduler->GetMainThreadScheduler()->AddPageScheduler(this); ON_CALL(*this, IsWaitingForMainFrameContentfulPaint) .WillByDefault(Return(true)); @@ -443,8 +443,8 @@ idle_task_runner_ = scheduler_->IdleTaskRunner(); v8_task_runner_ = scheduler_->V8TaskQueue()->task_runner(); - page_scheduler_ = - std::make_unique<NiceMock<MockPageSchedulerImpl>>(scheduler_.get()); + page_scheduler_ = std::make_unique<NiceMock<MockPageSchedulerImpl>>( + scheduler_->CreateAgentGroupScheduler()); main_frame_scheduler_ = CreateFrameScheduler(page_scheduler_.get(), nullptr, nullptr, FrameScheduler::FrameType::kMainFrame);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc index b31624a..653cdae 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -151,11 +151,14 @@ PageSchedulerImpl::PageSchedulerImpl( PageScheduler::Delegate* delegate, - MainThreadSchedulerImpl* main_thread_scheduler) - : main_thread_scheduler_(main_thread_scheduler), + AgentGroupSchedulerImpl* agent_group_scheduler) + : main_thread_scheduler_(agent_group_scheduler->GetMainThreadScheduler()), + agent_group_scheduler_(agent_group_scheduler), page_visibility_(kDefaultPageVisibility), page_visibility_changed_time_( - main_thread_scheduler->GetTickClock()->NowTicks()), + agent_group_scheduler->GetMainThreadScheduler() + ->GetTickClock() + ->NowTicks()), audio_state_(AudioState::kSilent), is_frozen_(false), reported_background_throttling_since_navigation_(false), @@ -165,7 +168,8 @@ is_main_frame_local_(false), is_cpu_time_throttled_(false), are_wake_ups_intensively_throttled_(false), - keep_active_(main_thread_scheduler->SchedulerKeepActive()), + keep_active_(agent_group_scheduler->GetMainThreadScheduler() + ->SchedulerKeepActive()), had_recent_title_or_favicon_update_(false), cpu_time_budget_pool_(nullptr), same_origin_wake_up_budget_pool_(nullptr), @@ -843,6 +847,10 @@ return main_thread_scheduler_; } +AgentGroupSchedulerImpl* PageSchedulerImpl::GetAgentGroupScheduler() { + return agent_group_scheduler_; +} + bool PageSchedulerImpl::IsBackgrounded() const { return page_visibility_ == PageVisibilityState::kHidden && !IsAudioPlaying(); }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h index 20d7f6b3..de15b40 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h" #include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/agent_group_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_origin_type.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_visibility_state.h" #include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h" @@ -52,7 +53,7 @@ static constexpr base::TimeDelta kDefaultThrottledWakeUpInterval = base::TimeDelta::FromSeconds(1); - PageSchedulerImpl(PageScheduler::Delegate*, MainThreadSchedulerImpl*); + PageSchedulerImpl(PageScheduler::Delegate*, AgentGroupSchedulerImpl*); ~PageSchedulerImpl() override; @@ -109,6 +110,7 @@ bool IsOrdinary() const; MainThreadSchedulerImpl* GetMainThreadScheduler() const; + AgentGroupSchedulerImpl* GetAgentGroupScheduler(); void Unregister(FrameSchedulerImpl*); void OnNavigation(); @@ -279,6 +281,7 @@ TraceableVariableController tracing_controller_; HashSet<FrameSchedulerImpl*> frame_schedulers_; MainThreadSchedulerImpl* main_thread_scheduler_; + AgentGroupSchedulerImpl* agent_group_scheduler_; PageVisibilityState page_visibility_; base::TimeTicks page_visibility_changed_time_;
diff --git a/third_party/blink/renderer/platform/scheduler/public/agent_group_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/agent_group_scheduler.h new file mode 100644 index 0000000..a46f0a3 --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/public/agent_group_scheduler.h
@@ -0,0 +1,20 @@ +// 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_RENDERER_PLATFORM_SCHEDULER_PUBLIC_AGENT_GROUP_SCHEDULER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_AGENT_GROUP_SCHEDULER_H_ + +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace blink { + +// AgentGroupScheduler schedules per-AgentSchedulingGroup tasks. +class PLATFORM_EXPORT AgentGroupScheduler { + public: + virtual ~AgentGroupScheduler() = default; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_AGENT_GROUP_SCHEDULER_H_
diff --git a/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h index e546e668..f458a4a 100644 --- a/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
@@ -181,6 +181,10 @@ // TODO(altimin): Move FrameScheduler object to oilpan. virtual base::WeakPtr<FrameScheduler> GetWeakPtr() = 0; + + // Notifies the delegate the list of active features for this frame if they + // have changed since the last notification. + virtual void ReportActiveSchedulerTrackedFeatures() = 0; }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h b/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h index 338abd6..fc55897 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
@@ -55,7 +55,11 @@ bool is_cross_origin_to_main_frame, bool is_exempt_from_throttling, FrameScheduler::Delegate* delegate) - : FrameSchedulerImpl(nullptr, nullptr, delegate, nullptr, frame_type), + : FrameSchedulerImpl(/*main_thread_scheduler=*/nullptr, + /*parent_page_scheduler=*/nullptr, + /*delegate=*/delegate, + /*blame_context=*/nullptr, + /*frame_type=*/frame_type), page_scheduler_(page_scheduler), is_page_visible_(is_page_visible), is_frame_visible_(is_frame_visible),
diff --git a/third_party/blink/tools/blinkpy/third_party/README.chromium b/third_party/blink/tools/blinkpy/third_party/README.chromium index 7fb0a39..062a7d5 100644 --- a/third_party/blink/tools/blinkpy/third_party/README.chromium +++ b/third_party/blink/tools/blinkpy/third_party/README.chromium
@@ -22,7 +22,7 @@ Name: web-platform-tests - Test Suites for Web Platform specifications Short Name: wpt URL: https://github.com/web-platform-tests/wpt/ -Version: 6a5c1eb4f386da68adc77c84ac3f6e3fa1cb3033 +Version: da260d2136bc4bec547fa7ebe98598d77e0f5841 License: LICENSES FOR W3C TEST SUITES (https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html) License File: wpt/wpt/LICENSE.md Security Critical: no
diff --git a/third_party/blink/tools/blinkpy/third_party/wpt/checkout.sh b/third_party/blink/tools/blinkpy/third_party/wpt/checkout.sh index 7604e4b8..044b16a 100755 --- a/third_party/blink/tools/blinkpy/third_party/wpt/checkout.sh +++ b/third_party/blink/tools/blinkpy/third_party/wpt/checkout.sh
@@ -9,7 +9,7 @@ TARGET_DIR=$DIR/wpt REMOTE_REPO="https://github.com/web-platform-tests/wpt.git" -WPT_HEAD=6a5c1eb4f386da68adc77c84ac3f6e3fa1cb3033 +WPT_HEAD=da260d2136bc4bec547fa7ebe98598d77e0f5841 function clone { # Remove existing repo if already exists.
diff --git a/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/serve/commands.json b/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/serve/commands.json index a5457b5..ed1d72e 100644 --- a/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/serve/commands.json +++ b/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/serve/commands.json
@@ -12,7 +12,6 @@ "parser": "get_parser", "help": "Run wptserve server for WAVE", "virtualenv": true, - "install": ["ua-parser"], "requirements": ["../wave/requirements.txt"] } }
diff --git a/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/webdriver/webdriver/client.py b/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/webdriver/webdriver/client.py index 7f122c8..fe5189ec0 100644 --- a/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/webdriver/webdriver/client.py +++ b/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/webdriver/webdriver/client.py
@@ -242,6 +242,15 @@ def __init__(self, session): self.session = session + @command + def close(self): + handles = self.session.send_session_command("DELETE", "window") + if handles is not None and len(handles) == 0: + # With no more open top-level browsing contexts, the session is closed. + self.session.session_id = None + + return handles + @property @command def rect(self): @@ -548,6 +557,13 @@ def source(self): return self.send_session_command("GET", "source") + @command + def new_window(self, type_hint=None): + body = {"type": type_hint} + value = self.send_session_command("POST", "window/new", body) + + return value["handle"] + @property @command def window_handle(self): @@ -569,15 +585,6 @@ return self.send_session_command("POST", url, body) - @command - def close(self): - handles = self.send_session_command("DELETE", "window") - if handles is not None and len(handles) == 0: - # With no more open top-level browsing contexts, the session is closed. - self.session_id = None - - return handles - @property @command def handles(self):
diff --git a/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/wpt/commands.json b/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/wpt/commands.json index a47ab40..51f66d0 100644 --- a/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/wpt/commands.json +++ b/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/wpt/commands.json
@@ -6,7 +6,6 @@ "help": "Run tests in a browser", "virtualenv": true, "install": [ - "requests", "zstandard" ], "requirements": [ @@ -25,9 +24,6 @@ "parser": "create_parser_update", "help": "Update expectations files from raw logs.", "virtualenv": true, - "install": [ - "requests" - ], "requirements": [ "../wptrunner/requirements.txt" ] @@ -51,6 +47,7 @@ "script": "run", "parser": "get_parser", "help": "Install browser components", + "virtualenv": true, "install": [ "mozinstall" ]
diff --git a/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/wpt/wpt.py b/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/wpt/wpt.py index 395db039..efa985c 100644 --- a/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/wpt/wpt.py +++ b/third_party/blink/tools/blinkpy/third_party/wpt/wpt/tools/wpt/wpt.py
@@ -38,6 +38,8 @@ "requirements": [os.path.join(base_dir, item) for item in props.get("requirements", [])] } + if rv[command]["install"] or rv[command]["requirements"]: + assert rv[command]["virtualenv"] return rv
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index 18ea2e4..72b6bbcf 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -2147,6 +2147,8 @@ virtual/wbn-from-network/external/wpt/web-bundle/wbn-from-network/* [ Pass ] crbug.com/1082020 external/wpt/web-bundle/subresource-loading/* [ Skip ] virtual/subresource-web-bundles/external/wpt/web-bundle/subresource-loading/* [ Pass ] +crbug.com/1082020 http/tests/loading/wbn/subresource-loading/* [ Skip ] +virtual/subresource-web-bundles/http/tests/loading/wbn/subresource-loading/* [ Pass ] # No good way to automate this test yet external/wpt/native-file-system/showSaveFilePicker-manual.https.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 4f277262..b171cd2 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -118,6 +118,36 @@ # display-lock # Some additional bugs that are caused by painting problems are also within this section. +# TODO(crbug.com/1113629): Temporary disable these test for the experiment +crbug.com/1113629 compositing/contents-opaque/overflow-hidden-child-layers.html [ Failure ] +crbug.com/1113629 compositing/geometry/foreground-layer.html [ Failure ] +crbug.com/1113629 compositing/iframes/become-composited-nested-iframes.html [ Failure ] +crbug.com/1113629 compositing/iframes/become-overlapped-iframe.html [ Failure ] +crbug.com/1113629 compositing/iframes/composited-parent-iframe.html [ Failure ] +crbug.com/1113629 compositing/iframes/connect-compositing-iframe-delayed.html [ Failure ] +crbug.com/1113629 compositing/iframes/connect-compositing-iframe.html [ Failure ] +crbug.com/1113629 compositing/iframes/connect-compositing-iframe2.html [ Failure ] +crbug.com/1113629 compositing/iframes/connect-compositing-iframe3.html [ Failure ] +crbug.com/1113629 compositing/iframes/enter-compositing-iframe.html [ Failure ] +crbug.com/1113629 compositing/iframes/iframe-resize.html [ Failure ] +crbug.com/1113629 compositing/iframes/iframe-size-from-zero.html [ Failure ] +crbug.com/1113629 compositing/iframes/invisible-nested-iframe-show.html [ Failure ] +crbug.com/1113629 compositing/iframes/overlapped-iframe-iframe.html [ Failure ] +crbug.com/1113629 compositing/iframes/overlapped-iframe.html [ Failure ] +crbug.com/1113629 compositing/iframes/overlapped-nested-iframes.html [ Failure ] +crbug.com/1113629 compositing/iframes/resizer.html [ Failure ] +crbug.com/1113629 compositing/iframes/scrolling-iframe.html [ Failure ] +crbug.com/1113629 compositing/rtl/rtl-iframe-absolute-overflow-scrolled.html [ Failure ] +crbug.com/1113629 compositing/rtl/rtl-iframe-absolute-overflow.html [ Failure ] +crbug.com/1113629 compositing/rtl/rtl-iframe-absolute.html [ Failure ] +crbug.com/1113629 compositing/rtl/rtl-iframe-fixed-overflow-scrolled.html [ Failure ] +crbug.com/1113629 compositing/rtl/rtl-iframe-fixed-overflow.html [ Failure Crash ] +crbug.com/1113629 compositing/rtl/rtl-iframe-fixed.html [ Failure ] +crbug.com/1113629 fast/sub-pixel/transformed-iframe-copy-on-scroll.html [ Failure ] +crbug.com/1113629 paint/invalidation/compositing/overlap-test-with-filter.html [ Failure ] +crbug.com/1113629 paint/invalidation/scroll/composited-iframe-scroll-repaint.html [ Failure ] +crbug.com/1113629 paint/invalidation/scroll/repaint-during-scroll-with-zoom.html [ Failure ] + # --- Begin CompositeAfterPaint Tests -- # Only whitelisted tests run under the virtual suite. # More tests run with CompositeAfterPaint on the flag-specific try bot. @@ -6369,10 +6399,7 @@ crbug.com/1048597 [ Linux ] virtual/android/fullscreen/video-scrolled-iframe.html [ Pass Timeout ] -crbug.com/1056022 [ Fuchsia ] http/tests/uri/escaped-entity.html [ Skip ] -crbug.com/1056022 [ Fuchsia ] http/tests/uri/utf8-path.html [ Skip ] -crbug.com/1056022 [ Fuchsia ] virtual/text-antialias/international/001.html [ Skip ] -crbug.com/1056022 [ Fuchsia ] http/tests/eventsource/eventsource-bad-mime-type.html [ Skip ] +crbug.com/1056022 [ Fuchsia ] virtual/text-antialias/international/001.html [ Timeout ] # Sheriff 2020-02-28 crbug.com/1056879 [ Win7 ] external/wpt/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html [ Pass Failure Timeout ] @@ -6394,8 +6421,6 @@ # Ecosystem-Infra Sheriff 2020-04-15 crbug.com/1070995 external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/blob-data.https.html [ Pass Failure Timeout ] -crbug.com/1057020 [ Fuchsia ] http/tests/streams/chromium/get-reader-byob.html [ Skip ] - # Sheriff 2020-03-05 crbug.com/1058073 [ Mac10.14 ] accessibility/content-changed-notification-causes-crash.html [ Pass Failure ] @@ -6733,5 +6758,5 @@ # Sheriff 2020-08-11 crbug.com/1095540 virtual/threaded-prefer-compositing/fast/scrolling/resize-corner-tracking-touch.html [ Pass Failure ] - crbug.com/1113521 [ Mac ] fast/events/mouse-cursor-image-set.html [ Pass Crash ] +crbug.com/1046784 http/tests/devtools/network/network-content-replacement-xhr.js [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 8bf29c7..f1ed4ad 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -743,7 +743,8 @@ }, { "prefix": "subresource-web-bundles", - "bases": [ "external/wpt/web-bundle/subresource-loading" ], + "bases": [ "external/wpt/web-bundle/subresource-loading", + "http/tests/loading/wbn/subresource-loading" ], "args": [ "--enable-blink-features=SubresourceWebBundles" ] }, {
diff --git a/third_party/blink/web_tests/WebDriverExpectations b/third_party/blink/web_tests/WebDriverExpectations index e17f57e..b6d5928 100644 --- a/third_party/blink/web_tests/WebDriverExpectations +++ b/third_party/blink/web_tests/WebDriverExpectations
@@ -77,157 +77,6 @@ crbug.com/1020018 [ Linux ] external/wpt/webdriver/tests/get_active_element/get.py>>test_sucess_input_non_interactable [ Failure ] # ====== New tests from wpt-importer added here ====== -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_screenshot/screenshot.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/release_actions/release.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_modifiers.py>>test_shift_modifier_generates_capital_letters[\ue050] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/navigate_to/navigate.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/forward.py>>test_no_browsing_history [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_accept[capabilities0-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_dismiss[capabilities0-alert] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/add_cookie/add.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_dismissed_beforeunload [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_default[confirm-False] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_selected/selected.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/close.py>>test_close_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_window/switch.py>>test_null_response_value [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/user_prompts.py>>test_accept[capabilities0-alert-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt[confirm] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/none.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_accept[capabilities0-alert] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/delete_all_cookies/delete.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt_twice[confirm] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_default[alert-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/print/printcmd.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/user_prompts.py>>test_dismiss[capabilities0-alert-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_dismiss[capabilities0-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_async_script/execute_async.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/forward.py>>test_null_response_value [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_dismiss[capabilities0-alert] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/user_prompts.py>>test_accept[capabilities0-confirm-True] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/take_element_screenshot/screenshot.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/accept_alert/accept.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/forward.py>>test_history_pushstate [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/fullscreen_window/fullscreen.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/forward.py>>test_fragments [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_window.py>>test_new_window_sets_no_window_name [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_dismiss[capabilities0-confirm] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_property/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/permissions/set.py>>test_set_to_state_cross_realm[capabilities0-realmSetting0-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/permissions/set.py>>test_set_to_state_cross_realm[capabilities0-realmSetting1-granted] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/close.py>>test_close_browsing_context_with_dismissed_beforeunload_prompt [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_accept[capabilities0-alert] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_tag_name/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_default[prompt-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_history_pushstate [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_data_urls [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_accept[capabilities0-confirm] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/set_window_rect/set.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt[prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/permissions/set.py>>test_set_to_state_cross_realm[capabilities0-realmSetting0-denied] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/is_element_enabled/enabled.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_window_rect/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/delete_cookie/delete.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt_twice[alert] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_dismiss[capabilities0-alert] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_dismiss[capabilities0-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_window.py>>test_new_window_opens_about_blank [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_refresh_switches_to_parent_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_css_value/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/maximize_window/maximize.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/element_send_keys/send_keys.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_no_browsing_history [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_accept[capabilities0-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_attribute/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_modifiers.py>>test_shift_modifier_generates_capital_letters[\ue008] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_ending_comment [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_window_handle/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_rect/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_null_parameter_value [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/permissions/set.py>>test_set_to_state_cross_realm[capabilities0-realmSetting1-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_frame/switch.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new.py>>test_type_with_null_value [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_tab.py>>test_new_tab [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_dismiss_and_notify[capabilities0-confirm-False] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_fragments [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_accept[capabilities0-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/forward.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_element_text/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/user_prompts.py>>test_dismiss[capabilities0-confirm-False] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_accept[capabilities0-confirm] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_basic [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_dismiss[capabilities0-confirm] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_override_listeners [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/switch_to_parent_frame/switch.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_ignore[capabilities0-alert] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new.py>>test_type_with_unknown_value [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/minimize_window/minimize.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_ignore[capabilities0-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_active_element/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_page_source/source.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_history_pushstate [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_accept_and_notify[capabilities0-confirm-True] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_null_response_value [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_default[prompt-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/permissions/set.py>>test_set_to_state_cross_realm[capabilities0-realmSetting0-granted] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_modifiers.py>>test_shift_modifier_and_non_printable_keys[\ue008] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/user_prompts.py>>test_accept[capabilities0-prompt-] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_current_url/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_window_handles/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_dismiss_and_notify[capabilities0-prompt-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_alert_text/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_default[confirm-False] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_default[prompt-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_named_cookie/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_default[confirm-False] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_accept_and_notify[capabilities0-prompt-] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/permissions/set.py>>test_set_to_state_cross_realm[capabilities0-realmSetting1-denied] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/close.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_title/get.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt[alert] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/forward.py>>test_dismissed_beforeunload [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_tab.py>>test_new_tab_sets_no_opener [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/back.py>>test_dismissed_beforeunload [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/forward.py>>test_data_urls [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_ignore[capabilities0-confirm] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_dismiss[capabilities0-prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_tab.py>>test_new_tab_opens_about_blank [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/execute_script/execute.py>>test_abort_by_user_prompt_twice[prompt] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_window.py>>test_type_with_window [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_accept[capabilities0-confirm] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/forward/user_prompts.py>>test_dismiss_and_notify[capabilities0-alert-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_null_response_value [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_default[alert-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/dismiss_alert/dismiss.py>>test_no_browsing_context [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_window.py>>test_new_window_sets_no_opener [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_window_handles/get.py>>test_multiple_windows [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/key_modifiers.py>>test_shift_modifier_and_non_printable_keys[\ue050] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/close_window/user_prompts.py>>test_accept_and_notify[capabilities0-alert-None] [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/new_window/new_tab.py>>test_new_tab_sets_no_window_name [ Failure ] -crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/back/user_prompts.py>>test_dismiss[capabilities0-confirm] [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_tripleclick.py>>test_tripleclick_at_coordinates [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/minimize_window/minimize.py>>test_fully_exit_fullscreen [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/get_named_cookie/get.py>>test_duplicated_cookie [ Failure ]
diff --git a/third_party/blink/web_tests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt b/third_party/blink/web_tests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt index 8266778..6c8343cf 100644 --- a/third_party/blink/web_tests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt +++ b/third_party/blink/web_tests/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt
@@ -12,6 +12,19 @@ "bounds": [200, 200], "backgroundColor": "#000000", "transform": 1 + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='software-parent'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#008000" + }, + { + "name": "LayoutNGBlockFlow (positioned) DIV id='software-child'", + "position": [100, 100], + "bounds": [50, 50], + "contentsOpaque": true, + "backgroundColor": "#0000FF" } ], "transforms": [
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 46f3160d..339d17c3 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -215388,6 +215388,10 @@ "checkpoint-after-error-event.js": [ "f415732aa68dd529dcdacc49fb0d0ca6816c1249", [] + ], + "resolve-then-throw.js": [ + "a841eb780a050a82acb3cd496f4f7ad04a8f3a5b", + [] ] } }, @@ -217912,10 +217916,6 @@ "document-fonts-ready.html.ini": [ "d074292053b6d580efda36155c1d82af699494bc", [] - ], - "html-elements.html.ini": [ - "67caa470342db6d2b46dab28464f2491f84dd7b2", - [] ] }, "expected-fail": { @@ -230081,7 +230081,7 @@ [] ], "safari-technology-preview.rb": [ - "63ad4e5425e593e6641bc36d4ac4fc1bbb9085d6", + "9219623d55f6e034703f5125ac7285e1ba68d7aa", [] ], "system_info.yml": [ @@ -239744,10 +239744,6 @@ "4316c3804a28f44d1f86af97c86e478570b2437a", [] ], - "RTCDTMFSender-insertDTMF.https-expected.txt": [ - "5bd1585a8ca1eafd699a427af4b64a0919d87ab2", - [] - ], "RTCDTMFSender-ontonechange.https-expected.txt": [ "622e37bef6506534b776bb855f86eb8e4afa2bf7", [] @@ -239781,7 +239777,7 @@ [] ], "RTCPeerConnection-createDataChannel-expected.txt": [ - "b2f2fdb0b7e54f01b99dcb8d5f2c5dfeec9916cb", + "e8ee8c6838c21aa79dad80870fbd4ee2c4ab243c", [] ], "RTCPeerConnection-createOffer-expected.txt": [ @@ -239820,16 +239816,12 @@ "a4eb397e2077c1d8371cee0ef1a244fd24cb6ca4", [] ], - "RTCPeerConnection-removeTrack.https-expected.txt": [ - "b2be9c6cc049dc2685c5dbd768c34a51473b23ea", - [] - ], "RTCPeerConnection-restartIce.https-expected.txt": [ "b9c48a53445b55950fb9d5147c6da2bdb8eb1dc6", [] ], "RTCPeerConnection-setDescription-transceiver-expected.txt": [ - "77588ee5f22ef2a9705a93abcc4e6299b57b6373", + "bee8749ac080ecc3b229db141246fcef597e9d5f", [] ], "RTCPeerConnection-setLocalDescription-answer-expected.txt": [ @@ -239901,15 +239893,11 @@ [] ], "RTCRtpSender-replaceTrack.https-expected.txt": [ - "484741a9ef26eb8829a3c0dafb7b6ef7566f592a", - [] - ], - "RTCRtpSender-setParameters-expected.txt": [ - "2fc98778be9bda4aaba7e49faa4f1a8d4fa5a0a2", + "5431b223c14a91569dca56474498b72995e92711", [] ], "RTCRtpTransceiver-stop-expected.txt": [ - "80df50319c86b8e9da60893db6ea82dbacf2b02c", + "d7e8b204b7cebd632f4990fc2fc7f04f0c137eae", [] ], "RTCRtpTransceiver.https-expected.txt": [ @@ -239955,7 +239943,7 @@ [] ], "idlharness.https.window-expected.txt": [ - "d4c1de610ef3128b00c5bd4f4e113c254def0976", + "8b39ad8233089068b5d7f789fd4781c4ef81fb02", [] ], "legacy": { @@ -348934,6 +348922,31 @@ null, {} ] + ], + "checkpoint-importScripts.any.js": [ + "8791a099b6ec875e5851d3f18c0b9c29a9eab83b", + [ + "html/semantics/scripting-1/the-script-element/microtasks/checkpoint-importScripts.any.sharedworker.html", + { + "script_metadata": [ + [ + "global", + "dedicatedworker,sharedworker" + ] + ] + } + ], + [ + "html/semantics/scripting-1/the-script-element/microtasks/checkpoint-importScripts.any.worker.html", + { + "script_metadata": [ + [ + "global", + "dedicatedworker,sharedworker" + ] + ] + } + ] ] }, "module": { @@ -365728,7 +365741,7 @@ ] ], "secure-payment-confirmation.https.html": [ - "1133214217a79f640e35ee09ab4abbaa8ca00e4a", + "860876e2e9bb750a266b33472753444532fe9a6a", [ null, {} @@ -404187,7 +404200,7 @@ ] ], "RTCPeerConnection-createDataChannel.html": [ - "87867664b58a6787bd96cfb85559b4f1171e263f", + "7ad8bf7d46ecd7a3702542d8b484132afcc94d63", [ null, { @@ -404256,7 +404269,7 @@ ] ], "RTCPeerConnection-iceGatheringState.html": [ - "d9e3f42d2c21003c5a6c5614c24398aa9e681c60", + "88acf348eb5eaf0e803a88381d1b5463647b7a9e", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/fetch/corb/script-resource-with-nonsniffable-types.tentative.sub.html b/third_party/blink/web_tests/external/wpt/fetch/corb/script-resource-with-nonsniffable-types.tentative.sub.html index 81e2560..6d490d5 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/corb/script-resource-with-nonsniffable-types.tentative.sub.html +++ b/third_party/blink/web_tests/external/wpt/fetch/corb/script-resource-with-nonsniffable-types.tentative.sub.html
@@ -42,12 +42,7 @@ }); // www1 is cross-origin, so the HTTP response is CORB-eligible. - // - // TODO(lukasza@chromium.org): Once https://crbug.com/888079 and - // https://crbug.com/1098938 are fixed, we should use a cross-*origin* - // rather than cross-*site* URL below (e.g. s/hosts[alt]/domains/g). - // See also https://crbug.com/918660 for more context. - var src_prefix = "http://{{hosts[alt][www1]}}:{{ports[http][0]}}/fetch/corb/resources/sniffable-resource.py"; + var src_prefix = "http://{{domains[www1]}}:{{ports[http][0]}}/fetch/corb/resources/sniffable-resource.py"; body = `window['${script_has_run_token}'] = true;` script.src = src_prefix + "?type=" + mime_type + "&body=" + encodeURIComponent(body); document.body.appendChild(script)
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/html-elements.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/html-elements.html.ini deleted file mode 100644 index 67caa47..0000000 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/assumptions/html-elements.html.ini +++ /dev/null
@@ -1,9 +0,0 @@ -[html-elements.html] - [Compare CSS span definitions (only valid if pre-reqs pass)] - expected: - if product == "safari" or product == "epiphany" or product == "webkit": FAIL # https://bugs.webkit.org/show_bug.cgi?id=187052 - - - [Compare CSS div definitions (only valid if pre-reqs pass)] - expected: - if product == "safari" or product == "epiphany" or product == "webkit": FAIL # https://bugs.webkit.org/show_bug.cgi?id=187052
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/trusted-types.tentative.idl b/third_party/blink/web_tests/external/wpt/interfaces/trusted-types.tentative.idl index 4e469c1..df7beba 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/trusted-types.tentative.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/trusted-types.tentative.idl
@@ -30,7 +30,20 @@ SecureContext ] interface TrustedTypePolicyFactory : EventTarget { TrustedTypePolicy createPolicy(DOMString policyName, optional TrustedTypePolicyOptions policyOptions = {}); - // All the policy object names that have been created + boolean isHTML(any checkedObject); + boolean isScript(any checkedObject); + boolean isScriptURL(any checkedObject); + readonly attribute TrustedHTML emptyHTML; + readonly attribute TrustedScript emptyScript; + DOMString? getAttributeType(DOMString tagName, DOMString attribute, + optional DOMString elementNS, optional DOMString attrNs); + DOMString? getPropertyType(DOMString tagName, DOMString property, + optional DOMString elementNS); + + readonly attribute TrustedTypePolicy defaultPolicy; + object? getTypeMapping(optional DOMString ns); + + attribute EventHandler onbeforecreatepolicy; }; [
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt index 0fe2009..a0fe0bed 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/service-workers/idlharness.https.any.serviceworker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 296 tests; 252 PASS, 44 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 296 tests; 253 PASS, 43 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS Partial interface Navigator: original interface defined @@ -216,7 +216,7 @@ PASS FetchEvent interface: attribute clientId PASS FetchEvent interface: attribute resultingClientId FAIL FetchEvent interface: attribute replacesClientId assert_true: The prototype object must have a property "replacesClientId" expected true got false -FAIL FetchEvent interface: attribute handled assert_true: The prototype object must have a property "handled" expected true got false +PASS FetchEvent interface: attribute handled PASS FetchEvent interface: operation respondWith(Promise<Response>) FAIL FetchEvent must be primary interface of new FetchEvent("type") assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present." FAIL Stringification of new FetchEvent("type") assert_equals: Unexpected exception when evaluating object expected null but got object "TypeError: Failed to construct 'FetchEvent': 2 arguments required, but only 1 present."
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-handled.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-handled.https-expected.txt deleted file mode 100644 index 9b071f9..0000000 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/fetch-event-handled.https-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -PASS global setup -FAIL FetchEvent.handled should resolve when respondWith() is not called for a navigation request assert_equals: expected "RESOLVED" but got "FAILED" -FAIL FetchEvent.handled should resolve when respondWith() is not called for a sub-resource request assert_equals: expected "RESOLVED" but got "FAILED" -FAIL FetchEvent.handled should reject when respondWith() is not called and the event is canceled assert_equals: expected "REJECTED" but got "FAILED" -FAIL FetchEvent.handled should resolve when the promise provided to respondWith() is resolved assert_equals: expected "RESOLVED" but got "FAILED" -FAIL FetchEvent.handled should reject when the promise provided to respondWith() is resolved to an invalid response assert_equals: expected "REJECTED" but got "FAILED" -FAIL FetchEvent.handled should reject when the promise provided to respondWith() is rejected assert_equals: expected "REJECTED" but got "FAILED" -PASS global cleanup -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/azure/safari-technology-preview.rb b/third_party/blink/web_tests/external/wpt/tools/ci/azure/safari-technology-preview.rb index 63ad4e54..9219623 100644 --- a/third_party/blink/web_tests/external/wpt/tools/ci/azure/safari-technology-preview.rb +++ b/third_party/blink/web_tests/external/wpt/tools/ci/azure/safari-technology-preview.rb
@@ -1,10 +1,10 @@ cask 'safari-technology-preview' do - if MacOS.version <= :mojave - version '108,001-15210-20200610-d35e22e0-d9fa-4503-9988-cf7b2b554e15' - sha256 '0299fd2f2836b170a8b633b00d289bcc6913716042e82251af4fa1d5394b87d5' + if MacOS.version <= :catalina + version '111,001-32177-20200728-f459b529-99a7-4707-a85c-e693ddb56eee' + sha256 'f95f72e8cf6a3160fad71411168c8f0eeb805ca1e7a7eec06b6e92d2a0ab6e85' else - version '108,001-16091-20200610-09f04256-ae36-4930-b7c4-b1333f8d8e5f' - sha256 '22a4d9ca7fb39227cbf4a83be13ad05973171cf88eb6bcc2fac4556a36017357' + version '111,001-32479-20200728-12c458d1-e348-4ec5-9d55-9e9bad9c805e' + sha256 '6b199cca77be7407f40a62bc1ec576a8751b24da15613dfc0a951ac3d996f45f' end url "https://secure-appldnld.apple.com/STP/#{version.after_comma}/SafariTechnologyPreview.dmg" @@ -13,7 +13,7 @@ homepage 'https://developer.apple.com/safari/download/' auto_updates true - depends_on macos: '>= :mojave' + depends_on macos: '>= :catalina' pkg 'Safari Technology Preview.pkg'
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/idlharness.tentative.window-expected.txt b/third_party/blink/web_tests/external/wpt/trusted-types/idlharness.tentative.window-expected.txt index 31bfc3b..585a51b 100644 --- a/third_party/blink/web_tests/external/wpt/trusted-types/idlharness.tentative.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/trusted-types/idlharness.tentative.window-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 59 tests; 58 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 85 tests; 84 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS idl_test setup PASS idl_test validation PASS TrustedHTML interface: existence and properties of interface object @@ -36,10 +36,36 @@ PASS TrustedTypePolicyFactory interface: existence and properties of interface prototype object's "constructor" property PASS TrustedTypePolicyFactory interface: existence and properties of interface prototype object's @@unscopables property FAIL TrustedTypePolicyFactory interface: operation createPolicy(DOMString, optional TrustedTypePolicyOptions) assert_equals: property has wrong .length expected 1 but got 2 +PASS TrustedTypePolicyFactory interface: operation isHTML(any) +PASS TrustedTypePolicyFactory interface: operation isScript(any) +PASS TrustedTypePolicyFactory interface: operation isScriptURL(any) +PASS TrustedTypePolicyFactory interface: attribute emptyHTML +PASS TrustedTypePolicyFactory interface: attribute emptyScript +PASS TrustedTypePolicyFactory interface: operation getAttributeType(DOMString, DOMString, optional DOMString, optional DOMString) +PASS TrustedTypePolicyFactory interface: operation getPropertyType(DOMString, DOMString, optional DOMString) +PASS TrustedTypePolicyFactory interface: attribute defaultPolicy +PASS TrustedTypePolicyFactory interface: operation getTypeMapping(optional DOMString) +PASS TrustedTypePolicyFactory interface: attribute onbeforecreatepolicy PASS TrustedTypePolicyFactory must be primary interface of window.trustedTypes PASS Stringification of window.trustedTypes PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "createPolicy(DOMString, optional TrustedTypePolicyOptions)" with the proper type PASS TrustedTypePolicyFactory interface: calling createPolicy(DOMString, optional TrustedTypePolicyOptions) on window.trustedTypes with too few arguments must throw TypeError +PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "isHTML(any)" with the proper type +PASS TrustedTypePolicyFactory interface: calling isHTML(any) on window.trustedTypes with too few arguments must throw TypeError +PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "isScript(any)" with the proper type +PASS TrustedTypePolicyFactory interface: calling isScript(any) on window.trustedTypes with too few arguments must throw TypeError +PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "isScriptURL(any)" with the proper type +PASS TrustedTypePolicyFactory interface: calling isScriptURL(any) on window.trustedTypes with too few arguments must throw TypeError +PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "emptyHTML" with the proper type +PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "emptyScript" with the proper type +PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "getAttributeType(DOMString, DOMString, optional DOMString, optional DOMString)" with the proper type +PASS TrustedTypePolicyFactory interface: calling getAttributeType(DOMString, DOMString, optional DOMString, optional DOMString) on window.trustedTypes with too few arguments must throw TypeError +PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "getPropertyType(DOMString, DOMString, optional DOMString)" with the proper type +PASS TrustedTypePolicyFactory interface: calling getPropertyType(DOMString, DOMString, optional DOMString) on window.trustedTypes with too few arguments must throw TypeError +PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "defaultPolicy" with the proper type +PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "getTypeMapping(optional DOMString)" with the proper type +PASS TrustedTypePolicyFactory interface: calling getTypeMapping(optional DOMString) on window.trustedTypes with too few arguments must throw TypeError +PASS TrustedTypePolicyFactory interface: window.trustedTypes must inherit property "onbeforecreatepolicy" with the proper type PASS TrustedTypePolicy interface: existence and properties of interface object PASS TrustedTypePolicy interface object length PASS TrustedTypePolicy interface object name
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-timeline-of-an-animation.html b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-timeline-of-an-animation.html index dd861750..7e98ef42 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-timeline-of-an-animation.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/timing-model/animations/setting-the-timeline-of-an-animation.html
@@ -60,7 +60,7 @@ new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC), null); animation.startTime = document.timeline.currentTime; - assert_equals(animation.playState, 'idle'); + assert_equals(animation.playState, 'running'); animation.timeline = document.timeline; @@ -73,7 +73,7 @@ new Animation(new KeyframeEffect(createDiv(t), null, 100 * MS_PER_SEC), null); animation.startTime = document.timeline.currentTime - 200 * MS_PER_SEC; - assert_equals(animation.playState, 'idle'); + assert_equals(animation.playState, 'running'); animation.timeline = document.timeline;
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt index bab18af..ae2b8514 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/compositing/filters/sw-nested-shadow-overlaps-hw-nested-shadow-expected.txt
@@ -12,6 +12,19 @@ "bounds": [200, 200], "backgroundColor": "#000000", "transform": 1 + }, + { + "name": "LayoutBlockFlow (positioned) DIV id='software-parent'", + "bounds": [100, 100], + "contentsOpaque": true, + "backgroundColor": "#008000" + }, + { + "name": "LayoutBlockFlow (positioned) DIV id='software-child'", + "position": [100, 100], + "bounds": [50, 50], + "contentsOpaque": true, + "backgroundColor": "#0000FF" } ], "transforms": [
diff --git a/third_party/blink/web_tests/http/tests/loading/wbn/resources/generate-test-wbns.sh b/third_party/blink/web_tests/http/tests/loading/wbn/resources/generate-test-wbns.sh index 56e4fb3..1a255ab 100755 --- a/third_party/blink/web_tests/http/tests/loading/wbn/resources/generate-test-wbns.sh +++ b/third_party/blink/web_tests/http/tests/loading/wbn/resources/generate-test-wbns.sh
@@ -14,6 +14,13 @@ gen-bundle \ -version b1 \ + -baseURL http://127.0.0.1:8000/loading/wbn/resources/server/hello/ \ + -primaryURL http://127.0.0.1:8000/loading/wbn/resources/server/hello/script.js \ + -dir hello/ \ + -o wbn/hello.wbn + +gen-bundle \ + -version b1 \ -baseURL https://localhost:8443/loading/wbn/resources/server/wbn-subresource-origin-trial/ \ -primaryURL https://localhost:8443/loading/wbn/resources/server/wbn-subresource-origin-trial/script.js \ -dir wbn-subresource-origin-trial/ \
diff --git a/third_party/blink/web_tests/http/tests/loading/wbn/resources/hello/script.js b/third_party/blink/web_tests/http/tests/loading/wbn/resources/hello/script.js new file mode 100644 index 0000000..04f1b880 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/loading/wbn/resources/hello/script.js
@@ -0,0 +1 @@ +console.log('Hello from WebBundle');
diff --git a/third_party/blink/web_tests/http/tests/loading/wbn/resources/server/hello/notfound.js b/third_party/blink/web_tests/http/tests/loading/wbn/resources/server/hello/notfound.js new file mode 100644 index 0000000..26eeded --- /dev/null +++ b/third_party/blink/web_tests/http/tests/loading/wbn/resources/server/hello/notfound.js
@@ -0,0 +1 @@ +console.log('This resource exists only in server, not in bundle');
diff --git a/third_party/blink/web_tests/http/tests/loading/wbn/resources/server/hello/script.js b/third_party/blink/web_tests/http/tests/loading/wbn/resources/server/hello/script.js new file mode 100644 index 0000000..7ea8232 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/loading/wbn/resources/server/hello/script.js
@@ -0,0 +1 @@ +console.log('Hello from Server');
diff --git a/third_party/blink/web_tests/http/tests/loading/wbn/resources/wbn/hello.wbn b/third_party/blink/web_tests/http/tests/loading/wbn/resources/wbn/hello.wbn new file mode 100644 index 0000000..90c8b78 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/loading/wbn/resources/wbn/hello.wbn Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/loading/wbn/subresource-loading/subresource-loading-expected.txt b/third_party/blink/web_tests/http/tests/loading/wbn/subresource-loading/subresource-loading-expected.txt new file mode 100644 index 0000000..33f8112 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/loading/wbn/subresource-loading/subresource-loading-expected.txt
@@ -0,0 +1,10 @@ +main frame - DidStartNavigation +main frame - ReadyToCommitNavigation +main frame - didCommitLoadForFrame +main frame - TitleWasSet: Subresource loading with Web Bundles +main frame - didFinishDocumentLoadForFrame +main frame - didHandleOnloadEventsForFrame +main frame - didFinishLoadForFrame +CONSOLE MESSAGE: line 1: Hello from WebBundle +CONSOLE WARNING: http://127.0.0.1:8000/loading/wbn/resources/wbn/hello.wbn: http://127.0.0.1:8000/loading/wbn/resources/server/hello/notfound.js is not found in the WebBundle. +
diff --git a/third_party/blink/web_tests/http/tests/loading/wbn/subresource-loading/subresource-loading.html b/third_party/blink/web_tests/http/tests/loading/wbn/subresource-loading/subresource-loading.html new file mode 100644 index 0000000..f4bd658 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/loading/wbn/subresource-loading/subresource-loading.html
@@ -0,0 +1,48 @@ +<!DOCTYPE html> +<head> + <title>Subresource loading with Web Bundles</title> + <link rel="webbundle" href="../resources/wbn/hello.wbn" + resources="http://127.0.0.1:8000/loading/wbn/resources/server/hello/script.js + http://127.0.0.1:8000/loading/wbn/resources/server/hello/notfound.js"> +</head> +<body> +<script> +(async () => { +if (window.testRunner) { + testRunner.dumpAsText(); + testRunner.waitUntilDone(); +} + +// Delay running the test until "didFinishLoadForFrame" is printed. +// This is intended to avoid the flakiness of the result outputs. +await new Promise((resolve) => { + window.addEventListener('load', () => setTimeout(resolve, 0)); + }); + +if (!document.createElement('link').relList.supports('webbundle')) { + console.error("Subresource Web Bundles is not supported"); + testRunner.notifyDone(); + return; +} + +await new Promise((resolve, reject) => { + const script = document.createElement('script'); + script.src = 'http://127.0.0.1:8000/loading/wbn/resources/server/hello/script.js'; + script.onload = resolve; + script.onerror = reject; + document.body.appendChild(script); + }); + +await new Promise((resolve, reject) => { + // This request should fail rather than be loaded from the network. + const script = document.createElement('script'); + script.src = 'http://127.0.0.1:8000/loading/wbn/resources/server/hello/notfound.js'; + script.onload = reject; + script.onerror = resolve; + document.body.appendChild(script); + }); + +testRunner.notifyDone(); +})(); +</script> +</body>
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 22ffe957..4980ed3 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -511,6 +511,7 @@ interface FetchEvent : ExtendableEvent attribute @@toStringTag getter clientId + getter handled getter isReload getter preloadResponse getter request
diff --git a/third_party/blink/web_tests/platform/linux/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png b/third_party/blink/web_tests/platform/linux/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png index 64bbd30..35b9d86 100644 --- a/third_party/blink/web_tests/platform/linux/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png b/third_party/blink/web_tests/platform/mac/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png index f7dd9a0e..e22a4f65 100644 --- a/third_party/blink/web_tests/platform/mac/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png b/third_party/blink/web_tests/platform/win/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png index a8c7750..9224c4c 100644 --- a/third_party/blink/web_tests/platform/win/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/multicol/vertical-rl/composited-relpos-overlapping-will-change-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index b6d92d1..2005426 100644 --- a/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -446,6 +446,7 @@ interface FetchEvent : ExtendableEvent attribute @@toStringTag getter clientId + getter handled getter isReload getter preloadResponse getter request
diff --git a/third_party/blink/web_tests/wpt_internal/serial/resources/automation.js b/third_party/blink/web_tests/wpt_internal/serial/resources/automation.js index 5fb388c8..26053d1 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/resources/automation.js +++ b/third_party/blink/web_tests/wpt_internal/serial/resources/automation.js
@@ -101,8 +101,17 @@ // Implementation of blink.mojom.SerialPort. class FakeSerialPort { constructor() { - this.inputSignals_ = { dcd: false, cts: false, ri: false, dsr: false }; - this.outputSignals_ = { dtr: false, rts: false, brk: false }; + this.inputSignals_ = { + dataCarrierDetect: false, + clearToSend: false, + ringIndicator: false, + dataSetReady: false + }; + this.outputSignals_ = { + dataTerminalReady: false, + requestToSend: false, + break: false + }; } bind(request) { @@ -197,7 +206,7 @@ this.options_ = options; this.client_ = client; // OS typically sets DTR on open. - this.outputSignals_.dtr = true; + this.outputSignals_.dataTerminalReady = true; return { success: true }; } @@ -242,18 +251,24 @@ } async getControlSignals() { - return { signals: this.inputSignals_ }; + const signals = { + dcd: this.inputSignals_.dataCarrierDetect, + cts: this.inputSignals_.clearToSend, + ri: this.inputSignals_.ringIndicator, + dsr: this.inputSignals_.dataSetReady + }; + return {signals}; } async setControlSignals(signals) { if (signals.hasDtr) { - this.outputSignals_.dtr = signals.dtr; + this.outputSignals_.dataTerminalReady = signals.dtr; } if (signals.hasRts) { - this.outputSignals_.rts = signals.rts; + this.outputSignals_.requestToSend = signals.rts; } if (signals.hasBrk) { - this.outputSignals_.brk = signals.brk; + this.outputSignals_.break = signals.brk; } return { success: true }; } @@ -276,7 +291,7 @@ async close() { // OS typically clears DTR on close. - this.outputSignals_.dtr = false; + this.outputSignals_.dataTerminalReady = false; if (this.writer_) { this.writer_.close(); this.writer_.releaseLock();
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_close.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_close.https.window.js index 116c3fc7..2c6d95a 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_close.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_close.https.window.js
@@ -15,7 +15,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); await port.close(); await promise_rejects_dom(t, 'InvalidStateError', port.close()); }, 'A SerialPort cannot be closed if it is already closed.'); @@ -23,7 +23,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); const closePromise = port.close(); await promise_rejects_dom(t, 'InvalidStateError', port.close()); await closePromise;
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_disconnect-manual.https.html b/third_party/blink/web_tests/wpt_internal/serial/serialPort_disconnect-manual.https.html index b2307e6..a6b1b1c5 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_disconnect-manual.https.html +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_disconnect-manual.https.html
@@ -16,7 +16,7 @@ manual_loopback_serial_test(async (t, port) => { const watcher = new EventWatcher(t, navigator.serial, ['disconnect']); - await port.open({baudrate: 115200, buffersize: 1024}); + await port.open({baudRate: 115200, bufferSize: 1024}); const disconnectPromise = watcher.wait_for(['disconnect']) const reader = port.readable.getReader(); @@ -50,7 +50,7 @@ manual_loopback_serial_test(async (t, port) => { const watcher = new EventWatcher(t, navigator.serial, ['disconnect']); - await port.open({baudrate: 115200, buffersize: 1024}); + await port.open({baudRate: 115200, bufferSize: 1024}); const disconnectPromise = watcher.wait_for(['disconnect']) const writer = port.writable.getWriter();
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_getSignals.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_getSignals.https.window.js index 69b57b0..e7165bb 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_getSignals.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_getSignals.https.window.js
@@ -13,29 +13,34 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); - let expectedSignals = {dcd: false, cts: false, ri: false, dsr: false}; + let expectedSignals = { + dataCarrierDetect: false, + clearToSend: false, + ringIndicator: false, + dataSetReady: false + }; fakePort.simulateInputSignals(expectedSignals); let signals = await port.getSignals(); assert_object_equals(signals, expectedSignals); - expectedSignals.dcd = true; + expectedSignals.dataCarrierDetect = true; fakePort.simulateInputSignals(expectedSignals); signals = await port.getSignals(); assert_object_equals(signals, expectedSignals, 'DCD set'); - expectedSignals.cts = true; + expectedSignals.clearToSend = true; fakePort.simulateInputSignals(expectedSignals); signals = await port.getSignals(); assert_object_equals(signals, expectedSignals, 'CTS set'); - expectedSignals.ri = true; + expectedSignals.ringIndicator = true; fakePort.simulateInputSignals(expectedSignals); signals = await port.getSignals(); assert_object_equals(signals, expectedSignals, 'RI set'); - expectedSignals.dsr = true; + expectedSignals.dataSetReady = true; fakePort.simulateInputSignals(expectedSignals); signals = await port.getSignals(); assert_object_equals(signals, expectedSignals, 'DSR set');
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_loopback-manual.https.html b/third_party/blink/web_tests/wpt_internal/serial/serialPort_loopback-manual.https.html index c9ebf658..0c56007d 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_loopback-manual.https.html +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_loopback-manual.https.html
@@ -15,9 +15,9 @@ </p> <script> manual_loopback_serial_test(async (t, port) => { - await port.open({baudrate: 115200, buffersize: 1024}); + await port.open({baudRate: 115200, bufferSize: 1024}); - // Create something much smaller than buffersize above. + // Create something much smaller than bufferSize above. const data = new Uint8Array(64); for (let i = 0; i < data.byteLength; ++i) data[i] = i & 0xff; @@ -40,9 +40,9 @@ }, 'Can perform a series of small writes.'); manual_loopback_serial_test(async (t, port) => { - await port.open({baudrate: 115200, buffersize: 1024}); + await port.open({baudRate: 115200, bufferSize: 1024}); - // Create something much larger than buffersize above. + // Create something much larger than bufferSize above. const data = new Uint8Array(10 * 1024); for (let i = 0; i < data.byteLength; ++i) data[i] = (i / 1024) & 0xff; @@ -65,7 +65,7 @@ }, 'Can perform a series of large writes.'); manual_loopback_serial_test(async (t, port) => { - await port.open({baudrate: 115200, buffersize: 64}); + await port.open({baudRate: 115200, bufferSize: 64}); const writer = port.writable.getWriter(); // |data| is small enough to be completely transmitted. @@ -94,9 +94,9 @@ }, 'Canceling the reader discards buffered data.'); manual_loopback_serial_test(async (t, port) => { - await port.open({baudrate: 115200, buffersize: 1024}); + await port.open({baudRate: 115200, bufferSize: 1024}); - // Create something much larger than buffersize above. + // Create something much larger than bufferSize above. const data = new Uint8Array(16 * 1024); for (let i = 0; i < data.byteLength; ++i) data[i] = (i / 1024) & 0xff; @@ -141,7 +141,7 @@ }, 'Overflowing the receive buffer triggers an error.'); manual_loopback_serial_test(async (t, port) => { - await port.open({baudrate: 115200, buffersize: 1024}); + await port.open({baudRate: 115200, bufferSize: 1024}); let reader = port.readable.getReader(); let readPromise = (async () => {
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_open.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_open.https.window.js index a0e2fed..f9a92b77 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_open.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_open.https.window.js
@@ -9,17 +9,17 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); return promise_rejects_dom( - t, 'InvalidStateError', port.open({baudrate: 9600})); + t, 'InvalidStateError', port.open({baudRate: 9600})); }, 'A SerialPort cannot be opened if it is already open.'); serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - const firstRequest = port.open({baudrate: 9600}); + const firstRequest = port.open({baudRate: 9600}); await promise_rejects_dom( - t, 'InvalidStateError', port.open({baudrate: 9600})); + t, 'InvalidStateError', port.open({baudRate: 9600})); await firstRequest; }, 'Simultaneous calls to open() are disallowed.'); @@ -29,21 +29,21 @@ await promise_rejects_js(t, TypeError, port.open({})); await Promise.all([-1, 0].map( - baudrate => { - return promise_rejects_js(t, TypeError, port.open({baudrate}))})); + baudRate => { + return promise_rejects_js(t, TypeError, port.open({baudRate}))})); }, 'Baud rate is required and must be greater than zero.'); serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await Promise.all([-1, 0, 6, 9].map(databits => { + await Promise.all([-1, 0, 6, 9].map(dataBits => { return promise_rejects_js( - t, TypeError, port.open({baudrate: 9600, databits})); + t, TypeError, port.open({baudRate: 9600, dataBits})); })); - await[undefined, 7, 8].reduce(async (previousTest, databits) => { + await[undefined, 7, 8].reduce(async (previousTest, dataBits) => { await previousTest; - await port.open({baudrate: 9600, databits}); + await port.open({baudRate: 9600, dataBits}); await port.close(); }, Promise.resolve()); }, 'Data bits must be 7 or 8'); @@ -53,14 +53,14 @@ await Promise.all([0, null, 'cats'].map(parity => { return promise_rejects_js( - t, TypeError, port.open({baudrate: 9600, parity}), + t, TypeError, port.open({baudRate: 9600, parity}), `Should reject parity option "${parity}"`); })); await[undefined, 'none', 'even', 'odd'].reduce( async (previousTest, parity) => { await previousTest; - await port.open({baudrate: 9600, parity}); + await port.open({baudRate: 9600, parity}); await port.close(); }, Promise.resolve()); @@ -69,14 +69,14 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await Promise.all([-1, 0, 3, 4].map(stopbits => { + await Promise.all([-1, 0, 3, 4].map(stopBits => { return promise_rejects_js( - t, TypeError, port.open({baudrate: 9600, stopbits})); + t, TypeError, port.open({baudRate: 9600, stopBits})); })); - await[undefined, 1, 2].reduce(async (previousTest, stopbits) => { + await[undefined, 1, 2].reduce(async (previousTest, stopBits) => { await previousTest; - await port.open({baudrate: 9600, stopbits}); + await port.open({baudRate: 9600, stopBits}); await port.close(); }, Promise.resolve()); }, 'Stop bits must be 1 or 2'); @@ -85,15 +85,15 @@ const {port, fakePort} = await getFakeSerialPort(fake); await promise_rejects_js( - t, TypeError, port.open({baudrate: 9600, buffersize: -1})); + t, TypeError, port.open({baudRate: 9600, bufferSize: -1})); await promise_rejects_js( - t, TypeError, port.open({baudrate: 9600, buffersize: 0})); + t, TypeError, port.open({baudRate: 9600, bufferSize: 0})); }, 'Buffer size must be greater than zero.'); serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - const buffersize = 1 * 1024 * 1024 * 1024 /* 1 GiB */; + const bufferSize = 1 * 1024 * 1024 * 1024 /* 1 GiB */; return promise_rejects_js( - t, TypeError, port.open({baudrate: 9600, buffersize})); + t, TypeError, port.open({baudRate: 9600, bufferSize})); }, 'Unreasonably large buffer sizes are rejected.');
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_cancel.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_cancel.https.window.js index b127403..9e12472 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_cancel.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_cancel.https.window.js
@@ -8,7 +8,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const reader = port.readable.getReader(); const readPromise = reader.read(); @@ -22,7 +22,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const reader = port.readable.getReader(); @@ -37,7 +37,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); // Select a buffer size smaller than the amount of data transferred. - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const reader = port.readable.getReader();
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_chain.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_chain.https.window.js index 25978f0..d8bd73a 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_chain.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_chain.https.window.js
@@ -9,7 +9,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); // Select a buffer size larger than the amount of data transferred. - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const decoder = new TextDecoderStream(); const streamClosed = port.readable.pipeTo(decoder.writable);
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_closeLocked.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_closeLocked.https.window.js index e1e65a0..fa904e4 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_closeLocked.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_closeLocked.https.window.js
@@ -9,7 +9,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); assert_true(port.readable instanceof ReadableStream); const reader = port.readable.getReader();
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_disconnect.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_disconnect.https.window.js index 520c230..681d35c 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_disconnect.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_disconnect.https.window.js
@@ -9,7 +9,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); // Select a buffer size smaller than the amount of data transferred. - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const reader = port.readable.getReader();
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_gc.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_gc.https.window.js index f4d8e246..c45a716 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_gc.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_gc.https.window.js
@@ -14,7 +14,7 @@ ({port, fakePort} = await getFakeSerialPort(fake)); // Select a buffer size larger than the amount of data transferred. - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); let writable; chunkReceived = new Promise(resolve => {
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_largeRead.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_largeRead.https.window.js index 1644a62..b02b80b 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_largeRead.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_largeRead.https.window.js
@@ -9,12 +9,12 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); // Select a buffer size smaller than the amount of data transferred. - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const reader = port.readable.getReader(); await fakePort.writable(); - const data = new Uint8Array(1024); // Much larger than buffersize above. + const data = new Uint8Array(1024); // Much larger than bufferSize above. for (let i = 0; i < data.byteLength; ++i) data[i] = i & 0xff; fakePort.write(data);
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_open.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_open.https.window.js index 5276666..dc3e6cd 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_open.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_open.https.window.js
@@ -11,7 +11,7 @@ assert_equals(port.readable, null); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); const readable = port.readable; assert_true(readable instanceof ReadableStream);
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_parityError.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_parityError.https.window.js index a78a877..5943c8b8 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_parityError.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_parityError.https.window.js
@@ -22,7 +22,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); // Select a buffer size smaller than the amount of data transferred. - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); let readable = port.readable; let reader = readable.getReader();
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_pipeThrough.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_pipeThrough.https.window.js index 818c57e..fc2796d 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_pipeThrough.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_pipeThrough.https.window.js
@@ -9,7 +9,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); // Select a buffer size larger than the amount of data transferred. - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const decoder = new TextDecoderStream(); const streamClosed = port.readable.pipeTo(decoder.writable);
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_smallRead.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_smallRead.https.window.js index 73998e9..f4da5617 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_smallRead.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_readable_smallRead.https.window.js
@@ -9,7 +9,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); // Select a buffer size larger than the amount of data transferred. - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const reader = port.readable.getReader();
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_setSignals.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_setSignals.https.window.js index 9ba22241..417af5e0 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_setSignals.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_setSignals.https.window.js
@@ -13,9 +13,13 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); - let expectedSignals = {dtr: true, rts: false, brk: false}; + let expectedSignals = { + dataTerminalReady: true, + requestToSend: false, + break: false + }; assert_object_equals(fakePort.outputSignals, expectedSignals, 'initial'); await promise_rejects_js(t, TypeError, port.setSignals()); @@ -24,21 +28,22 @@ await promise_rejects_js(t, TypeError, port.setSignals({})); assert_object_equals(fakePort.outputSignals, expectedSignals, 'no-op'); - await port.setSignals({dtr: false}); - expectedSignals.dtr = false; + await port.setSignals({dataTerminalReady: false}); + expectedSignals.dataTerminalReady = false; assert_object_equals(fakePort.outputSignals, expectedSignals, 'clear DTR'); - await port.setSignals({rts: true}); - expectedSignals.rts = true; + await port.setSignals({requestToSend: true}); + expectedSignals.requestToSend = true; assert_object_equals(fakePort.outputSignals, expectedSignals, 'set RTS'); - await port.setSignals({brk: true}); - expectedSignals.brk = true; + await port.setSignals({break: true}); + expectedSignals.break = true; assert_object_equals(fakePort.outputSignals, expectedSignals, 'set BRK'); - await port.setSignals({dtr: true, rts: false, brk: false}); - expectedSignals.dtr = true; - expectedSignals.rts = false; - expectedSignals.brk = false; + await port.setSignals( + {dataTerminalReady: true, requestToSend: false, break: false}); + expectedSignals.dataTerminalReady = true; + expectedSignals.requestToSend = false; + expectedSignals.break = false; assert_object_equals(fakePort.outputSignals, expectedSignals, 'invert'); }, 'setSignals() modifies the state of the port');
diff --git a/third_party/blink/web_tests/wpt_internal/serial/serialPort_writable.https.window.js b/third_party/blink/web_tests/wpt_internal/serial/serialPort_writable.https.window.js index bf97394..97d43b1 100644 --- a/third_party/blink/web_tests/wpt_internal/serial/serialPort_writable.https.window.js +++ b/third_party/blink/web_tests/wpt_internal/serial/serialPort_writable.https.window.js
@@ -11,7 +11,7 @@ assert_equals(port.writable, null); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); const writable = port.writable; assert_true(writable instanceof WritableStream); @@ -26,7 +26,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); assert_true(port.writable instanceof WritableStream); const writer = port.writable.getWriter(); @@ -40,7 +40,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); assert_true(port.writable instanceof WritableStream); const writer = port.writable.getWriter(); @@ -60,10 +60,10 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); // Select a buffer size smaller than the amount of data transferred. - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const writer = port.writable.getWriter(); - const data = new Uint8Array(1024); // Much larger than buffersize above. + const data = new Uint8Array(1024); // Much larger than bufferSize above. for (let i = 0; i < data.byteLength; ++i) data[i] = i & 0xff; writer.write(data); @@ -78,7 +78,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); const writable = port.writable; assert_true(writable instanceof WritableStream); @@ -106,7 +106,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); assert_true(port.writable instanceof WritableStream); const writer = port.writable.getWriter(); @@ -123,7 +123,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const originalWritable = port.writable; assert_true(originalWritable instanceof WritableStream); @@ -153,10 +153,10 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); // Select a buffer size smaller than the amount of data transferred. - await port.open({baudrate: 9600, buffersize: 64}); + await port.open({baudRate: 9600, bufferSize: 64}); const writer = port.writable.getWriter(); - const data = new Uint8Array(1024); // Much larger than buffersize above. + const data = new Uint8Array(1024); // Much larger than bufferSize above. for (let i = 0; i < data.byteLength; ++i) data[i] = i & 0xff; writer.write(data); @@ -181,7 +181,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); assert_true(port.writable instanceof WritableStream); const encoder = new TextEncoderStream(); @@ -203,7 +203,7 @@ serial_test(async (t, fake) => { const {port, fakePort} = await getFakeSerialPort(fake); - await port.open({baudrate: 9600}); + await port.open({baudRate: 9600}); assert_true(port.writable instanceof WritableStream); const transform = new TransformStream();
diff --git a/third_party/grpc/BUILD.gn b/third_party/grpc/BUILD.gn index f3b693d3..da32d91 100644 --- a/third_party/grpc/BUILD.gn +++ b/third_party/grpc/BUILD.gn
@@ -33,15 +33,14 @@ # The gRPC library. Note that server side code will not be built. You probably # want to use cc_grpc_library() from grpc_library.gni directly. static_library("grpcpp") { - # This is currently only used by remoting and chromecast. - # NOTE: Using gRPC outside remoting may have security concerns and other + # This is currently only used by chromecast and libassistant. + # NOTE: Using gRPC in Chrome may have security concerns and other # complications when building the binary. Please contact # chrome-security-reviews@ first before you decide to use gRPC. visibility = [ "//chromecast/*", "//chromeos/assistant/internal/*", "//chromeos/services/assistant/*", - "//remoting/*", ] sources = [ "src/src/cpp/client/channel_cc.cc",
diff --git a/third_party/grpc/OWNERS b/third_party/grpc/OWNERS index f49c132..edf33c8 100644 --- a/third_party/grpc/OWNERS +++ b/third_party/grpc/OWNERS
@@ -1,6 +1,8 @@ -jamiewalch@chromium.org -joedow@chromium.org -yuweih@chromium.org +# Chromecast team members +achaulk@chromium.org +dnicoara@chromium.org +halliwell@chromium.org -# COMPONENT: Services>Chromoting -# TEAM: chromoting-team@google.com +# libassistant team members +updowndota@chromium.org +xiaohuic@chromium.org
diff --git a/third_party/xcbproto/patch.diff b/third_party/xcbproto/patch.diff index 59a806e7..a7ba0fb 100644 --- a/third_party/xcbproto/patch.diff +++ b/third_party/xcbproto/patch.diff
@@ -1,6 +1,6 @@ diff -ru xcbproto/src/randr.xml src/src/randr.xml ---- xcbproto/src/randr.xml 2020-07-29 09:55:07.897405223 -0700 -+++ src/src/randr.xml 2020-07-29 09:52:58.484783705 -0700 +--- xcbproto/src/randr.xml 2020-08-03 10:33:29.404868416 -0700 ++++ src/src/randr.xml 2020-08-03 10:29:36.503609230 -0700 @@ -803,64 +803,6 @@ <item name="Lease"> <value>6</value></item> </enum> @@ -174,8 +174,8 @@ </event> </xcb> diff -ru xcbproto/src/xinput.xml src/src/xinput.xml ---- xcbproto/src/xinput.xml 2020-07-29 09:55:07.897405223 -0700 -+++ src/src/xinput.xml 2020-07-29 09:52:58.484783705 -0700 +--- xcbproto/src/xinput.xml 2020-08-03 10:33:29.408868437 -0700 ++++ src/src/xinput.xml 2020-08-03 10:29:36.503609230 -0700 @@ -200,7 +200,12 @@ <list type="STR" name="names"> <fieldref>devices_len</fieldref> @@ -190,9 +190,19 @@ </reply> </request> +@@ -1347,7 +1352,8 @@ + + <!-- XIQueryPointer --> + +- <enum name="Device"> ++ <!-- Chromium patch: Rename so that this will get merged with DeviceId --> ++ <enum name="DEVICE_ID"> + <item name="All"> <value>0</value> </item> + <item name="AllMaster"> <value>1</value> </item> + </enum> diff -ru xcbproto/src/xproto.xml src/src/xproto.xml ---- xcbproto/src/xproto.xml 2020-07-29 09:55:07.901405242 -0700 -+++ src/src/xproto.xml 2020-07-29 09:52:58.484783705 -0700 +--- xcbproto/src/xproto.xml 2020-08-03 10:33:29.408868437 -0700 ++++ src/src/xproto.xml 2020-08-03 10:29:36.503609230 -0700 @@ -4686,7 +4686,7 @@ <field type="CARD8" name="left_pad" /> <field type="CARD8" name="depth" />
diff --git a/third_party/xcbproto/src/src/xinput.xml b/third_party/xcbproto/src/src/xinput.xml index 76db79d..ed170b3e 100644 --- a/third_party/xcbproto/src/src/xinput.xml +++ b/third_party/xcbproto/src/src/xinput.xml
@@ -1352,7 +1352,8 @@ <!-- XIQueryPointer --> - <enum name="Device"> + <!-- Chromium patch: Rename so that this will get merged with DeviceId --> + <enum name="DEVICE_ID"> <item name="All"> <value>0</value> </item> <item name="AllMaster"> <value>1</value> </item> </enum>
diff --git a/tools/android/dependency_analysis/js/package.json b/tools/android/dependency_analysis/js/package.json index 5ae301a..abfaafdc 100644 --- a/tools/android/dependency_analysis/js/package.json +++ b/tools/android/dependency_analysis/js/package.json
@@ -20,6 +20,7 @@ "eslint": "^7.2.0", "eslint-config-google": "^0.14.0", "eslint-plugin-vue": "^7.0.0-alpha.9", + "file-loader": "^6.0.0", "html-webpack-plugin": "^4.3.0", "http-server": "^0.12.3", "style-loader": "^1.2.1",
diff --git a/tools/android/dependency_analysis/js/src/assets/graph_icon.png b/tools/android/dependency_analysis/js/src/assets/graph_icon.png new file mode 100644 index 0000000..6108ef6 --- /dev/null +++ b/tools/android/dependency_analysis/js/src/assets/graph_icon.png Binary files differ
diff --git a/tools/android/dependency_analysis/js/src/chrome_hooks.js b/tools/android/dependency_analysis/js/src/chrome_hooks.js index 2cd2f7dae..ea20d32 100644 --- a/tools/android/dependency_analysis/js/src/chrome_hooks.js +++ b/tools/android/dependency_analysis/js/src/chrome_hooks.js
@@ -23,19 +23,19 @@ } /** - * Shortens a class name, including its package in parentheses at the end. - * @param {string} name The full class name to shorten. - * @return {string} The shortened class name. + * Splits a full class name into its package and class name. + * @param {string} name The full class name to split. + * @return {!Array<string>} An array of [packageName, className]. */ -function shortenClassNameWithPackage(name) { +function splitClassName(name) { const lastDotIdx = name.lastIndexOf('.'); const packageName = name.substring(0, lastDotIdx); const className = name.substring(lastDotIdx + 1); - return `${className} (${shortenPackageName(packageName)})`; + return [packageName, className]; } export { shortenPackageName, shortenClassName, - shortenClassNameWithPackage, + splitClassName, };
diff --git a/tools/android/dependency_analysis/js/src/display_settings_data.js b/tools/android/dependency_analysis/js/src/display_settings_data.js index 4cfadaeb..65fc914 100644 --- a/tools/android/dependency_analysis/js/src/display_settings_data.js +++ b/tools/android/dependency_analysis/js/src/display_settings_data.js
@@ -85,11 +85,11 @@ } /** - * Removes a node from the filter list (i.e., set state to ignored) if it + * Delists a node from the filter list (i.e., set state to ignored) if it * exists. - * @param {string} nodeName The name of the node to remove. + * @param {string} nodeName The name of the node to delist. */ - removeNode(nodeName) { + delistNode(nodeName) { const deleteIndex = this.filterList.findIndex( filterEntry => filterEntry.name === nodeName); if (deleteIndex >= 0) { @@ -118,6 +118,14 @@ } /** + * Delists all unchecked nodes from the filter list. + */ + delistUnchecked() { + this.filterList = this.filterList.filter( + filterEntry => filterEntry.checked); + } + + /** * @return {!Set<string>} A set of nodes that are checked in the filter. */ getSelectedNodeSet() {
diff --git a/tools/android/dependency_analysis/js/src/vue_components/class_details_panel.vue b/tools/android/dependency_analysis/js/src/vue_components/class_details_panel.vue index 6bfb9c78..3e40a74 100644 --- a/tools/android/dependency_analysis/js/src/vue_components/class_details_panel.vue +++ b/tools/android/dependency_analysis/js/src/vue_components/class_details_panel.vue
@@ -3,24 +3,36 @@ found in the LICENSE file. --> <template> - <div - v-if="selectedClass !== null" - class="class-details-panel"> - <LinkToGraph - :filter="[selectedClass.packageName]" - :graph-type="PagePathName.PACKAGE" - :text="'View ' + selectedClass.packageName"/> - <div v-if="selectedClass.buildTargets.length > 0"> - <div>Class buildtarget(s):</div> - <ul> - <li - v-for="buildTarget in selectedClass.buildTargets" - :key="buildTarget"> - {{ buildTarget }} - </li> - </ul> - </div> - </div> + <MdList class="md-double-line details-list"> + <MdListItem> + <div class="list-item-entry"> + <!-- Ideally this is the first element under .md-list-item-text for a + double-line layout, but vue-material doesn't recognize this + component. Therefore it's pulled outside, and a placeholder <span/> + is added so the second line would be properly styled. --> + <LinkToGraph + :filter="[selectedClass.packageName]" + :graph-type="PagePathName.PACKAGE" + :text="selectedClass.packageName"/> + <div class="md-list-item-text"> + <span/> + <span>Package Graph URL</span> + </div> + </div> + </MdListItem> + <MdListItem v-if="selectedClass.buildTargets.length > 0"> + <div class="md-list-item-text"> + <ul class="buildtarget-list"> + <li + v-for="buildTarget in selectedClass.buildTargets" + :key="buildTarget"> + {{ buildTarget }} + </li> + </ul> + <span>Build Targets</span> + </div> + </MdListItem> + </MdList> </template> <script> @@ -43,3 +55,17 @@ export default ClassDetailsPanel; </script> + +<style scoped> +.buildtarget-list { + padding-left: 0; +} + +.details-list { + padding: 0; +} + +.list-item-entry { + width: 100%; +} +</style>
diff --git a/tools/android/dependency_analysis/js/src/vue_components/class_graph_page.vue b/tools/android/dependency_analysis/js/src/vue_components/class_graph_page.vue index 9dc9e73c..d3002ce4 100644 --- a/tools/android/dependency_analysis/js/src/vue_components/class_graph_page.vue +++ b/tools/android/dependency_analysis/js/src/vue_components/class_graph_page.vue
@@ -30,15 +30,16 @@ <GraphFilterItems id="graph-filter-items" :node-filter-data="displaySettingsData.nodeFilterData" - :shorten-name="filterShortenName" - @[CUSTOM_EVENTS.FILTER_REMOVE]="filterRemoveNode" + :get-display-data="filterGetDisplayData" + @[CUSTOM_EVENTS.FILTER_DELIST]="filterDelistNode" @[CUSTOM_EVENTS.FILTER_CHECK_ALL]="filterCheckAll" - @[CUSTOM_EVENTS.FILTER_UNCHECK_ALL]="filterUncheckAll"/> + @[CUSTOM_EVENTS.FILTER_UNCHECK_ALL]="filterUncheckAll" + @[CUSTOM_EVENTS.FILTER_DELIST_UNCHECKED]="filterDelistUnchecked"/> <GraphFilterInput :node-ids="pageModel.getNodeIds()" :nodes-already-in-filter=" displaySettingsData.nodeFilterData.filterList" - :shorten-name="filterShortenName" + :get-short-name="filterGetShortName" @[CUSTOM_EVENTS.FILTER_SUBMITTED]="filterAddOrCheckNode"/> <MdSubheader class="sidebar-subheader"> Display Options @@ -72,9 +73,10 @@ <GraphSelectedNodeDetails :selected-node-details-data="pageModel.selectedNodeDetailsData" @[CUSTOM_EVENTS.DETAILS_CHECK_NODE]="filterAddOrCheckNode" - @[CUSTOM_EVENTS.DETAILS_UNCHECK_NODE]="filterUncheckNode"/> - <ClassDetailsPanel - :selected-class="pageModel.selectedNodeDetailsData.selectedNode"/> + @[CUSTOM_EVENTS.DETAILS_UNCHECK_NODE]="filterUncheckNode"> + <ClassDetailsPanel + :selected-class="pageModel.selectedNodeDetailsData.selectedNode"/> + </GraphSelectedNodeDetails> </div> </div> </template> @@ -91,7 +93,7 @@ DisplaySettingsPreset, } from '../display_settings_data.js'; import {parseClassGraphModelFromJson} from '../process_graph_json.js'; -import {shortenClassNameWithPackage} from '../chrome_hooks.js'; +import {shortenPackageName, splitClassName} from '../chrome_hooks.js'; import ClassDetailsPanel from './class_details_panel.vue'; import ClassGraphHullSettings from './class_graph_hull_settings.vue'; @@ -203,9 +205,19 @@ const pageUrl = urlProcessor.getUrl(document.URL, PagePathName.CLASS); history.replaceState(null, '', pageUrl); }, - filterShortenName: shortenClassNameWithPackage, - filterRemoveNode: function(nodeName) { - this.displaySettingsData.nodeFilterData.removeNode(nodeName); + filterGetShortName: function(fullClassName) { + const [packageName, className] = splitClassName(fullClassName); + return `${className} (${shortenPackageName(packageName)})`; + }, + filterGetDisplayData: function(fullClassName) { + const [packageName, className] = splitClassName(fullClassName); + return { + firstLine: className, + secondLine: shortenPackageName(packageName), + }; + }, + filterDelistNode: function(nodeName) { + this.displaySettingsData.nodeFilterData.delistNode(nodeName); }, filterAddOrCheckNode: function(nodeName) { this.displaySettingsData.nodeFilterData.addOrFindNode( @@ -221,6 +233,9 @@ filterUncheckAll: function() { this.displaySettingsData.nodeFilterData.uncheckAll(); }, + filterDelistUnchecked: function() { + this.displaySettingsData.nodeFilterData.delistUnchecked(); + }, /** * @param {number} depth The new inbound depth. */ @@ -256,13 +271,6 @@ export default ClassGraphPage; </script> -<style> -.user-input-group { - display: flex; - flex-direction: column; -} -</style> - <style scoped> #title { padding: 10px; @@ -286,7 +294,7 @@ flex-direction: column; flex-grow: 0; overflow-y: scroll; - padding: 0 20px; + padding: 0 20px 20px 20px; width: 30vw; }
diff --git a/tools/android/dependency_analysis/js/src/vue_components/graph_filter_input.vue b/tools/android/dependency_analysis/js/src/vue_components/graph_filter_input.vue index a3c8345..7ac6d324 100644 --- a/tools/android/dependency_analysis/js/src/vue_components/graph_filter_input.vue +++ b/tools/android/dependency_analysis/js/src/vue_components/graph_filter_input.vue
@@ -31,16 +31,16 @@ props: { nodeIds: Array, nodesAlreadyInFilter: Array, - shortenName: Function, + getShortName: Function, }, data: function() { return { - // Sorts the nodes by their shortened names, which will be displayed. - // this.shortenName() is cached to improve performance (~150 ms at load). + // Sorts the nodes by their short names, which will be displayed. + // this.getShortName() is cached to improve performance (~150 ms at load). nodeIdsSortedByShortNames: this.nodeIds .map(name => ({ realName: name, - shortName: this.shortenName(name), + shortName: this.getShortName(name), })) .sort((a, b) => a.shortName.localeCompare(b.shortName)) .map(nameObj => nameObj.realName), @@ -54,7 +54,7 @@ }, methods: { getResultValue: function(result) { - return this.shortenName(result); + return this.getShortName(result); }, search: function(searchTerm) {
diff --git a/tools/android/dependency_analysis/js/src/vue_components/graph_filter_items.vue b/tools/android/dependency_analysis/js/src/vue_components/graph_filter_items.vue index b139646..a4ea3af22 100644 --- a/tools/android/dependency_analysis/js/src/vue_components/graph_filter_items.vue +++ b/tools/android/dependency_analysis/js/src/vue_components/graph_filter_items.vue
@@ -15,23 +15,31 @@ @click="uncheckAll"> Uncheck All </MdButton> + <MdButton + class="md-primary md-raised md-dense" + @click="delistUnchecked"> + Delist Unchecked + </MdButton> </div> <MdList id="filter-list" - class="md-scrollbar"> + class="md-scrollbar md-double-line"> <MdListItem - v-for="node in filterList" + v-for="(node, index) in filterList" :key="node.name"> <MdButton class="numeric-input-button md-icon-button md-dense" - @click="removeFromFilter(node.name)"> + @click="delistFromFilter(node.name)"> <MdIcon>clear</MdIcon> </MdButton> <MdCheckbox v-model="node.checked" class="md-primary"/> <div class="filter-items-text md-list-item-text"> - {{ shortenName(node.name) }} + <div>{{ filterListDisplayData[index].firstLine }}</div> + <div v-if="filterListDisplayData[index].secondLine !== ''"> + {{ filterListDisplayData[index].secondLine }} + </div> </div> </MdListItem> </MdList> @@ -45,14 +53,31 @@ const GraphFilterItems = { props: { nodeFilterData: Object, - shortenName: Function, + getDisplayData: Function, }, data: function() { return this.nodeFilterData; }, + computed: { + /** + * Computes an array of display values such that filterListDisplayData[i] + * corresponds to filterList[i]. + * + * This is needed instead of computing a new array to iterate over in the + * template since checkboxes are v-model bound to `node.checked` in the + * template. If a new array were computed, the binding would be on the + * elements of the new array instead of `filterList`. + * + * @return {!Array<{firstLine: string, secondLine: string}>} Text lines to + * display in UI. + */ + filterListDisplayData: function() { + return this.filterList.map(node => this.getDisplayData(node.name)); + }, + }, methods: { - removeFromFilter: function(nodeName) { - this.$emit(CUSTOM_EVENTS.FILTER_REMOVE, nodeName); + delistFromFilter: function(nodeName) { + this.$emit(CUSTOM_EVENTS.FILTER_DELIST, nodeName); }, checkAll: function() { this.$emit(CUSTOM_EVENTS.FILTER_CHECK_ALL); @@ -60,19 +85,15 @@ uncheckAll: function() { this.$emit(CUSTOM_EVENTS.FILTER_UNCHECK_ALL); }, + delistUnchecked: function() { + this.$emit(CUSTOM_EVENTS.FILTER_DELIST_UNCHECKED); + }, }, }; export default GraphFilterItems; </script> -<style> -#filter-list .md-list-item-content { - min-height: 0; - padding: 0; -} -</style> - <style scoped> ul { list-style-type: none; @@ -98,6 +119,11 @@ overflow-y: scroll; } +#filter-list >>> .md-list-item-content { + min-height: 0; + padding: 0; +} + #controls { display: flex; flex-direction: row;
diff --git a/tools/android/dependency_analysis/js/src/vue_components/graph_selected_node_details.vue b/tools/android/dependency_analysis/js/src/vue_components/graph_selected_node_details.vue index bcb6b8b5..1b975a07 100644 --- a/tools/android/dependency_analysis/js/src/vue_components/graph_selected_node_details.vue +++ b/tools/android/dependency_analysis/js/src/vue_components/graph_selected_node_details.vue
@@ -5,24 +5,9 @@ <template> <div class="selected-node-details"> <template v-if="selectedNode !== null"> - <MdList class="md-double-line"> - <MdListItem> - <div class="md-list-item-text"> - <span class="selected-node-details-text"> - {{ selectedNode.id }} - </span> - <span>Name</span> - </div> - </MdListItem> - <MdListItem> - <div class="md-list-item-text"> - <span class="selected-node-details-text"> - {{ selectedNode.displayName }} - </span> - <span>Display Name</span> - </div> - </MdListItem> - </MdList> + <div class="md-title selected-node-title"> + {{ selectedNode.displayName }} + </div> <MdButton v-if="selectedNode.visualizationState.selectedByFilter" class="md-primary md-raised md-dense" @@ -35,6 +20,17 @@ @click="checkNodeInFilter"> Add/check in filter </MdButton> + <MdList class="md-double-line details-list"> + <MdListItem> + <div class="md-list-item-text"> + <span class="selected-node-details-text"> + {{ selectedNode.id }} + </span> + <span>Full Name</span> + </div> + </MdListItem> + </MdList> + <slot/> </template> <div v-else> (Click a node for more details.) @@ -72,8 +68,15 @@ flex-direction: column; } -.selected-node-details-text{ - display: inline-block; +.details-list { + padding: 0; +} + +.selected-node-title { + word-wrap: break-word; +} + +.selected-node-details-text { white-space: normal; width: 100%; word-wrap: break-word;
diff --git a/tools/android/dependency_analysis/js/src/vue_components/link_to_graph.vue b/tools/android/dependency_analysis/js/src/vue_components/link_to_graph.vue index 8da30f0d..9e354ca 100644 --- a/tools/android/dependency_analysis/js/src/vue_components/link_to_graph.vue +++ b/tools/android/dependency_analysis/js/src/vue_components/link_to_graph.vue
@@ -3,12 +3,23 @@ found in the LICENSE file. --> <template> - <a :href="url">{{ text }}</a> + <a + class="link-to-graph-container" + :href="url"> + <img + class="link-to-graph-icon" + :src="GraphIcon"> + <div class="link-to-graph-text"> + {{ text }} + </div> + </a> </template> <script> import {UrlProcessor, URL_PARAM_KEYS} from '../url_processor.js'; +import GraphIcon from '../assets/graph_icon.png'; + // @vue/component const LinkToGraph = { props: { @@ -17,6 +28,7 @@ text: String, }, computed: { + GraphIcon: () => GraphIcon, url: function() { const urlProcessor = UrlProcessor.createForOutput(); urlProcessor.appendArray(URL_PARAM_KEYS.FILTER_NAMES, this.filter); @@ -27,3 +39,23 @@ export default LinkToGraph; </script> + +<style scoped> +.link-to-graph-container { + align-items: center; + display: flex; + flex-direction: row; +} + +.link-to-graph-icon { + height: 24px; + margin-right: 10px; + width: 24px; +} + +.link-to-graph-text { + min-width: 0; + white-space: normal; + word-wrap: break-word; +} +</style>
diff --git a/tools/android/dependency_analysis/js/src/vue_components/package_details_panel.vue b/tools/android/dependency_analysis/js/src/vue_components/package_details_panel.vue index 456a9fe..eff5965 100644 --- a/tools/android/dependency_analysis/js/src/vue_components/package_details_panel.vue +++ b/tools/android/dependency_analysis/js/src/vue_components/package_details_panel.vue
@@ -3,24 +3,49 @@ found in the LICENSE file. --> <template> - <div - v-if="selectedPackage !== null" - class="package-details-panel"> - <LinkToGraph - :filter="packageClassNames" - :graph-type="PagePathName.CLASS" - text="Class graph with all classes in this package"/> - <ul> - <li - v-for="classObj in packageClassObjects" - :key="classObj.name"> + <MdList class="md-double-line details-list"> + <MdListItem> + <div class="list-item-entry"> + <!-- Ideally this is the first element under .md-list-item-text for a + double-line layout, but vue-material doesn't recognize this + component. Therefore it's pulled outside, and a placeholder <span/> + is added so the second line would be properly styled. --> <LinkToGraph - :filter="[classObj.name]" + :filter="packageClassNames" :graph-type="PagePathName.CLASS" - :text="classObj.shortName"/> - </li> - </ul> - </div> + :text="selectedPackage.displayName"/> + <div class="md-list-item-text"> + <span/> + <span>Full Class Graph URL</span> + </div> + </div> + </MdListItem> + <MdListItem> + <div class="list-item-entry"> + <!-- Ideally this is the first element under .md-list-item-text for a + double-line layout, but vue-material doesn't recognize this + component. Therefore it's pulled outside, and a placeholder <span/> + is added so the second line would be properly styled. --> + <MdList + id="class-list" + class="md-scrollbar"> + <MdListItem + v-for="classObj in packageClassObjects" + :key="classObj.name"> + <LinkToGraph + class="class-list-entry" + :filter="[classObj.name]" + :graph-type="PagePathName.CLASS" + :text="classObj.shortName"/> + </MdListItem> + </MdList> + <div class="md-list-item-text"> + <span/> + <span>Individual Class Graph URLs</span> + </div> + </div> + </MdListItem> + </MdList> </template> <script> @@ -57,10 +82,27 @@ </script> <style scoped> -.package-details-panel { - max-height: 400px; - min-height: 200px; +#class-list { + max-height: 300px; overflow-y: scroll; - overflow-x: hidden; +} + +#class-list >>> .md-list-item-content { + min-height: 0; + padding: 0; +} + +.class-list-entry { + width: 100%; +} + +.details-list { + padding: 0; +} + +.list-item-entry { + display: flex; + flex-direction: column; + width: 100%; } </style>
diff --git a/tools/android/dependency_analysis/js/src/vue_components/package_graph_page.vue b/tools/android/dependency_analysis/js/src/vue_components/package_graph_page.vue index 048c049..94fe9ed1 100644 --- a/tools/android/dependency_analysis/js/src/vue_components/package_graph_page.vue +++ b/tools/android/dependency_analysis/js/src/vue_components/package_graph_page.vue
@@ -28,15 +28,16 @@ <GraphFilterItems id="graph-filter-items" :node-filter-data="displaySettingsData.nodeFilterData" - :shorten-name="filterShortenName" - @[CUSTOM_EVENTS.FILTER_REMOVE]="filterRemoveNode" + :get-display-data="filterGetDisplayData" + @[CUSTOM_EVENTS.FILTER_DELIST]="filterDelistNode" @[CUSTOM_EVENTS.FILTER_CHECK_ALL]="filterCheckAll" - @[CUSTOM_EVENTS.FILTER_UNCHECK_ALL]="filterUncheckAll"/> + @[CUSTOM_EVENTS.FILTER_UNCHECK_ALL]="filterUncheckAll" + @[CUSTOM_EVENTS.FILTER_DELIST_UNCHECKED]="filterDelistUnchecked"/> <GraphFilterInput :node-ids="pageModel.getNodeIds()" :nodes-already-in-filter=" displaySettingsData.nodeFilterData.filterList" - :shorten-name="filterShortenName" + :get-short-name="filterGetShortName" @[CUSTOM_EVENTS.FILTER_SUBMITTED]="filterAddOrCheckNode"/> <MdSubheader class="sidebar-subheader"> Display Options @@ -67,9 +68,10 @@ <GraphSelectedNodeDetails :selected-node-details-data="pageModel.selectedNodeDetailsData" @[CUSTOM_EVENTS.DETAILS_CHECK_NODE]="filterAddOrCheckNode" - @[CUSTOM_EVENTS.DETAILS_UNCHECK_NODE]="filterUncheckNode"/> - <PackageDetailsPanel - :selected-package="pageModel.selectedNodeDetailsData.selectedNode"/> + @[CUSTOM_EVENTS.DETAILS_UNCHECK_NODE]="filterUncheckNode"> + <PackageDetailsPanel + :selected-package="pageModel.selectedNodeDetailsData.selectedNode"/> + </GraphSelectedNodeDetails> </div> </div> </template> @@ -177,9 +179,15 @@ const pageUrl = urlProcessor.getUrl(document.URL, PagePathName.PACKAGE); history.replaceState(null, '', pageUrl); }, - filterShortenName: shortenPackageName, - filterRemoveNode: function(nodeName) { - this.displaySettingsData.nodeFilterData.removeNode(nodeName); + filterGetShortName: shortenPackageName, + filterGetDisplayData: function(fullPackageName) { + return { + firstLine: shortenPackageName(fullPackageName), + secondLine: '', + }; + }, + filterDelistNode: function(nodeName) { + this.displaySettingsData.nodeFilterData.delistNode(nodeName); }, filterAddOrCheckNode: function(nodeName) { this.displaySettingsData.nodeFilterData.addOrFindNode( @@ -195,6 +203,9 @@ filterUncheckAll: function() { this.displaySettingsData.nodeFilterData.uncheckAll(); }, + filterDelistUnchecked: function() { + this.displaySettingsData.nodeFilterData.delistUnchecked(); + }, /** * @param {number} depth The new inbound depth. */ @@ -260,7 +271,7 @@ flex-direction: column; flex-grow: 0; overflow-y: scroll; - padding: 0 20px; + padding: 0 20px 20px 20px; width: 30vw; }
diff --git a/tools/android/dependency_analysis/js/src/vue_custom_events.js b/tools/android/dependency_analysis/js/src/vue_custom_events.js index 1a426b5..4c65406 100644 --- a/tools/android/dependency_analysis/js/src/vue_custom_events.js +++ b/tools/android/dependency_analysis/js/src/vue_custom_events.js
@@ -9,7 +9,8 @@ DETAILS_UNCHECK_NODE: 'details-uncheck-node', DISPLAY_OPTION_CHANGED: 'display-option-changed', DISPLAY_PRESET_SELECTED: 'display-preset-selected', - FILTER_REMOVE: 'filter-remove', + FILTER_DELIST: 'filter-delist', + FILTER_DELIST_UNCHECKED: 'filter-delist-unchecked', FILTER_CHECK_ALL: 'filter-check-all', FILTER_UNCHECK_ALL: 'filter-uncheck-all', FILTER_SUBMITTED: 'filter-submitted',
diff --git a/tools/android/dependency_analysis/js/webpack.config.js b/tools/android/dependency_analysis/js/webpack.config.js index 803ac5c..e399935e 100644 --- a/tools/android/dependency_analysis/js/webpack.config.js +++ b/tools/android/dependency_analysis/js/webpack.config.js
@@ -61,6 +61,10 @@ test: /\.css$/, use: ['vue-style-loader', 'style-loader', 'css-loader'], }, + { + test: /\.(png|svg|jpg|gif)$/, + use: 'file-loader', + }, ], }, plugins: [
diff --git a/tools/android/io_benchmark/io_benchmark.cc b/tools/android/io_benchmark/io_benchmark.cc index ea01b9df..00af687 100644 --- a/tools/android/io_benchmark/io_benchmark.cc +++ b/tools/android/io_benchmark/io_benchmark.cc
@@ -51,10 +51,11 @@ const base::TimeTicks& tick, const base::TimeTicks& tock, int size) { - double delta_us = (tock - tick).InMicrosecondsF(); - double mb_per_second = (static_cast<double>(size) / 1e6) / (delta_us / 1e6); - std::string message = base::StringPrintf("%s %d = %.0fus (%.02fMB/s)", prefix, - size, delta_us, mb_per_second); + base::TimeDelta delta = tock - tick; + double mb_per_second = size * delta.ToHz() / 1e6; + std::string message = + base::StringPrintf("%s %d = %.0fus (%.02fMB/s)", prefix, size, + delta.InMicrosecondsF(), mb_per_second); return message; }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 093e9cc..48373a8 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -1855,6 +1855,7 @@ <int value="16" label="All renderer allocation failure"/> <int value="17" label="Utility process foreground OOM"/> <int value="18" label="All utility process crashes"/> + <int value="19" label="Renderer shutdown from RenderProcessHost::Shutdown"/> </enum> <enum name="AndroidProcessedMinidumps"> @@ -6246,6 +6247,7 @@ <int value="229" label="RFH_INACTIVE_CHECK_FROM_SPECULATIVE_RFH"/> <int value="230" label="RFH_SUBFRAME_CAPTURE_ON_MAIN_FRAME"/> <int value="231" label="RFH_CSP_ATTRIBUTE"/> + <int value="232" label="RFH_RECEIVED_ASSOCIATED_MESSAGE_WHILE_BFCACHED"/> </enum> <enum name="BadMessageReasonExtensions"> @@ -7626,6 +7628,11 @@ <int value="1" label="Invalid"/> </enum> +<enum name="BooleanIsAdaptiveIcon"> + <int value="0" label="Non adaptive icon"/> + <int value="1" label="Adaptive icon"/> +</enum> + <enum name="BooleanIsGenerationTriggeredManually"> <int value="0" label="Password generation was triggered automatically"/> <int value="1" label="A user triggered password generation"/> @@ -21410,6 +21417,8 @@ <int value="766" label="InsecurePrivateNetworkRequestsAllowed"/> <int value="767" label="InsecurePrivateNetworkRequestsAllowedForUrls"/> <int value="768" label="UserPrintersAllowed"/> + <int value="769" label="Printers"/> + <int value="770" label="PrintersBulkConfiguration"/> </enum> <enum name="EnterprisePolicyDeviceIdValidity"> @@ -28702,6 +28711,8 @@ <int value="3373" label="WrongBaselineOfEmptyLineButton"/> <int value="3374" label="V8RTCRtpTransceiver_Stopped_AttributeGetter"/> <int value="3375" label="V8RTCRtpTransceiver_Stop_Method"/> + <int value="3376" label="SecurePaymentConfirmation"/> + <int value="3377" label="CSSInvalidVariableUnset"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -39094,6 +39105,7 @@ <int value="5" label="Non-integral x offset"/> <int value="6" label="Non-integral y offset"/> <int value="7" label="Will-change: transform"/> + <int value="8" label="Pixel or color effect"/> </enum> <enum name="LevelDBCorruptionRestoreValue"> @@ -39973,7 +39985,6 @@ <int value="-2105133782" label="GesturePropertiesDBusService:enabled"/> <int value="-2104950596" label="HandwritingGesture:enabled"/> <int value="-2104654357" label="GamesHub:enabled"/> - <int value="-2103664329" label="EnableHighResolutionMouseScrolling:disabled"/> <int value="-2101682955" label="EnableNotificationIndicator:enabled"/> <int value="-2101337189" label="AutofillOffNoServerData:disabled"/> <int value="-2099486626" label="DownloadLater:enabled"/> @@ -40645,6 +40656,7 @@ <int value="-1433719718" label="enable-webrtc-stun-origin"/> <int value="-1433452630" label="AllowRemoteContextForNotifications:enabled"/> <int value="-1433087548" label="enable-app-install-alerts"/> + <int value="-1432246303" label="FilesZipPack:enabled"/> <int value="-1431722713" label="TabFreeze:disabled"/> <int value="-1431563697" label="WebPaymentsMethodSectionOrderV2:enabled"/> <int value="-1430090822" label="EnableSharedImageForWebview:disabled"/> @@ -40696,6 +40708,7 @@ <int value="-1388817073" label="OmniboxReverseAnswers:disabled"/> <int value="-1386966873" label="disable-mac-views-native-app-windows"/> <int value="-1386790338" label="ImeMozcProto:disabled"/> + <int value="-1386776772" label="FilesZipPack:disabled"/> <int value="-1385221197" label="AllowSignedHTTPExchangeCertsWithoutExtension:enabled"/> <int value="-1384426209" label="SharingDeviceRegistration:disabled"/> @@ -41018,6 +41031,7 @@ <int value="-1069628248" label="OmniboxZeroSuggestionsOnSERP:enabled"/> <int value="-1069453905" label="CCTModuleUseIntentExtras:disabled"/> <int value="-1067635248" label="SpeculativeResourcePrefetching:disabled"/> + <int value="-1065227777" label="CrOSAutoSelect:disabled"/> <int value="-1064733740" label="ui-show-composited-layer-borders"/> <int value="-1064302126" label="OmniboxAlternateMatchDescriptionSeparator:enabled"/> @@ -41194,6 +41208,7 @@ <int value="-886912558" label="ChromeHomePromo:enabled"/> <int value="-886898803" label="CooperativeScheduling:enabled"/> <int value="-885601782" label="enable-contextual-search"/> + <int value="-885209667" label="FilesZipMount:disabled"/> <int value="-884864731" label="WebPaymentsSingleAppUiSkip:enabled"/> <int value="-883694393" label="SyncPseudoUSSSupervisedUsers:disabled"/> <int value="-883608641" label="enable-cros-action-recorder"/> @@ -41233,7 +41248,6 @@ <int value="-850821337" label="WebContentsForceDark:enabled"/> <int value="-848691867" label="DesktopPWAWindowing:enabled"/> <int value="-847216521" label="ChromeDuplex:enabled"/> - <int value="-847200849" label="EnableHighResolutionMouseScrolling:enabled"/> <int value="-844537521" label="HttpFormWarning:disabled"/> <int value="-844381918" label="ArcNativeBridgeExperiment:disabled"/> <int value="-843496368" label="AutofillRejectCompanyBirthyear:disabled"/> @@ -42462,6 +42476,8 @@ <int value="504994663" label="GenericSensor:disabled"/> <int value="505561325" label="OpenXR:disabled"/> <int value="506680761" label="WebNFC:disabled"/> + <int value="510060832" + label="OmniboxFocusGestureTriggersContextualWebZeroSuggest:disabled"/> <int value="510066229" label="AutofillEnforceMinRequiredFieldsForQuery:enabled"/> <int value="510814146" label="OfflineBookmarks:enabled"/> @@ -42511,6 +42527,7 @@ <int value="564522013" label="Av1Decoder:disabled"/> <int value="565406673" label="EnableVirtualKeyboardMdUi:enabled"/> <int value="567368307" label="enable-experimental-canvas-features"/> + <int value="572915501" label="FilesZipUnpack:disabled"/> <int value="573385109" label="SharedClipboardUI:enabled"/> <int value="575380532" label="ExperimentalAccessibilityLabels:disabled"/> <int value="575394365" label="AndroidPaymentApps:disabled"/> @@ -42565,6 +42582,7 @@ <int value="624317932" label="print-pdf-as-image"/> <int value="624368375" label="OmniboxEntitySuggestions:enabled"/> <int value="625273056" label="disable-boot-animation"/> + <int value="626605468" label="FilesZipUnpack:enabled"/> <int value="628302973" label="NTPSnippets:enabled"/> <int value="628570445" label="AndroidAutofillAccessibility:enabled"/> <int value="629549626" label="ContextualSearchMlTapSuppression:enabled"/> @@ -42708,6 +42726,8 @@ <int value="749516419" label="DragToSnapInClamshellMode:disabled"/> <int value="752194066" label="enable-app-window-cycling"/> <int value="752939691" label="disable-tab-for-desktop-share"/> + <int value="754816492" + label="OmniboxFocusGestureTriggersContextualWebZeroSuggest:enabled"/> <int value="757645375" label="AndroidDarkSearch:disabled"/> <int value="760542355" label="ServiceWorkerScriptFullCodeCache:enabled"/> <int value="762700519" label="enable-checker-imaging"/> @@ -43322,6 +43342,7 @@ <int value="1413158119" label="WebRtcRemoteEventLog:disabled"/> <int value="1413334779" label="WebPaymentsMinimalUI:enabled"/> <int value="1413948819" label="NupPrinting:enabled"/> + <int value="1414918327" label="enable-accelerated-video-decode"/> <int value="1416592483" label="ash-enable-mirrored-screen"/> <int value="1418054870" label="SpecialLocale:enabled"/> <int value="1421620678" label="simple-clear-browsing-data-support-string"/> @@ -43503,6 +43524,7 @@ <int value="1628259213" label="DuetTabStripIntegrationAndroid:enabled"/> <int value="1628831121" label="SafeBrowsingUseLocalBlacklistsV2:enabled"/> <int value="1630159957" label="SharingSendViaSync:disabled"/> + <int value="1630283072" label="CrOSAutoSelect:enabled"/> <int value="1630988998" label="VrBrowsingExperimentalRendering:disabled"/> <int value="1632112977" label="ash-disable-tablet-autohide-titlebars"/> <int value="1632176267" label="PDFViewerUpdate:enabled"/> @@ -43718,7 +43740,6 @@ <int value="1861251313" label="enable-message-center-always-scroll-up-upon-notification-removal"/> <int value="1861521561" label="OmniboxLocalEntitySuggestions:enabled"/> - <int value="1861954820" label="HighResolutionMouseScrolling:enabled"/> <int value="1862126613" label="DesktopPWAsRunOnOsLogin:enabled"/> <int value="1862207743" label="enable-android-spellchecker"/> <int value="1863622457" label="WebAuthentication:enabled"/> @@ -43838,6 +43859,7 @@ <int value="1974776131" label="MediaFeeds:disabled"/> <int value="1975657253" label="ScalableAppList:disabled"/> <int value="1976644015" label="enable-forbid-sync-xhr-in-page-dismissal"/> + <int value="1978548617" label="FilesZipMount:enabled"/> <int value="1979222611" label="XRSandbox:disabled"/> <int value="1979472169" label="TabGroupsFeedback:disabled"/> <int value="1980011075" label="debug-packed-apps"/> @@ -52601,6 +52623,8 @@ <int value="1201" label="Show Input Options In Shelf"/> <int value="1202" label="Show Personal Information Suggestions"/> <int value="1203" label="Show Emoji Suggestions"/> + <int value="1204" label="Change System Language"/> + <int value="1205" label="Offer Translation"/> <int value="1300" label="Google Drive Connection"/> <int value="1400" label="Add Printer"/> <int value="1401" label="Saved Printers"/> @@ -68947,6 +68971,11 @@ </int> </enum> +<enum name="TabSearchTabSwitchAction"> + <int value="0" label="Switch to tab from unfiltered tab list"/> + <int value="1" label="Switch to tab from filtered search tab list"/> +</enum> + <enum name="TabStatus"> <int value="0" label="Memory resident"/> <int value="1" label="Evicted and reloaded"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 4a73645c..9a99973 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -8403,6 +8403,39 @@ </summary> </histogram> +<histogram name="Arc.AdaptiveIconLoad.FromArcAppIcon" + enum="BooleanIsAdaptiveIcon" expires_after="2020-12-31"> + <owner>dominickn@chromium.org</owner> + <owner>lgcheng@google.com</owner> + <owner>nancylingwang@chromium.org</owner> + <summary> + The adaptive Arc app icons are loaded from ArcAppIcon. Recorded whether the + icon is the adaptive icon when the icon is loaded. + </summary> +</histogram> + +<histogram name="Arc.AdaptiveIconLoad.FromArcDefaultAppIcon" + enum="BooleanIsAdaptiveIcon" expires_after="2020-12-31"> + <owner>dominickn@chromium.org</owner> + <owner>lgcheng@google.com</owner> + <owner>nancylingwang@chromium.org</owner> + <summary> + The adaptive Arc app icons are loaded from ArcAppIcon for default Arc apps. + Recorded whether the icon is the adaptive icon when the icon is loaded. + </summary> +</histogram> + +<histogram name="Arc.AdaptiveIconLoad.FromNonArcAppIcon" + enum="BooleanIsAdaptiveIcon" expires_after="2020-12-31"> + <owner>dominickn@chromium.org</owner> + <owner>lgcheng@google.com</owner> + <owner>nancylingwang@chromium.org</owner> + <summary> + The adaptive Arc app icons are loaded from Non ArcAppIcon. Recorded whether + the icon is the adaptive icon when the icon is loaded. + </summary> +</histogram> + <histogram name="Arc.AdbSideloadingEnablingScreen" enum="AdbSideloadingPromptEvent" expires_after="M88"> <owner>victorhsieh@chromium.org</owner> @@ -9453,7 +9486,7 @@ </histogram> <histogram name="ArcAuth.MainAccountResolutionStatus" - enum="ArcAuthMainAccountResolutionStatus" expires_after="M85"> + enum="ArcAuthMainAccountResolutionStatus" expires_after="2021-08-11"> <owner>khmel@chromium.org</owner> <owner>jhorwich@chromium.org</owner> <summary>Contains the status of main account resolution.</summary> @@ -80492,6 +80525,18 @@ </summary> </histogram> +<histogram name="Media.History.Init.ResultAfterDelete" + enum="MediaHistoryInitResult" expires_after="2020-12-31"> + <owner>beccahughes@chromium.org</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Recorded when Media History is recreated when the browser is started and the + Media History database has been corrupted to the point where we need to + delete it and start again. This is not recorded in incognito mode or if + "save browsing history" is disabled. + </summary> +</histogram> + <histogram name="Media.History.Playback.WriteResult" enum="MediaHistoryPlaybackWriteResult" expires_after="2020-12-31"> <owner>beccahughes@chromium.org</owner> @@ -89042,6 +89087,18 @@ </summary> </histogram> +<histogram name="MobileIntent.FirstPartyToInternalScheme" enum="Boolean" + expires_after="2021-01-01"> + <owner>peconn@chromium.org</owner> + <owner>peter@chromium.org</owner> + <summary> + Recorded when Chrome on Android is launched to an internal Chrome scheme + (chrome://, chrome-native://, about://) by a first party app (not Chrome). + This metric is to be used to determine whether any first party app uses the + feature, and whether we can remove it. + </summary> +</histogram> + <histogram name="MobileIntent.PageLoadDueToExternalApp" enum="ClientAppId" expires_after="never"> <!-- expires-never: Navigation (external-apps) heartbeat metric for Android. --> @@ -143624,8 +143681,9 @@ </histogram> <histogram name="Renderer4.MainThreadGestureScrollReason" - enum="MainThreadScrollingReason" expires_after="M85"> + enum="MainThreadScrollingReason" expires_after="M88"> <owner>tdresser@chromium.org</owner> + <owner>pdr@chromium.org</owner> <summary> Ideally we'd always scroll on the impl thread, but there are a variety of situations where we need to scroll on main. We should try to drive these @@ -143636,8 +143694,9 @@ </histogram> <histogram name="Renderer4.MainThreadWheelScrollReason" - enum="MainThreadScrollingReason" expires_after="M85"> + enum="MainThreadScrollingReason" expires_after="M88"> <owner>tdresser@chromium.org</owner> + <owner>pdr@chromium.org</owner> <summary> Ideally we'd always scroll on the impl thread, but there are a variety of situations where we need to scroll on main. We should try to drive these @@ -159597,8 +159656,9 @@ </histogram> <histogram name="ServiceWorker.Storage.DeleteAndStartOverResult" - enum="ServiceWorkerDeleteAndStartOverResult" expires_after="M81"> - <owner>nhiroki@chromium.org</owner> + enum="ServiceWorkerDeleteAndStartOverResult" expires_after="M90"> + <owner>bashi@chromium.org</owner> + <owner>chrome-worker@google.com</owner> <summary> Records result of storage recovery operations in ServiceWorkerStorage. </summary> @@ -160241,8 +160301,10 @@ app) also ends a session. Another set of cases is the screen time-out (blanking the screen) or the lock screen. Either will cause Chrome to be considered to leave the foreground, ending the session. (ii) some in-app - actions. Yes, some in-app events trigger the end of a session. These can - mostly be considered bugs. Cases: (a) switching to viewing Bookmarks, + actions. Yes, some in-app events trigger the end of a session. + + Android continued: These in-app actions that trigger the end of a session + can mostly be considered bugs. Cases: (a) switching to viewing Bookmarks, History, Downloads, or Settings causes the session to end. Note that switching out of those modes does not cause the end of a session, only switching in. Oddly, though the interface looks similar, switching to Recent @@ -160254,7 +160316,30 @@ from being one of a set of multi-window apps that are displayed to be the only app displayed. - iOS: not documented. + iOS: A session starts when Chrome is launched to the foreground and ends + when Chrome leaves the screen. This is generally straightforward. Chrome + leaves the screen when the screen goes blank or shows the lock screen, when + Chrome clicks a link that opens in another app, or when the user switches to + the app switcher. Note that, unlike on desktop, even if Chrome is playing + media in the background, the session is still terminated when Chrome leaves + the screen. + + iOS continued: These are some edge cases to be aware of: (i) OS overlays. + These can appear, for examples, when a link is clicked that could go to a + non-Google app that has not yet been set to default and the OS asks whether + to open the link in the app by default, or when a user has set the OS to + block certain sites or types of sites by default and require authentication + to access them. This authentication prompt is an OS overlay. At the time of + writing this description, we're not sure if displaying an overlay will end + the session. (ii) full-screen media playing. Because media is played through + iOS's technology stack, if the user takes media that's playing within Chrome + and displayed it full-screen, the session ends because no part of Chrome is + on the screen anymore. (iii) multi-window support. Not yet launched as of + M-85. Sessions end and immediately restart when a user switches from a + single-window to a multi-window view and vice versa, and also ends when + resizing the Chrome window. The end is because Chrome is considered no + longer active during the time the OS animates the windows to change their + sizes. This histogram is of special interest to the chrome-analysis-team@. Do not change its semantics or retire it without talking to them first. @@ -180140,6 +180225,18 @@ </summary> </histogram> +<histogram name="Tabs.TabSearch.WebUI.TabSwitchAction" + enum="TabSearchTabSwitchAction" expires_after="M90"> + <owner>tluk@chromium.org</owner> + <owner>robliao@chromium.org</owner> + <summary> + Tab Search is a feature that allows users to better search their browsers + for and switch to their desired tabs. This records whether the user used Tab + Search to switch to a tab from a filtered search results list or the default + unfiltered list. + </summary> +</histogram> + <histogram name="Tabs.TabSearch.WindowDisplayedDuration" units="seconds" expires_after="M90"> <owner>tluk@chromium.org</owner> @@ -194468,7 +194565,7 @@ </histogram> <histogram name="WebRTC.Video.InterframeDelay95PercentileInMs" units="ms" - expires_after="2020-09-13"> + expires_after="M88"> <owner>ilnik@chromium.org</owner> <owner>webrtc-video@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/merge_xml.py b/tools/metrics/histograms/merge_xml.py index a715be0..aec1baf 100755 --- a/tools/metrics/histograms/merge_xml.py +++ b/tools/metrics/histograms/merge_xml.py
@@ -74,7 +74,14 @@ key=lambda node: node.getAttribute('name').lower()) for histogram in sorted_histograms: - combined_histograms.appendChild(histogram) + # Use unsafe version of `appendChild` function here because the safe one + # takes a lot longer (10000x) to append all children. The unsafe version + # is ok here because: + # 1. the node to be appended is a clean node. + # 2. The unsafe version only do less check but not changing any + # behavior and it's documented to be usable if performance matters. + # See https://github.com/python/cpython/blob/2.7/Lib/xml/dom/minidom.py#L276. + xml.dom.minidom._append_child(combined_histograms, histogram) return [combined_histograms]
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 78076f9..6c44d5ce 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,16 +1,16 @@ { "trace_processor_shell": { "win": { - "hash": "44fcb6a2624a01261a18b1c94746d06fed032a08", - "remote_path": "perfetto_binaries/trace_processor_shell/win/5697d3550bc824284097e5578ba540ec606c05fb/trace_processor_shell.exe" + "hash": "442e852ef28b8924f6c40fda1431540be2aa0e91", + "remote_path": "perfetto_binaries/trace_processor_shell/win/dbee93ac203d9269fe93c1ff1e48eba6148e542c/trace_processor_shell.exe" }, "mac": { - "hash": "491d5aee4a10985c3a1111db30daa00f10314b69", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/09afd88dfed8bbe701e0eaa096efe7b681ac12f7/trace_processor_shell" + "hash": "27f63277ace856aad218ce2806fcd2a3d5ca0839", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/dbee93ac203d9269fe93c1ff1e48eba6148e542c/trace_processor_shell" }, "linux": { - "hash": "5afe1dad71cc6ead4121b34f3a8d79b033524a1f", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/5697d3550bc824284097e5578ba540ec606c05fb/trace_processor_shell" + "hash": "d1080003a68b2a808256bed9d034529030f1aca9", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/dbee93ac203d9269fe93c1ff1e48eba6148e542c/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm b/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm index e67729e..1597008 100644 --- a/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm +++ b/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm
@@ -447,8 +447,8 @@ if (has_hdr_color_space) type = CALayerType::kHDRCopier; break; - // TODO(crbug.com/1103432): We'll likely need YpCbCr10 here for HDR. case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange: + case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange: // Only allow 4:2:0 frames which fill the layer's contents to be // promoted to AV layers. if (tree->allow_av_sample_buffer_display_layer_ &&
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index 41985f56..fca92cd 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -3333,8 +3333,12 @@ // Active-descendant-changed notifications are typically only relevant when // the change is within the focused widget. - if (atk_object != g_current_focused) + if (!g_current_focused) return; + if (auto* focused_node = FromAtkObject(g_current_focused)) { + if (!focused_node->IsDescendantOf(this)) + return; + } AtkObject* descendant = GetActiveDescendantOfCurrentFocused(); if (descendant == g_current_active_descendant)
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc index 706471c0..bbfc9c6 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
@@ -2556,4 +2556,81 @@ EXPECT_FALSE(AtkObjectHasState(dialog_obj, ATK_STATE_ACTIVE)); } +// Tests if kActiveDescendantChanged on unfocused node triggers a focused event. +TEST_F(AXPlatformNodeAuraLinuxTest, + TestActiveDescendantChangedOnUnfocusedNode) { + AXNodeData menu; + menu.id = 1; + menu.role = ax::mojom::Role::kMenu; + menu.AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId, 4); + menu.child_ids = {2, 3}; + + AXNodeData input; + input.id = 2; + input.role = ax::mojom::Role::kTextField; + input.AddState(ax::mojom::State::kFocusable); + input.AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId, 4); + + AXNodeData container; + container.id = 3; + container.role = ax::mojom::Role::kGenericContainer; + container.child_ids = {4, 5}; + + AXNodeData menu_item_1; + menu_item_1.id = 4; + menu_item_1.role = ax::mojom::Role::kMenuItemCheckBox; + + AXNodeData menu_item_2; + menu_item_2.id = 5; + menu_item_2.role = ax::mojom::Role::kMenuItemCheckBox; + + Init(menu, input, container, menu_item_1, menu_item_2); + TestAXNodeWrapper::SetGlobalIsWebContent(true); + + // Creates TestAXNodeWrapper for the first menu item to keep the current + // active descendant. + AtkObjectFromNode(GetRootAsAXNode()->children()[1]->children()[0]); + + // Sets focus to the input node. + AXNode* input_node = GetRootAsAXNode()->children()[0]; + GetPlatformNode(input_node) + ->NotifyAccessibilityEvent(ax::mojom::Event::kFocus); + + bool saw_active_focus_state_change = false; + AtkObject* menu_2_atk_object = + AtkObjectFromNode(GetRootAsAXNode()->children()[1]->children()[1]); + EXPECT_TRUE(ATK_IS_OBJECT(menu_2_atk_object)); + g_object_ref(menu_2_atk_object); + // Registers callback to get focus event on |menu_2_atk_object|. + g_signal_connect(menu_2_atk_object, "state-change", + G_CALLBACK(+[](AtkObject* atkobject, gchar* state_changed, + gboolean new_value, bool* flag) { + if (!g_strcmp0(state_changed, "focused") && new_value) + *flag = true; + }), + &saw_active_focus_state_change); + + // Updates the active descendant node from the node id 4 to the node id 5; + AXNode* menu_node = GetRootAsAXNode(); + AXNodeData menu_new_data(menu); + menu_new_data.AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId, + 5); + menu_node->SetData(menu_new_data); + + AXNodeData input_new_data(input); + input_new_data.AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId, + 5); + input_node->SetData(input_new_data); + + // Notifies active descendant is changed. + GetPlatformNode(menu_node)->NotifyAccessibilityEvent( + ax::mojom::Event::kActiveDescendantChanged); + // The current active descendant node, |menu_2_atk_object|, should get the + // focused event. + EXPECT_TRUE(saw_active_focus_state_change); + + TestAXNodeWrapper::SetGlobalIsWebContent(false); + g_object_unref(menu_2_atk_object); +} + } // namespace ui
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java index 0c589c4..55065c4 100644 --- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -10,6 +10,7 @@ import android.annotation.TargetApi; import android.app.Activity; import android.app.PendingIntent; +import android.app.UiModeManager; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -189,6 +190,8 @@ private ObserverList<SelectionHandlesObserver> mSelectionHandlesObservers = new ObserverList<>(); + private final boolean mAllowChangeRefreshRate; + /** * Gets the view for readback. */ @@ -220,6 +223,12 @@ mDisplayAndroid = display; mDisplayAndroid.addObserver(this); + // Using this setting is gated to Q due to bugs on Razer phones which can freeze the device + // if the API is used. See crbug.com/990646. + // Disable refresh rate change on TV platforms, as it may cause black screen flicker due to + // display mode changes. + mAllowChangeRefreshRate = BuildInfo.isAtLeastQ() && !isTv(context); + // Multiple refresh rate support is only available on M+. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) recomputeSupportedRefreshRates(); @@ -241,6 +250,13 @@ } } + private static boolean isTv(Context context) { + UiModeManager uiModeManager = + (UiModeManager) context.getSystemService(Context.UI_MODE_SERVICE); + return uiModeManager != null + && uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION; + } + @CalledByNative private static long createForTesting() { WindowAndroid windowAndroid = new WindowAndroid(ContextUtils.getApplicationContext()); @@ -938,7 +954,7 @@ @TargetApi(Build.VERSION_CODES.M) @CalledByNative private float[] getSupportedRefreshRates() { - if (mSupportedRefreshRateModes == null) return null; + if (mSupportedRefreshRateModes == null || !mAllowChangeRefreshRate) return null; float[] supportedRefreshRates = new float[mSupportedRefreshRateModes.size()]; for (int i = 0; i < mSupportedRefreshRateModes.size(); ++i) { @@ -950,9 +966,7 @@ @SuppressLint("NewApi") @CalledByNative private void setPreferredRefreshRate(float preferredRefreshRate) { - // Using this setting is gated to Q due to bugs on Razer phones which can freeze the device - // if the API is used. See crbug.com/990646. - if (mSupportedRefreshRateModes == null || !BuildInfo.isAtLeastQ()) return; + if (mSupportedRefreshRateModes == null || !mAllowChangeRefreshRate) return; int preferredModeId = getPreferredModeId(preferredRefreshRate); Window window = getWindow();
diff --git a/ui/base/clipboard/clipboard_constants.cc b/ui/base/clipboard/clipboard_constants.cc index 3ea7842..e435dd2 100644 --- a/ui/base/clipboard/clipboard_constants.cc +++ b/ui/base/clipboard/clipboard_constants.cc
@@ -10,15 +10,12 @@ const char kMimeTypeTextUtf8[] = "text/plain;charset=utf-8"; const char kMimeTypeURIList[] = "text/uri-list"; const char kMimeTypeMozillaURL[] = "text/x-moz-url"; -// Unstandardized format for downloading files after drop events. Now only -// works in Windows, but used to also work in Linux and MacOS. -// See https://crbug.com/860557 and https://crbug.com/425170. const char kMimeTypeDownloadURL[] = "downloadurl"; const char kMimeTypeHTML[] = "text/html"; const char kMimeTypeRTF[] = "text/rtf"; const char kMimeTypePNG[] = "image/png"; + #if !defined(OS_APPLE) -// TODO(dcheng): This name is temporary. See crbug.com/106449. const char kMimeTypeWebCustomData[] = "chromium/x-web-custom-data"; const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste"; const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data";
diff --git a/ui/base/clipboard/clipboard_constants.h b/ui/base/clipboard/clipboard_constants.h index d749751..bdc32ecba 100644 --- a/ui/base/clipboard/clipboard_constants.h +++ b/ui/base/clipboard/clipboard_constants.h
@@ -24,6 +24,9 @@ COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeText[]; COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeTextUtf8[]; COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeURIList[]; +// Unstandardized format for downloading files after drop events. Now only +// works in Windows, but used to also work in Linux and MacOS. +// See https://crbug.com/860557 and https://crbug.com/425170. COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeDownloadURL[]; COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) @@ -31,7 +34,19 @@ COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeHTML[]; COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeRTF[]; COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypePNG[]; + +// Linux-specific MIME type constants (also used in Fuchsia). +#if defined(OS_LINUX) || defined(OS_FUCHSIA) +COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) +constexpr char kMimeTypeLinuxUtf8String[] = "UTF8_STRING"; +COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) +constexpr char kMimeTypeLinuxString[] = "STRING"; +COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) +constexpr char kMimeTypeLinuxText[] = "TEXT"; +#endif // defined(OS_LINUX) || defined(OS_FUCHSIA) + #if !defined(OS_APPLE) +// TODO(dcheng): This name is temporary. See crbug.com/106449. COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) extern const char kMimeTypeWebCustomData[]; COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES)
diff --git a/ui/base/clipboard/clipboard_ozone.cc b/ui/base/clipboard/clipboard_ozone.cc index 4db9efa6..5f46a62 100644 --- a/ui/base/clipboard/clipboard_ozone.cc +++ b/ui/base/clipboard/clipboard_ozone.cc
@@ -38,12 +38,6 @@ namespace { -// TODO(crbug.com/1105892): those three constants can be found in a few other -// places. Perhaps it would be worth finding some common place for them? -constexpr char kMimeTypeX11String[] = "STRING"; -constexpr char kMimeTypeX11Text[] = "TEXT"; -constexpr char kMimeTypeX11Utf8String[] = "UTF8_STRING"; - // The amount of time to wait for a request to complete before aborting it. constexpr base::TimeDelta kRequestTimeout = base::TimeDelta::FromSeconds(10); @@ -564,8 +558,8 @@ void ClipboardOzone::WriteText(const char* text_data, size_t text_len) { std::vector<uint8_t> data(text_data, text_data + text_len); async_clipboard_ozone_->InsertData( - std::move(data), {kMimeTypeText, kMimeTypeX11Text, kMimeTypeX11String, - kMimeTypeTextUtf8, kMimeTypeX11Utf8String}); + std::move(data), {kMimeTypeText, kMimeTypeLinuxText, kMimeTypeLinuxString, + kMimeTypeTextUtf8, kMimeTypeLinuxUtf8String}); } void ClipboardOzone::WriteHTML(const char* markup_data,
diff --git a/ui/base/clipboard/clipboard_test_template.h b/ui/base/clipboard/clipboard_test_template.h index 61b7dfa..f0cf758 100644 --- a/ui/base/clipboard/clipboard_test_template.h +++ b/ui/base/clipboard/clipboard_test_template.h
@@ -27,6 +27,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "build/chromecast_buildflags.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -167,6 +168,11 @@ EXPECT_THAT(this->GetAvailableTypes(ClipboardBuffer::kCopyPaste), Contains(ASCIIToUTF16(kMimeTypeText))); +#if defined(USE_OZONE) && !defined(OS_CHROMEOS) && !defined(OS_FUCHSIA) && \ + !BUILDFLAG(IS_CHROMECAST) + EXPECT_THAT(this->GetAvailableTypes(ClipboardBuffer::kCopyPaste), + Contains(ASCIIToUTF16(kMimeTypeTextUtf8))); +#endif EXPECT_TRUE(this->clipboard().IsFormatAvailable( ClipboardFormatType::GetPlainTextType(), ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr)); @@ -242,10 +248,13 @@ } #endif // !defined(OS_ANDROID) -// TODO(msisov, tonikitoo): Enable test once ClipboardOzone implements -// selection support. https://crbug.com/911992 -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(USE_OZONE) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) TYPED_TEST(ClipboardTest, MultipleBufferTest) { +#if defined(USE_OZONE) + if (!this->clipboard().IsSelectionBufferAvailable()) + return; +#endif + base::string16 text(ASCIIToUTF16("Standard")), text_result; base::string16 markup(ASCIIToUTF16("<string>Selection</string>")); std::string url("http://www.example.com/"), url_result;
diff --git a/ui/base/clipboard/clipboard_x11.cc b/ui/base/clipboard/clipboard_x11.cc index f5119b6..fff2b73e 100644 --- a/ui/base/clipboard/clipboard_x11.cc +++ b/ui/base/clipboard/clipboard_x11.cc
@@ -758,9 +758,9 @@ base::RefCountedString::TakeString(&str)); x11_details_->InsertMapping(kMimeTypeText, mem); - x11_details_->InsertMapping(kText, mem); - x11_details_->InsertMapping(kString, mem); - x11_details_->InsertMapping(kUtf8String, mem); + x11_details_->InsertMapping(kMimeTypeLinuxText, mem); + x11_details_->InsertMapping(kMimeTypeLinuxString, mem); + x11_details_->InsertMapping(kMimeTypeLinuxUtf8String, mem); } void ClipboardX11::WriteHTML(const char* markup_data,
diff --git a/ui/base/cocoa/menu_controller.h b/ui/base/cocoa/menu_controller.h index 8dc3cdb..566dc96 100644 --- a/ui/base/cocoa/menu_controller.h +++ b/ui/base/cocoa/menu_controller.h
@@ -15,6 +15,13 @@ class MenuModel; } +COMPONENT_EXPORT(UI_BASE) +@protocol MenuControllerCocoaDelegate +- (void)controllerWillAddItem:(NSMenuItem*)menuItem + fromModel:(ui::MenuModel*)model + atIndex:(NSInteger)index; +@end + // A controller for the cross-platform menu model. The menu that's created // has the tag and represented object set for each menu item. The object is a // NSValue holding a pointer to the model for that level of the menu (to @@ -40,6 +47,7 @@ // slightly different form (0th item is empty). Note this attribute of the menu // cannot be changed after it has been created. - (instancetype)initWithModel:(ui::MenuModel*)model + delegate:(id<MenuControllerCocoaDelegate>)delegate useWithPopUpButtonCell:(BOOL)useWithCell; // Programmatically close the constructed menu.
diff --git a/ui/base/cocoa/menu_controller.mm b/ui/base/cocoa/menu_controller.mm index df978482..be5edb5a 100644 --- a/ui/base/cocoa/menu_controller.mm +++ b/ui/base/cocoa/menu_controller.mm
@@ -107,14 +107,12 @@ - (void)itemSelected:(id)sender; @end -@interface ResponsiveNSMenuItem : NSMenuItem -@end - @implementation MenuControllerCocoa { base::WeakPtr<ui::MenuModel> _model; base::scoped_nsobject<NSMenu> _menu; BOOL _useWithPopUpButtonCell; // If YES, 0th item is blank BOOL _isMenuOpen; + id<MenuControllerCocoaDelegate> _delegate; } @synthesize useWithPopUpButtonCell = _useWithPopUpButtonCell; @@ -133,9 +131,11 @@ } - (instancetype)initWithModel:(ui::MenuModel*)model + delegate:(id<MenuControllerCocoaDelegate>)delegate useWithPopUpButtonCell:(BOOL)useWithCell { if ((self = [super init])) { _model = model->AsWeakPtr(); + _delegate = delegate; _useWithPopUpButtonCell = useWithCell; [self menu]; } @@ -153,6 +153,10 @@ [super dealloc]; } +- (void)setDelegate:(id<MenuControllerCocoaDelegate>)delegate { + _delegate = delegate; +} + - (void)cancel { if (_isMenuOpen) { [_menu cancelTracking]; @@ -239,6 +243,10 @@ } } } + + if (_delegate) + [_delegate controllerWillAddItem:item fromModel:model atIndex:index]; + [menu insertItem:item atIndex:index]; }
diff --git a/ui/base/cocoa/menu_controller_unittest.mm b/ui/base/cocoa/menu_controller_unittest.mm index 19a7cec..4d317fc 100644 --- a/ui/base/cocoa/menu_controller_unittest.mm +++ b/ui/base/cocoa/menu_controller_unittest.mm
@@ -170,6 +170,7 @@ model_.AddItem(1, ASCIIToUTF16("foo")); controller_.reset([[WatchedLifetimeMenuController alloc] initWithModel:&model_ + delegate:nil useWithPopUpButtonCell:NO]); [controller_ setDeallocCalled:did_dealloc]; } @@ -225,6 +226,7 @@ SimpleMenuModel model(&delegate); base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); EXPECT_EQ(0, [[menu menu] numberOfItems]); } @@ -241,6 +243,7 @@ base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); EXPECT_EQ(6, [[menu menu] numberOfItems]); @@ -267,6 +270,7 @@ base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); EXPECT_EQ(3, [[menu menu] numberOfItems]); @@ -301,6 +305,7 @@ base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); EXPECT_EQ(2, [[menu menu] numberOfItems]); @@ -328,6 +333,7 @@ base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); EXPECT_EQ(2, [[menu menu] numberOfItems]); @@ -361,6 +367,7 @@ // Create the controller. base::scoped_nsobject<MenuControllerCocoa> menu_controller( [[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); EXPECT_EQ(2, [[menu_controller menu] numberOfItems]); delegate.menu_to_close_ = [menu_controller menu]; @@ -410,6 +417,7 @@ // Create the controller. base::scoped_nsobject<MenuControllerCocoa> menu_controller( [[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); delegate.menu_to_close_ = [menu_controller menu]; @@ -450,6 +458,7 @@ // title. base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:YES]); EXPECT_EQ(4, [[menu menu] numberOfItems]); EXPECT_EQ(base::string16(), @@ -466,6 +475,7 @@ model.AddItem(1, ASCIIToUTF16("one")); base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); EXPECT_EQ(1, [[menu menu] numberOfItems]); @@ -496,6 +506,7 @@ base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); EXPECT_EQ(3, [[menu menu] numberOfItems]); @@ -514,6 +525,7 @@ base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); EXPECT_EQ(2, [[menu menu] numberOfItems]); @@ -556,6 +568,7 @@ model.AddItem(1, ASCIIToUTF16("foo")); base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); EXPECT_EQ(1, [[menu menu] numberOfItems]); // Validate() simulates opening the menu - the item label/icon should be @@ -598,6 +611,7 @@ // Create the controller. base::scoped_nsobject<MenuControllerCocoa> menu([[MenuControllerCocoa alloc] initWithModel:&model + delegate:nil useWithPopUpButtonCell:NO]); delegate.menu_to_close_ = [menu menu];
diff --git a/ui/base/ime/BUILD.gn b/ui/base/ime/BUILD.gn index 21dbb157..b441ea7 100644 --- a/ui/base/ime/BUILD.gn +++ b/ui/base/ime/BUILD.gn
@@ -58,8 +58,6 @@ "constants.h", "ime_assistive_window_handler_interface.h", "ime_candidate_window_handler_interface.h", - "ime_engine_handler_interface.h", - "ime_input_context_handler_interface.h", "input_method.h", "input_method_base.cc", "input_method_base.h", @@ -71,8 +69,6 @@ "input_method_minimal.cc", "input_method_minimal.h", "input_method_observer.h", - "mock_ime_input_context_handler.cc", - "mock_ime_input_context_handler.h", "mock_input_method.cc", "mock_input_method.h", "text_edit_commands.h",
diff --git a/ui/base/ime/chromeos/BUILD.gn b/ui/base/ime/chromeos/BUILD.gn index 9ced5ab..bb036a98 100644 --- a/ui/base/ime/chromeos/BUILD.gn +++ b/ui/base/ime/chromeos/BUILD.gn
@@ -22,6 +22,8 @@ "fake_input_method_delegate.h", "ime_bridge.cc", "ime_bridge.h", + "ime_engine_handler_interface.h", + "ime_input_context_handler_interface.h", "ime_keyboard.cc", "ime_keyboard_impl.cc", "ime_keyboard_impl.h", @@ -44,6 +46,8 @@ "mock_ime_candidate_window_handler.h", "mock_ime_engine_handler.cc", "mock_ime_engine_handler.h", + "mock_ime_input_context_handler.cc", + "mock_ime_input_context_handler.h", ] defines = [ "IS_UI_BASE_IME_CHROMEOS_IMPL" ]
diff --git a/ui/base/ime/chromeos/ime_bridge.h b/ui/base/ime/chromeos/ime_bridge.h index 50c6e67..a6fff1f9 100644 --- a/ui/base/ime/chromeos/ime_bridge.h +++ b/ui/base/ime/chromeos/ime_bridge.h
@@ -8,11 +8,11 @@ #include "base/component_export.h" #include "base/macros.h" #include "build/build_config.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" +#include "ui/base/ime/chromeos/ime_input_context_handler_interface.h" #include "ui/base/ime/ime_assistive_window_handler_interface.h" #include "ui/base/ime/ime_bridge_observer.h" #include "ui/base/ime/ime_candidate_window_handler_interface.h" -#include "ui/base/ime/ime_engine_handler_interface.h" -#include "ui/base/ime/ime_input_context_handler_interface.h" class IMECandidateWindowHandlerInterface; class IMEAssistiveWindowHandlerInterface;
diff --git a/ui/base/ime/ime_engine_handler_interface.h b/ui/base/ime/chromeos/ime_engine_handler_interface.h similarity index 94% rename from ui/base/ime/ime_engine_handler_interface.h rename to ui/base/ime/chromeos/ime_engine_handler_interface.h index 4895587..cd2307b 100644 --- a/ui/base/ime/ime_engine_handler_interface.h +++ b/ui/base/ime/chromeos/ime_engine_handler_interface.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 UI_BASE_IME_IME_ENGINE_HANDLER_INTERFACE_H_ -#define UI_BASE_IME_IME_ENGINE_HANDLER_INTERFACE_H_ +#ifndef UI_BASE_IME_CHROMEOS_IME_ENGINE_HANDLER_INTERFACE_H_ +#define UI_BASE_IME_CHROMEOS_IME_ENGINE_HANDLER_INTERFACE_H_ #include <stddef.h> #include <stdint.h> @@ -34,7 +34,7 @@ #endif // defined(OS_CHROMEOS) // A interface to handle the engine handler method call. -class COMPONENT_EXPORT(UI_BASE_IME) IMEEngineHandlerInterface { +class COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) IMEEngineHandlerInterface { public: typedef base::OnceCallback<void(bool consumed)> KeyEventDoneCallback; @@ -149,4 +149,4 @@ } // namespace ui -#endif // UI_BASE_IME_IME_ENGINE_HANDLER_INTERFACE_H_ +#endif // UI_BASE_IME_CHROMEOS_IME_ENGINE_HANDLER_INTERFACE_H_
diff --git a/ui/base/ime/ime_input_context_handler_interface.h b/ui/base/ime/chromeos/ime_input_context_handler_interface.h similarity index 88% rename from ui/base/ime/ime_input_context_handler_interface.h rename to ui/base/ime/chromeos/ime_input_context_handler_interface.h index 915d08e..7acd398 100644 --- a/ui/base/ime/ime_input_context_handler_interface.h +++ b/ui/base/ime/chromeos/ime_input_context_handler_interface.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 UI_BASE_IME_IME_INPUT_CONTEXT_HANDLER_INTERFACE_H_ -#define UI_BASE_IME_IME_INPUT_CONTEXT_HANDLER_INTERFACE_H_ +#ifndef UI_BASE_IME_CHROMEOS_IME_INPUT_CONTEXT_HANDLER_INTERFACE_H_ +#define UI_BASE_IME_CHROMEOS_IME_INPUT_CONTEXT_HANDLER_INTERFACE_H_ #include <stdint.h> @@ -20,7 +20,7 @@ gfx::Range selection_range; }; -class COMPONENT_EXPORT(UI_BASE_IME) IMEInputContextHandlerInterface { +class COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) IMEInputContextHandlerInterface { public: // Called when the engine commit a text. virtual void CommitText(const std::string& text) = 0; @@ -72,4 +72,4 @@ } // namespace ui -#endif // UI_BASE_IME_IME_INPUT_CONTEXT_HANDLER_INTERFACE_H_ +#endif // UI_BASE_IME_CHROMEOS_IME_INPUT_CONTEXT_HANDLER_INTERFACE_H_
diff --git a/ui/base/ime/chromeos/input_method_chromeos.cc b/ui/base/ime/chromeos/input_method_chromeos.cc index 94fb16a..203539c 100644 --- a/ui/base/ime/chromeos/input_method_chromeos.cc +++ b/ui/base/ime/chromeos/input_method_chromeos.cc
@@ -20,10 +20,10 @@ #include "base/third_party/icu/icu_utf.h" #include "chromeos/system/devicemode.h" #include "ui/base/ime/chromeos/ime_bridge.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/chromeos/ime_keyboard.h" #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/composition_text.h" -#include "ui/base/ime/ime_engine_handler_interface.h" #include "ui/base/ime/input_method_delegate.h" #include "ui/base/ime/text_input_client.h" #include "ui/events/event.h" @@ -314,6 +314,13 @@ TextInputClient* focused) { ConfirmCompositionText(/* reset_engine */ true, /* keep_selection */ false); + // Removes any autocorrect range in the unfocused TextInputClient. + gfx::Range text_range; + if (focused_before && focused_before->GetTextRange(&text_range)) { + // This is currently only implemented in RenderWidgetHostViewAura. + focused_before->SetAutocorrectRange(base::EmptyString16(), text_range); + } + if (GetEngine()) GetEngine()->FocusOut(); } @@ -403,7 +410,9 @@ void InputMethodChromeOS::ConfirmCompositionText(bool reset_engine, bool keep_selection) { - InputMethodBase::ConfirmCompositionText(reset_engine, keep_selection); + TextInputClient* client = GetTextInputClient(); + if (client && client->HasCompositionText()) + client->ConfirmCompositionText(keep_selection); // See https://crbug.com/984472. ResetContext(reset_engine); @@ -687,6 +696,27 @@ } } +void InputMethodChromeOS::SendKeyEvent(KeyEvent* event) { + ui::EventDispatchDetails details = DispatchKeyEvent(event); + DCHECK(!details.dispatcher_destroyed); +} + +SurroundingTextInfo InputMethodChromeOS::GetSurroundingTextInfo() { + gfx::Range text_range; + SurroundingTextInfo info; + TextInputClient* client = GetTextInputClient(); + if (!client->GetTextRange(&text_range) || + !client->GetTextFromRange(text_range, &info.surrounding_text) || + !client->GetEditableSelectionRange(&info.selection_range)) { + return SurroundingTextInfo(); + } + // Makes the |selection_range| be relative to the |surrounding_text|. + info.selection_range.set_start(info.selection_range.start() - + text_range.start()); + info.selection_range.set_end(info.selection_range.end() - text_range.start()); + return info; +} + void InputMethodChromeOS::DeleteSurroundingText(int32_t offset, uint32_t length) { if (!GetTextInputClient()) @@ -806,4 +836,13 @@ return client ? client->GetFocusReason() : TextInputClient::FOCUS_REASON_NONE; } +bool InputMethodChromeOS::HasCompositionText() { + TextInputClient* client = GetTextInputClient(); + return client && client->HasCompositionText(); +} + +InputMethod* InputMethodChromeOS::GetInputMethod() { + return this; +} + } // namespace ui
diff --git a/ui/base/ime/chromeos/input_method_chromeos.h b/ui/base/ime/chromeos/input_method_chromeos.h index fed235f..34df9135 100644 --- a/ui/base/ime/chromeos/input_method_chromeos.h +++ b/ui/base/ime/chromeos/input_method_chromeos.h
@@ -17,8 +17,8 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "ui/base/ime/character_composer.h" +#include "ui/base/ime/chromeos/ime_input_context_handler_interface.h" #include "ui/base/ime/composition_text.h" -#include "ui/base/ime/ime_input_context_handler_interface.h" #include "ui/base/ime/input_method_base.h" #include "ui/base/ime/text_input_client.h" @@ -28,7 +28,8 @@ // A ui::InputMethod implementation for ChromeOS. class COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) InputMethodChromeOS - : public InputMethodBase { + : public InputMethodBase, + public IMEInputContextHandlerInterface { public: explicit InputMethodChromeOS(internal::InputMethodDelegate* delegate); ~InputMethodChromeOS() override; @@ -50,6 +51,9 @@ TextInputClient* focused) override; void OnDidChangeFocusedClient(TextInputClient* focused_before, TextInputClient* focused) override; + + // ui::IMEInputContextHandlerInterface overrides: + void CommitText(const std::string& text) override; bool SetCompositionRange( uint32_t before, uint32_t after, @@ -60,7 +64,15 @@ uint32_t start, uint32_t end) override; bool SetSelectionRange(uint32_t start, uint32_t end) override; + void UpdateCompositionText(const CompositionText& text, + uint32_t cursor_pos, + bool visible) override; + void DeleteSurroundingText(int32_t offset, uint32_t length) override; + SurroundingTextInfo GetSurroundingTextInfo() override; + void SendKeyEvent(KeyEvent* event) override; + InputMethod* GetInputMethod() override; void ConfirmCompositionText(bool reset_engine, bool keep_selection) override; + bool HasCompositionText() override; protected: // Converts |text| into CompositionText. @@ -124,13 +136,6 @@ // true if character composer comsumes key event. bool ExecuteCharacterComposer(const ui::KeyEvent& event); - // ui::IMEInputContextHandlerInterface overrides: - void CommitText(const std::string& text) override; - void UpdateCompositionText(const CompositionText& text, - uint32_t cursor_pos, - bool visible) override; - void DeleteSurroundingText(int32_t offset, uint32_t length) override; - // Hides the composition text. void HidePreeditText();
diff --git a/ui/base/ime/chromeos/input_method_chromeos_unittest.cc b/ui/base/ime/chromeos/input_method_chromeos_unittest.cc index 1db6fe9..ca67040 100644 --- a/ui/base/ime/chromeos/input_method_chromeos_unittest.cc +++ b/ui/base/ime/chromeos/input_method_chromeos_unittest.cc
@@ -19,12 +19,12 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/chromeos/ime_bridge.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h" #include "ui/base/ime/chromeos/mock_ime_engine_handler.h" #include "ui/base/ime/chromeos/mock_input_method_manager.h" #include "ui/base/ime/composition_text.h" #include "ui/base/ime/dummy_text_input_client.h" -#include "ui/base/ime/ime_engine_handler_interface.h" #include "ui/base/ime/input_method_delegate.h" #include "ui/base/ime/text_input_client.h" #include "ui/events/event.h" @@ -417,6 +417,17 @@ EXPECT_EQ(TEXT_INPUT_TYPE_PASSWORD, ime_->GetTextInputType()); } +TEST_F(InputMethodChromeOSTest, + OnWillChangeFocusedClientClearAutocorrectRange) { + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->SetFocusedTextInputClient(this); + ime_->SetAutocorrectRange(base::UTF8ToUTF16("text"), 0, 5); + EXPECT_EQ(gfx::Range(0, 5), this->GetAutocorrectRange()); + + ime_->SetFocusedTextInputClient(nullptr); + EXPECT_EQ(gfx::Range(), this->GetAutocorrectRange()); +} + // Confirm that IBusClient::FocusIn is called on "connected" if input_type_ is // TEXT. TEST_F(InputMethodChromeOSTest, FocusIn_Text) {
diff --git a/ui/base/ime/chromeos/mock_ime_engine_handler.h b/ui/base/ime/chromeos/mock_ime_engine_handler.h index 0d169fa..d84cf8b2 100644 --- a/ui/base/ime/chromeos/mock_ime_engine_handler.h +++ b/ui/base/ime/chromeos/mock_ime_engine_handler.h
@@ -10,7 +10,7 @@ #include <vector> #include "base/component_export.h" -#include "ui/base/ime/ime_engine_handler_interface.h" +#include "ui/base/ime/chromeos/ime_engine_handler_interface.h" #include "ui/events/event.h" namespace chromeos {
diff --git a/ui/base/ime/mock_ime_input_context_handler.cc b/ui/base/ime/chromeos/mock_ime_input_context_handler.cc similarity index 97% rename from ui/base/ime/mock_ime_input_context_handler.cc rename to ui/base/ime/chromeos/mock_ime_input_context_handler.cc index 570713e..d50aefdae 100644 --- a/ui/base/ime/mock_ime_input_context_handler.cc +++ b/ui/base/ime/chromeos/mock_ime_input_context_handler.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 "ui/base/ime/mock_ime_input_context_handler.h" +#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h" #include "base/logging.h" #include "base/notreached.h"
diff --git a/ui/base/ime/mock_ime_input_context_handler.h b/ui/base/ime/chromeos/mock_ime_input_context_handler.h similarity index 89% rename from ui/base/ime/mock_ime_input_context_handler.h rename to ui/base/ime/chromeos/mock_ime_input_context_handler.h index 6e24ae03..3f4b0dca 100644 --- a/ui/base/ime/mock_ime_input_context_handler.h +++ b/ui/base/ime/chromeos/mock_ime_input_context_handler.h
@@ -2,21 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_BASE_IME_MOCK_IME_INPUT_CONTEXT_HANDLER_H_ -#define UI_BASE_IME_MOCK_IME_INPUT_CONTEXT_HANDLER_H_ +#ifndef UI_BASE_IME_CHROMEOS_MOCK_IME_INPUT_CONTEXT_HANDLER_H_ +#define UI_BASE_IME_CHROMEOS_MOCK_IME_INPUT_CONTEXT_HANDLER_H_ #include <stdint.h> #include "base/component_export.h" +#include "ui/base/ime/chromeos/ime_input_context_handler_interface.h" #include "ui/base/ime/composition_text.h" -#include "ui/base/ime/ime_input_context_handler_interface.h" #include "ui/events/event.h" #include "ui/gfx/range/range.h" namespace ui { class InputMethod; -class COMPONENT_EXPORT(UI_BASE_IME) MockIMEInputContextHandler +class COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) MockIMEInputContextHandler : public IMEInputContextHandlerInterface { public: struct UpdateCompositionTextArg { @@ -99,6 +99,6 @@ UpdateCompositionTextArg last_update_composition_arg_; DeleteSurroundingTextArg last_delete_surrounding_text_arg_; }; -} // ui +} // namespace ui -#endif // UI_BASE_IME_MOCK_IME_INPUT_CONTEXT_HANDLER_H_ +#endif // UI_BASE_IME_CHROMEOS_MOCK_IME_INPUT_CONTEXT_HANDLER_H_
diff --git a/ui/base/ime/dummy_text_input_client.cc b/ui/base/ime/dummy_text_input_client.cc index a2b904d..d12d41e 100644 --- a/ui/base/ime/dummy_text_input_client.cc +++ b/ui/base/ime/dummy_text_input_client.cc
@@ -156,17 +156,23 @@ #if defined(OS_CHROMEOS) gfx::Range DummyTextInputClient::GetAutocorrectRange() const { - return gfx::Range(); + return autocorrect_range_; } gfx::Rect DummyTextInputClient::GetAutocorrectCharacterBounds() const { return gfx::Rect(); } -// TODO(crbug.com/1091088) Implement setAutocorrectRange bool DummyTextInputClient::SetAutocorrectRange( const base::string16& autocorrect_text, const gfx::Range& range) { - return false; + // Clears autocorrect range if text is empty. + // autocorrect_text content is ignored. + if (autocorrect_text.empty()) { + autocorrect_range_ = gfx::Range(); + } else { + autocorrect_range_ = range; + } + return true; } #endif
diff --git a/ui/base/ime/dummy_text_input_client.h b/ui/base/ime/dummy_text_input_client.h index a902d66..52bce9a 100644 --- a/ui/base/ime/dummy_text_input_client.h +++ b/ui/base/ime/dummy_text_input_client.h
@@ -102,6 +102,7 @@ std::vector<base::string16> insert_text_history_; std::vector<CompositionText> composition_history_; std::vector<gfx::Range> selection_history_; + gfx::Range autocorrect_range_; }; } // namespace ui
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc index e4ef7410..eac9131 100644 --- a/ui/base/ime/input_method_base.cc +++ b/ui/base/ime/input_method_base.cc
@@ -203,99 +203,4 @@ return evt.stopped_propagation(); } -void InputMethodBase::CommitText(const std::string& text) { - if (text.empty() || !GetTextInputClient() || IsTextInputTypeNone()) - return; - - const base::string16 utf16_text = base::UTF8ToUTF16(text); - if (utf16_text.empty()) - return; - - if (!SendFakeProcessKeyEvent(true)) - GetTextInputClient()->InsertText(utf16_text); - SendFakeProcessKeyEvent(false); -} - -void InputMethodBase::UpdateCompositionText(const CompositionText& composition_, - uint32_t cursor_pos, - bool visible) { - if (IsTextInputTypeNone()) - return; - - if (!SendFakeProcessKeyEvent(true)) { - if (visible && !composition_.text.empty()) - GetTextInputClient()->SetCompositionText(composition_); - else - GetTextInputClient()->ClearCompositionText(); - } - SendFakeProcessKeyEvent(false); -} - -#if defined(OS_CHROMEOS) -bool InputMethodBase::SetCompositionRange( - uint32_t before, - uint32_t after, - const std::vector<ui::ImeTextSpan>& text_spans) { - return false; -} - -gfx::Range InputMethodBase::GetAutocorrectRange() { - return gfx::Range(); -} - -gfx::Rect InputMethodBase::GetAutocorrectCharacterBounds() { - return gfx::Rect(); -} - -bool InputMethodBase::SetAutocorrectRange( - const base::string16& autocorrect_text, - uint32_t start, - uint32_t end) { - return false; -} - -bool InputMethodBase::SetSelectionRange(uint32_t start, uint32_t end) { - return false; -} -#endif - -void InputMethodBase::DeleteSurroundingText(int32_t offset, uint32_t length) {} - -SurroundingTextInfo InputMethodBase::GetSurroundingTextInfo() { - gfx::Range text_range; - SurroundingTextInfo info; - TextInputClient* client = GetTextInputClient(); - if (!client->GetTextRange(&text_range) || - !client->GetTextFromRange(text_range, &info.surrounding_text) || - !client->GetEditableSelectionRange(&info.selection_range)) { - return SurroundingTextInfo(); - } - // Makes the |selection_range| be relative to the |surrounding_text|. - info.selection_range.set_start(info.selection_range.start() - - text_range.start()); - info.selection_range.set_end(info.selection_range.end() - text_range.start()); - return info; -} - -void InputMethodBase::SendKeyEvent(KeyEvent* event) { - ui::EventDispatchDetails details = DispatchKeyEvent(event); - DCHECK(!details.dispatcher_destroyed); -} - -InputMethod* InputMethodBase::GetInputMethod() { - return this; -} - -void InputMethodBase::ConfirmCompositionText(bool reset_engine, - bool keep_selection) { - TextInputClient* client = GetTextInputClient(); - if (client && client->HasCompositionText()) - client->ConfirmCompositionText(keep_selection); -} - -bool InputMethodBase::HasCompositionText() { - TextInputClient* client = GetTextInputClient(); - return client && client->HasCompositionText(); -} - } // namespace ui
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h index 45b91a5b..70edaa1 100644 --- a/ui/base/ime/input_method_base.h +++ b/ui/base/ime/input_method_base.h
@@ -14,7 +14,7 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "build/build_config.h" -#include "ui/base/ime/ime_input_context_handler_interface.h" +#include "ui/base/ime/composition_text.h" #include "ui/base/ime/input_method.h" #include "ui/events/event_dispatcher.h" @@ -33,8 +33,7 @@ // implementations. class COMPONENT_EXPORT(UI_BASE_IME) InputMethodBase : public InputMethod, - public base::SupportsWeakPtr<InputMethodBase>, - public IMEInputContextHandlerInterface { + public base::SupportsWeakPtr<InputMethodBase> { public: ~InputMethodBase() override; @@ -81,32 +80,6 @@ virtual void OnDidChangeFocusedClient(TextInputClient* focused_before, TextInputClient* focused) {} - // IMEInputContextHandlerInterface: - void CommitText(const std::string& text) override; - void UpdateCompositionText(const CompositionText& text, - uint32_t cursor_pos, - bool visible) override; - -#if defined(OS_CHROMEOS) - bool SetCompositionRange( - uint32_t before, - uint32_t after, - const std::vector<ui::ImeTextSpan>& text_spans) override; - gfx::Range GetAutocorrectRange() override; - gfx::Rect GetAutocorrectCharacterBounds() override; - bool SetAutocorrectRange(const base::string16& autocorrect_text, - uint32_t start, - uint32_t end) override; - bool SetSelectionRange(uint32_t start, uint32_t end) override; -#endif - - void DeleteSurroundingText(int32_t offset, uint32_t length) override; - SurroundingTextInfo GetSurroundingTextInfo() override; - void SendKeyEvent(KeyEvent* event) override; - InputMethod* GetInputMethod() override; - void ConfirmCompositionText(bool reset_engine, bool keep_selection) override; - bool HasCompositionText() override; - // Sends a fake key event for IME composing without physical key events. // Returns true if the faked key event is stopped propagation. bool SendFakeProcessKeyEvent(bool pressed) const;
diff --git a/ui/base/ime/linux/input_method_auralinux.cc b/ui/base/ime/linux/input_method_auralinux.cc index de49a5b..10549686 100644 --- a/ui/base/ime/linux/input_method_auralinux.cc +++ b/ui/base/ime/linux/input_method_auralinux.cc
@@ -356,7 +356,7 @@ void InputMethodAuraLinux::OnWillChangeFocusedClient( TextInputClient* focused_before, TextInputClient* focused) { - ConfirmCompositionText(/* reset_engine */ true, /* keep_selection */ false); + ConfirmCompositionText(); } void InputMethodAuraLinux::OnDidChangeFocusedClient( @@ -393,12 +393,7 @@ return details; } -void InputMethodAuraLinux::ConfirmCompositionText(bool reset_engine, - bool keep_selection) { - if (keep_selection) { - NOTIMPLEMENTED_LOG_ONCE(); - } - InputMethodBase::ConfirmCompositionText(reset_engine, keep_selection); +void InputMethodAuraLinux::ConfirmCompositionText() { ResetContext(); }
diff --git a/ui/base/ime/linux/input_method_auralinux.h b/ui/base/ime/linux/input_method_auralinux.h index e560171..52c1cc61 100644 --- a/ui/base/ime/linux/input_method_auralinux.h +++ b/ui/base/ime/linux/input_method_auralinux.h
@@ -47,9 +47,9 @@ TextInputClient* focused) override; void OnDidChangeFocusedClient(TextInputClient* focused_before, TextInputClient* focused) override; - void ConfirmCompositionText(bool reset_engine, bool keep_selection) override; private: + void ConfirmCompositionText(); bool HasInputMethodResult(); bool NeedInsertChar() const; ui::EventDispatchDetails SendFakeProcessKeyEvent(ui::KeyEvent* event) const
diff --git a/ui/base/ime/text_input_client.h b/ui/base/ime/text_input_client.h index 74ffa6f..57d977b 100644 --- a/ui/base/ime/text_input_client.h +++ b/ui/base/ime/text_input_client.h
@@ -242,7 +242,8 @@ virtual gfx::Rect GetAutocorrectCharacterBounds() const = 0; // Set the autocorrect range and return if it has been set correctly as a - // boolean value. + // boolean value. If text or range is empty, existing autocorrect range is + // cleared. Out of range results in failure and no modification will be made. virtual bool SetAutocorrectRange(const base::string16& autocorrect_text, const gfx::Range& range) = 0; #endif
diff --git a/ui/base/ime/win/input_method_win_imm32.cc b/ui/base/ime/win/input_method_win_imm32.cc index 324a6bc9..20defba 100644 --- a/ui/base/ime/win/input_method_win_imm32.cc +++ b/ui/base/ime/win/input_method_win_imm32.cc
@@ -151,8 +151,7 @@ TextInputClient* focused_before, TextInputClient* focused) { if (IsWindowFocused(focused_before)) - ConfirmCompositionText(/* reset_engine */ true, - /* keep_selection */ false); + ConfirmCompositionText(); } void InputMethodWinImm32::OnDidChangeFocusedClient( @@ -315,10 +314,7 @@ } } -void InputMethodWinImm32::ConfirmCompositionText(bool reset_engine, - bool keep_selection) { - InputMethodBase::ConfirmCompositionText(reset_engine, keep_selection); - +void InputMethodWinImm32::ConfirmCompositionText() { // Makes sure the native IME app can be informed about the composition is // cleared, so that it can clean up its internal states. if (composing_window_handle_)
diff --git a/ui/base/ime/win/input_method_win_imm32.h b/ui/base/ime/win/input_method_win_imm32.h index c95a8ae7..b9ec2f5 100644 --- a/ui/base/ime/win/input_method_win_imm32.h +++ b/ui/base/ime/win/input_method_win_imm32.h
@@ -27,7 +27,6 @@ // Overridden from InputMethodBase: void OnFocus() override; - void ConfirmCompositionText(bool reset_engine, bool keep_selection) override; // Overridden from InputMethod: bool OnUntranslatedIMEMessage(const MSG event, @@ -79,6 +78,8 @@ // Enables or disables the IME according to the current text input type. void UpdateIMEState(); + void ConfirmCompositionText(); + // Windows IMM32 wrapper. // (See "ui/base/ime/win/ime_input.h" for its details.) ui::IMM32Manager imm32_manager_;
diff --git a/ui/base/ime/win/input_method_win_tsf.cc b/ui/base/ime/win/input_method_win_tsf.cc index b4e4fcc..aca6422 100644 --- a/ui/base/ime/win/input_method_win_tsf.cc +++ b/ui/base/ime/win/input_method_win_tsf.cc
@@ -143,8 +143,7 @@ TextInputClient* focused_before, TextInputClient* focused) { if (IsWindowFocused(focused_before)) { - ConfirmCompositionText(/* reset_engine */ true, - /* keep_selection */ false); + ConfirmCompositionText(); ui::TSFBridge::GetInstance()->RemoveFocusedClient(focused_before); } } @@ -168,13 +167,7 @@ InputMethodWinBase::OnDidChangeFocusedClient(focused_before, focused); } -void InputMethodWinTSF::ConfirmCompositionText(bool reset_engine, - bool keep_selection) { - // TODO(b/134473433) Modify this function so that when keep_selection is - // true, the selection is not changed when text committed - if (keep_selection) { - NOTIMPLEMENTED_LOG_ONCE(); - } +void InputMethodWinTSF::ConfirmCompositionText() { if (IsTextInputTypeNone()) return;
diff --git a/ui/base/ime/win/input_method_win_tsf.h b/ui/base/ime/win/input_method_win_tsf.h index 58e0cfe..34d9616ab 100644 --- a/ui/base/ime/win/input_method_win_tsf.h +++ b/ui/base/ime/win/input_method_win_tsf.h
@@ -41,11 +41,11 @@ TextInputClient* focused) override; void OnDidChangeFocusedClient(TextInputClient* focused_before, TextInputClient* focused) override; - void ConfirmCompositionText(bool reset_engine, bool keep_selection) override; - void ShowVirtualKeyboardIfEnabled() override; private: + void ConfirmCompositionText(); + class TSFEventObserver; // TSF event router and observer.
diff --git a/ui/base/ime/win/tsf_bridge.cc b/ui/base/ime/win/tsf_bridge.cc index 5e222550..14f653e 100644 --- a/ui/base/ime/win/tsf_bridge.cc +++ b/ui/base/ime/win/tsf_bridge.cc
@@ -31,7 +31,7 @@ TSFBridgeImpl(); ~TSFBridgeImpl() override; - bool Initialize(); + HRESULT Initialize(); // TsfBridge: void OnTextInputTypeChanged(const TextInputClient* client) override; @@ -48,24 +48,24 @@ void SetInputPanelPolicy(bool input_panel_policy_manual) override; private: - // Returns true if |tsf_document_map_| is successfully initialized. This + // Returns S_OK if |tsf_document_map_| is successfully initialized. This // method should be called from and only from Initialize(). - bool InitializeDocumentMapInternal(); + HRESULT InitializeDocumentMapInternal(); - // Returns true if |context| is successfully updated to be a disabled + // Returns S_OK if |context| is successfully updated to be a disabled // context, where an IME should be deactivated. This is suitable for some // special input context such as password fields. - bool InitializeDisabledContext(ITfContext* context); + HRESULT InitializeDisabledContext(ITfContext* context); - // Returns true if a TSF document manager and a TSF context is successfully + // Returns S_OK if a TSF document manager and a TSF context is successfully // created with associating with given |text_store|. The returned // |source_cookie| indicates the binding between |text_store| and |context|. // You can pass nullptr to |text_store| and |source_cookie| when text store is // not necessary. - bool CreateDocumentManager(TSFTextStore* text_store, - ITfDocumentMgr** document_manager, - ITfContext** context, - DWORD* source_cookie); + HRESULT CreateDocumentManager(TSFTextStore* text_store, + ITfDocumentMgr** document_manager, + ITfContext** context, + DWORD* source_cookie); // Returns true if |document_manager| is the focused document manager. bool IsFocused(ITfDocumentMgr* document_manager); @@ -178,61 +178,66 @@ client_id_ = TF_CLIENTID_NULL; } -bool TSFBridgeImpl::Initialize() { +HRESULT TSFBridgeImpl::Initialize() { DCHECK(base::CurrentUIThread::IsSet()); if (client_id_ != TF_CLIENTID_NULL) { DVLOG(1) << "Already initialized."; - return false; + return S_FALSE; } - if (FAILED(::CoCreateInstance(CLSID_TF_InputProcessorProfiles, nullptr, - CLSCTX_ALL, - IID_PPV_ARGS(&input_processor_profiles_)))) { + HRESULT hr = + ::CoCreateInstance(CLSID_TF_InputProcessorProfiles, nullptr, CLSCTX_ALL, + IID_PPV_ARGS(&input_processor_profiles_)); + if (FAILED(hr)) { DVLOG(1) << "Failed to create InputProcessorProfiles instance."; - return false; + return hr; } - if (FAILED(::CoCreateInstance(CLSID_TF_ThreadMgr, nullptr, CLSCTX_ALL, - IID_PPV_ARGS(&thread_manager_)))) { + hr = ::CoCreateInstance(CLSID_TF_ThreadMgr, nullptr, CLSCTX_ALL, + IID_PPV_ARGS(&thread_manager_)); + if (FAILED(hr)) { DVLOG(1) << "Failed to create ThreadManager instance."; - return false; + return hr; } - if (FAILED(thread_manager_->Activate(&client_id_))) { + hr = thread_manager_->Activate(&client_id_); + if (FAILED(hr)) { DVLOG(1) << "Failed to activate Thread Manager."; - return false; + return hr; } - if (!InitializeDocumentMapInternal()) - return false; + hr = InitializeDocumentMapInternal(); + if (FAILED(hr)) + return hr; // Japanese IME expects the default value of this compartment is // TF_SENTENCEMODE_PHRASEPREDICT like IMM32 implementation. This value is // managed per thread, so that it is enough to set this value at once. This // value does not affect other language's IME behaviors. Microsoft::WRL::ComPtr<ITfCompartmentMgr> thread_compartment_manager; - if (FAILED(thread_manager_.As(&thread_compartment_manager))) { + hr = thread_manager_.As(&thread_compartment_manager); + if (FAILED(hr)) { DVLOG(1) << "Failed to get ITfCompartmentMgr."; - return false; + return hr; } Microsoft::WRL::ComPtr<ITfCompartment> sentence_compartment; - if (FAILED(thread_compartment_manager->GetCompartment( - GUID_COMPARTMENT_KEYBOARD_INPUTMODE_SENTENCE, - &sentence_compartment))) { + hr = thread_compartment_manager->GetCompartment( + GUID_COMPARTMENT_KEYBOARD_INPUTMODE_SENTENCE, &sentence_compartment); + if (FAILED(hr)) { DVLOG(1) << "Failed to get sentence compartment."; - return false; + return hr; } base::win::ScopedVariant sentence_variant; sentence_variant.Set(TF_SENTENCEMODE_PHRASEPREDICT); - if (FAILED( - sentence_compartment->SetValue(client_id_, sentence_variant.ptr()))) { + hr = sentence_compartment->SetValue(client_id_, sentence_variant.ptr()); + if (FAILED(hr)) { DVLOG(1) << "Failed to change the sentence mode."; - return false; + return hr; } - return true; + return S_OK; } void TSFBridgeImpl::OnTextInputTypeChanged(const TextInputClient* client) { @@ -386,83 +391,89 @@ return thread_manager_; } -bool TSFBridgeImpl::CreateDocumentManager(TSFTextStore* text_store, - ITfDocumentMgr** document_manager, - ITfContext** context, - DWORD* source_cookie) { - if (FAILED(thread_manager_->CreateDocumentMgr(document_manager))) { +HRESULT TSFBridgeImpl::CreateDocumentManager(TSFTextStore* text_store, + ITfDocumentMgr** document_manager, + ITfContext** context, + DWORD* source_cookie) { + HRESULT hr = thread_manager_->CreateDocumentMgr(document_manager); + if (FAILED(hr)) { DVLOG(1) << "Failed to create Document Manager."; - return false; + return hr; } if (!text_store || !source_cookie) - return true; + return S_OK; DWORD edit_cookie = TF_INVALID_EDIT_COOKIE; - if (FAILED((*document_manager) - ->CreateContext(client_id_, 0, - static_cast<ITextStoreACP*>(text_store), - context, &edit_cookie))) { + hr = (*document_manager) + ->CreateContext(client_id_, 0, + static_cast<ITextStoreACP*>(text_store), context, + &edit_cookie); + if (FAILED(hr)) { DVLOG(1) << "Failed to create Context."; - return false; + return hr; } - if (FAILED((*document_manager)->Push(*context))) { + hr = (*document_manager)->Push(*context); + if (FAILED(hr)) { DVLOG(1) << "Failed to push context."; - return false; + return hr; } Microsoft::WRL::ComPtr<ITfSource> source; - if (FAILED((*context)->QueryInterface(IID_PPV_ARGS(&source)))) { + hr = (*context)->QueryInterface(IID_PPV_ARGS(&source)); + if (FAILED(hr)) { DVLOG(1) << "Failed to get source."; - return false; + return hr; } - if (FAILED(source->AdviseSink(IID_ITfTextEditSink, - static_cast<ITfTextEditSink*>(text_store), - source_cookie))) { + hr = source->AdviseSink(IID_ITfTextEditSink, + static_cast<ITfTextEditSink*>(text_store), + source_cookie); + if (FAILED(hr)) { DVLOG(1) << "AdviseSink failed."; - return false; + return hr; } Microsoft::WRL::ComPtr<ITfSource> source_ITfThreadMgr; - if (FAILED(thread_manager_->QueryInterface( - IID_PPV_ARGS(&source_ITfThreadMgr)))) { + hr = thread_manager_->QueryInterface(IID_PPV_ARGS(&source_ITfThreadMgr)); + if (FAILED(hr)) { DVLOG(1) << "Failed to get source_ITfThreadMgr."; - return false; + return hr; } - if (FAILED(source_ITfThreadMgr->AdviseSink( - IID_ITfKeyTraceEventSink, - static_cast<ITfKeyTraceEventSink*>(text_store), - &key_trace_sink_cookie_))) { + hr = source_ITfThreadMgr->AdviseSink( + IID_ITfKeyTraceEventSink, static_cast<ITfKeyTraceEventSink*>(text_store), + &key_trace_sink_cookie_); + if (FAILED(hr)) { DVLOG(1) << "AdviseSink for ITfKeyTraceEventSink failed."; - return false; + return hr; } Microsoft::WRL::ComPtr<ITfSource> language_source; - if (FAILED(input_processor_profiles_->QueryInterface( - IID_PPV_ARGS(&language_source)))) { + hr = + input_processor_profiles_->QueryInterface(IID_PPV_ARGS(&language_source)); + if (FAILED(hr)) { DVLOG(1) << "Failed to get source_ITfInputProcessorProfiles."; - return false; + return hr; } - if (FAILED( - language_source->AdviseSink(IID_ITfLanguageProfileNotifySink, - static_cast<ITfTextEditSink*>(text_store), - &language_profile_cookie_))) { + hr = language_source->AdviseSink(IID_ITfLanguageProfileNotifySink, + static_cast<ITfTextEditSink*>(text_store), + &language_profile_cookie_); + if (FAILED(hr)) { DVLOG(1) << "AdviseSink for language profile notify sink failed."; - return false; + return hr; } if (*source_cookie == TF_INVALID_COOKIE) { DVLOG(1) << "The result of cookie is invalid."; - return false; + return E_FAIL; } - return true; + return S_OK; } -bool TSFBridgeImpl::InitializeDocumentMapInternal() { +HRESULT TSFBridgeImpl::InitializeDocumentMapInternal() { const TextInputType kTextInputTypes[] = { TEXT_INPUT_TYPE_NONE, TEXT_INPUT_TYPE_TEXT, TEXT_INPUT_TYPE_PASSWORD, TEXT_INPUT_TYPE_SEARCH, @@ -478,57 +489,70 @@ DWORD* cookie_ptr = use_null_text_store ? nullptr : &cookie; scoped_refptr<TSFTextStore> text_store = use_null_text_store ? nullptr : new TSFTextStore(); - if (!CreateDocumentManager(text_store.get(), &document_manager, &context, - cookie_ptr)) - return false; - if ((input_type == TEXT_INPUT_TYPE_PASSWORD) && - !InitializeDisabledContext(context.Get())) - return false; + HRESULT hr = S_OK; + if (text_store) { + HRESULT hr = text_store->Initialize(); + if (FAILED(hr)) + return hr; + } + hr = CreateDocumentManager(text_store.get(), &document_manager, &context, + cookie_ptr); + if (FAILED(hr)) + return hr; + if (input_type == TEXT_INPUT_TYPE_PASSWORD) { + hr = InitializeDisabledContext(context.Get()); + if (FAILED(hr)) + return hr; + } tsf_document_map_[input_type].text_store = text_store; tsf_document_map_[input_type].document_manager = document_manager; tsf_document_map_[input_type].cookie = cookie; if (text_store) text_store->OnContextInitialized(context.Get()); } - return true; + return S_OK; } -bool TSFBridgeImpl::InitializeDisabledContext(ITfContext* context) { +HRESULT TSFBridgeImpl::InitializeDisabledContext(ITfContext* context) { Microsoft::WRL::ComPtr<ITfCompartmentMgr> compartment_mgr; - if (FAILED(context->QueryInterface(IID_PPV_ARGS(&compartment_mgr)))) { + HRESULT hr = context->QueryInterface(IID_PPV_ARGS(&compartment_mgr)); + if (FAILED(hr)) { DVLOG(1) << "Failed to get CompartmentMgr."; - return false; + return hr; } Microsoft::WRL::ComPtr<ITfCompartment> disabled_compartment; - if (FAILED(compartment_mgr->GetCompartment(GUID_COMPARTMENT_KEYBOARD_DISABLED, - &disabled_compartment))) { + hr = compartment_mgr->GetCompartment(GUID_COMPARTMENT_KEYBOARD_DISABLED, + &disabled_compartment); + if (FAILED(hr)) { DVLOG(1) << "Failed to get keyboard disabled compartment."; - return false; + return hr; } base::win::ScopedVariant variant; variant.Set(1); - if (FAILED(disabled_compartment->SetValue(client_id_, variant.ptr()))) { + hr = disabled_compartment->SetValue(client_id_, variant.ptr()); + if (FAILED(hr)) { DVLOG(1) << "Failed to disable the DocumentMgr."; - return false; + return hr; } Microsoft::WRL::ComPtr<ITfCompartment> empty_context; - if (FAILED(compartment_mgr->GetCompartment(GUID_COMPARTMENT_EMPTYCONTEXT, - &empty_context))) { + hr = compartment_mgr->GetCompartment(GUID_COMPARTMENT_EMPTYCONTEXT, + &empty_context); + if (FAILED(hr)) { DVLOG(1) << "Failed to get empty context compartment."; - return false; + return hr; } base::win::ScopedVariant empty_context_variant; empty_context_variant.Set(static_cast<int32_t>(1)); - if (FAILED( - empty_context->SetValue(client_id_, empty_context_variant.ptr()))) { + hr = empty_context->SetValue(client_id_, empty_context_variant.ptr()); + if (FAILED(hr)) { DVLOG(1) << "Failed to set empty context."; - return false; + return hr; } - return true; + return S_OK; } bool TSFBridgeImpl::IsFocused(ITfDocumentMgr* document_manager) { @@ -617,20 +641,20 @@ TSFBridge::~TSFBridge() {} // static -void TSFBridge::Initialize() { +HRESULT TSFBridge::Initialize() { if (!base::CurrentUIThread::IsSet()) { DVLOG(1) << "Do not use TSFBridge without UI thread."; - return; + return E_FAIL; } TSFBridgeImpl* delegate = static_cast<TSFBridgeImpl*>(TSFBridgeTLS().Get()); if (delegate) - return; + return S_OK; // If we aren't supporting TSF early out. if (!base::FeatureList::IsEnabled(features::kTSFImeSupport)) - return; + return E_FAIL; delegate = new TSFBridgeImpl(); TSFBridgeTLS().Set(delegate); - delegate->Initialize(); + return delegate->Initialize(); } // static
diff --git a/ui/base/ime/win/tsf_bridge.h b/ui/base/ime/win/tsf_bridge.h index e9a30587..14c8715 100644 --- a/ui/base/ime/win/tsf_bridge.h +++ b/ui/base/ime/win/tsf_bridge.h
@@ -36,7 +36,7 @@ // Sets the thread local instance. Must be called before any calls to // GetInstance(). - static void Initialize(); + static HRESULT Initialize(); // Injects an alternative TSFBridge such as MockTSFBridge for testing. The // injected object should be released by the caller. This function returns
diff --git a/ui/base/ime/win/tsf_input_policy_unittest.cc b/ui/base/ime/win/tsf_input_policy_unittest.cc index 4636e17..0b4a3f9 100644 --- a/ui/base/ime/win/tsf_input_policy_unittest.cc +++ b/ui/base/ime/win/tsf_input_policy_unittest.cc
@@ -187,6 +187,7 @@ protected: void SetUp() override { text_store_ = new TSFTextStore(); + EXPECT_EQ(S_OK, text_store_->Initialize()); sink_ = new MockStoreACPSink(); EXPECT_EQ(S_OK, text_store_->AdviseSink(IID_ITextStoreACPSink, sink_.get(), TS_AS_ALL_SINKS)); @@ -216,7 +217,9 @@ protected: void SetUp() override { text_store1_ = new TSFTextStore(); + EXPECT_EQ(S_OK, text_store1_->Initialize()); text_store2_ = new TSFTextStore(); + EXPECT_EQ(S_OK, text_store2_->Initialize()); sink1_ = new MockStoreACPSink(); sink2_ = new MockStoreACPSink(); EXPECT_EQ(S_OK, text_store1_->AdviseSink(IID_ITextStoreACPSink,
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc index acc2d7d..838bb47 100644 --- a/ui/base/ime/win/tsf_text_store.cc +++ b/ui/base/ime/win/tsf_text_store.cc
@@ -47,22 +47,28 @@ } // namespace -TSFTextStore::TSFTextStore() { - if (FAILED(::CoCreateInstance(CLSID_TF_CategoryMgr, nullptr, CLSCTX_ALL, - IID_PPV_ARGS(&category_manager_)))) { - LOG(FATAL) << "Failed to initialize CategoryMgr."; - return; - } - if (FAILED(::CoCreateInstance(CLSID_TF_DisplayAttributeMgr, nullptr, - CLSCTX_ALL, - IID_PPV_ARGS(&display_attribute_manager_)))) { - LOG(FATAL) << "Failed to initialize DisplayAttributeMgr."; - return; - } -} +TSFTextStore::TSFTextStore() {} TSFTextStore::~TSFTextStore() {} +HRESULT TSFTextStore::Initialize() { + HRESULT hr = ::CoCreateInstance(CLSID_TF_CategoryMgr, nullptr, CLSCTX_ALL, + IID_PPV_ARGS(&category_manager_)); + if (FAILED(hr)) { + DVLOG(1) << "Failed to initialize CategoryMgr."; + return hr; + } + + hr = ::CoCreateInstance(CLSID_TF_DisplayAttributeMgr, nullptr, CLSCTX_ALL, + IID_PPV_ARGS(&display_attribute_manager_)); + if (FAILED(hr)) { + DVLOG(1) << "Failed to initialize DisplayAttributeMgr."; + return hr; + } + + return S_OK; +} + ULONG STDMETHODCALLTYPE TSFTextStore::AddRef() { return InterlockedIncrement(&ref_count_); }
diff --git a/ui/base/ime/win/tsf_text_store.h b/ui/base/ime/win/tsf_text_store.h index f24db7fb..70455c7 100644 --- a/ui/base/ime/win/tsf_text_store.h +++ b/ui/base/ime/win/tsf_text_store.h
@@ -108,6 +108,7 @@ public: TSFTextStore(); virtual ~TSFTextStore(); + HRESULT Initialize(); // ITextStoreACP: IFACEMETHODIMP_(ULONG) AddRef() override;
diff --git a/ui/base/ime/win/tsf_text_store_unittest.cc b/ui/base/ime/win/tsf_text_store_unittest.cc index a4733d3..25db5d4 100644 --- a/ui/base/ime/win/tsf_text_store_unittest.cc +++ b/ui/base/ime/win/tsf_text_store_unittest.cc
@@ -140,6 +140,7 @@ protected: void SetUp() override { text_store_ = new TSFTextStore(); + EXPECT_EQ(S_OK, text_store_->Initialize()); sink_ = new MockStoreACPSink(); EXPECT_EQ(S_OK, text_store_->AdviseSink(IID_ITextStoreACPSink, sink_.get(), TS_AS_ALL_SINKS));
diff --git a/ui/base/models/dialog_model.cc b/ui/base/models/dialog_model.cc index 6f86f39b..b1e61aa3 100644 --- a/ui/base/models/dialog_model.cc +++ b/ui/base/models/dialog_model.cc
@@ -29,18 +29,6 @@ return *this; } -DialogModel::Builder& DialogModel::Builder::SetAcceptCallback( - base::OnceClosure callback) { - model_->accept_callback_ = std::move(callback); - return *this; -} - -DialogModel::Builder& DialogModel::Builder::SetCancelCallback( - base::OnceClosure callback) { - model_->cancel_callback_ = std::move(callback); - return *this; -} - DialogModel::Builder& DialogModel::Builder::SetCloseCallback( base::OnceClosure callback) { model_->close_callback_ = std::move(callback); @@ -53,11 +41,25 @@ return *this; } -DialogModel::Builder& DialogModel::Builder::AddDialogButton( - DialogButton button, +DialogModel::Builder& DialogModel::Builder::AddOkButton( + base::OnceClosure callback, base::string16 label, const DialogModelButton::Params& params) { - model_->AddDialogButton(button, std::move(label), params); + DCHECK(!params.has_callback()) << "Use |callback| only."; + DCHECK(!model_->accept_callback_); + model_->accept_callback_ = std::move(callback); + model_->AddDialogButton(ui::DIALOG_BUTTON_OK, std::move(label), params); + return *this; +} + +DialogModel::Builder& DialogModel::Builder::AddCancelButton( + base::OnceClosure callback, + base::string16 label, + const DialogModelButton::Params& params) { + DCHECK(!params.has_callback()) << "Use |callback| only."; + DCHECK(!model_->cancel_callback_); + model_->cancel_callback_ = std::move(callback); + model_->AddDialogButton(ui::DIALOG_BUTTON_CANCEL, std::move(label), params); return *this; }
diff --git a/ui/base/models/dialog_model.h b/ui/base/models/dialog_model.h index 2cc4217d..85721956 100644 --- a/ui/base/models/dialog_model.h +++ b/ui/base/models/dialog_model.h
@@ -64,14 +64,11 @@ // auto dialog_model = // ui::DialogModel::Builder(std::move(model_delegate)) // .SetTitle(base::ASCIIToUTF16("Hello, world!")) -// .AddDialogButton(ui::DIALOG_BUTTON_OK, -// l10n_util::GetStringUTF16(IDS_OK)) +// .AddOkButton(base::BindOnce(&Delegate::OnDialogAccepted, +// base::Unretained(model_delegate_ptr))) // .AddTextfield( // base::ASCIIToUTF16("Name"), base::string16(), // ui::DialogModelTextfield::Params().SetUniqueId(kNameTextfield)) -// .SetAcceptCallback( -// base::BindOnce(&Delegate::OnDialogAccepted, -// base::Unretained(model_delegate_ptr))) // .Build(); // // // DialogModelBase::Host specific. In this example, uses views-specific @@ -96,12 +93,8 @@ Builder& SetShowCloseButton(bool show_close_button); Builder& SetTitle(base::string16 title); - // Called when the dialog is accepted, before it closes. - Builder& SetAcceptCallback(base::OnceClosure callback); - // Called when the dialog is cancelled. - Builder& SetCancelCallback(base::OnceClosure callback); - // Called when the dialog is explicitly closed (for instance, close-x). Not - // called during accept/cancel. + // Called when the dialog is explicitly closed (Esc, close-x). Not called + // during accept/cancel. Builder& SetCloseCallback(base::OnceClosure callback); // TODO(pbos): Clarify and enforce (through tests) that this is called after @@ -110,12 +103,19 @@ // {accept,cancel,close} callbacks. Builder& SetWindowClosingCallback(base::OnceClosure callback); - // Adds a dialog button (ok, cancel) to the dialog. Note that the callbacks - // for these button actions should be set using SetAcceptCallback() and - // SetCancelCallback(). - Builder& AddDialogButton( - DialogButton button, - base::string16 label, + // Adds a dialog button (ok, cancel) to the dialog. The |callback| is called + // when the dialog is accepted or cancelled, before it closes. Use + // base::DoNothing() as callback if you want nothing extra to happen as a + // result, besides the dialog closing. + // If no |label| is provided, default strings are chosen by the + // DialogModelHost implementation. + Builder& AddOkButton( + base::OnceClosure callback, + base::string16 label = base::string16(), + const DialogModelButton::Params& params = DialogModelButton::Params()); + Builder& AddCancelButton( + base::OnceClosure callback, + base::string16 label = base::string16(), const DialogModelButton::Params& params = DialogModelButton::Params()); // Use of the extra button in new dialogs are discouraged. If this is deemed
diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc index 22fbdcd..384150d 100644 --- a/ui/base/ui_base_switches.cc +++ b/ui/base/ui_base_switches.cc
@@ -31,9 +31,6 @@ // Disables use of DWM composition for top level windows. const char kDisableDwmComposition[] = "disable-dwm-composition"; -// Disables touch adjustment. -const char kDisableTouchAdjustment[] = "disable-touch-adjustment"; - // Disables touch event based drag and drop. const char kDisableTouchDragDrop[] = "disable-touch-drag-drop";
diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h index 6232033b..07ce187 100644 --- a/ui/base/ui_base_switches.h +++ b/ui/base/ui_base_switches.h
@@ -22,7 +22,6 @@ COMPONENT_EXPORT(UI_BASE) extern const char kDisableCompositedAntialiasing[]; COMPONENT_EXPORT(UI_BASE) extern const char kDisableDwmComposition[]; -COMPONENT_EXPORT(UI_BASE) extern const char kDisableTouchAdjustment[]; COMPONENT_EXPORT(UI_BASE) extern const char kDisableTouchDragDrop[]; COMPONENT_EXPORT(UI_BASE) extern const char kEnableTouchDragDrop[]; COMPONENT_EXPORT(UI_BASE) extern const char kForceCaptionStyle[];
diff --git a/ui/base/x/selection_utils.cc b/ui/base/x/selection_utils.cc index 34533b9..72e02bc 100644 --- a/ui/base/x/selection_utils.cc +++ b/ui/base/x/selection_utils.cc
@@ -19,19 +19,13 @@ namespace ui { -const char kString[] = "STRING"; -const char kText[] = "TEXT"; -const char kTextPlain[] = "text/plain"; -const char kTextPlainUtf8[] = "text/plain;charset=utf-8"; -const char kUtf8String[] = "UTF8_STRING"; - std::vector<x11::Atom> GetTextAtomsFrom() { std::vector<x11::Atom> atoms; - atoms.push_back(gfx::GetAtom(kUtf8String)); - atoms.push_back(gfx::GetAtom(kString)); - atoms.push_back(gfx::GetAtom(kText)); - atoms.push_back(gfx::GetAtom(kTextPlain)); - atoms.push_back(gfx::GetAtom(kTextPlainUtf8)); + atoms.push_back(gfx::GetAtom(kMimeTypeLinuxUtf8String)); + atoms.push_back(gfx::GetAtom(kMimeTypeLinuxString)); + atoms.push_back(gfx::GetAtom(kMimeTypeLinuxText)); + atoms.push_back(gfx::GetAtom(kMimeTypeText)); + atoms.push_back(gfx::GetAtom(kMimeTypeTextUtf8)); return atoms; } @@ -176,11 +170,12 @@ } std::string SelectionData::GetText() const { - if (type_ == gfx::GetAtom(kUtf8String) || type_ == gfx::GetAtom(kText) || - type_ == gfx::GetAtom(kTextPlainUtf8)) { + if (type_ == gfx::GetAtom(kMimeTypeLinuxUtf8String) || + type_ == gfx::GetAtom(kMimeTypeLinuxText) || + type_ == gfx::GetAtom(kMimeTypeTextUtf8)) { return RefCountedMemoryToString(memory_); - } else if (type_ == gfx::GetAtom(kString) || - type_ == gfx::GetAtom(kTextPlain)) { + } else if (type_ == gfx::GetAtom(kMimeTypeLinuxString) || + type_ == gfx::GetAtom(kMimeTypeText)) { std::string result; base::ConvertToUtf8AndNormalize(RefCountedMemoryToString(memory_), base::kCodepageLatin1, &result);
diff --git a/ui/base/x/selection_utils.h b/ui/base/x/selection_utils.h index 9ca25b3..3e90ed3f 100644 --- a/ui/base/x/selection_utils.h +++ b/ui/base/x/selection_utils.h
@@ -15,10 +15,6 @@ namespace ui { class SelectionData; -COMPONENT_EXPORT(UI_BASE_X) extern const char kString[]; -COMPONENT_EXPORT(UI_BASE_X) extern const char kText[]; -COMPONENT_EXPORT(UI_BASE_X) extern const char kUtf8String[]; - // Returns a list of all text atoms that we handle. COMPONENT_EXPORT(UI_BASE_X) std::vector<x11::Atom> GetTextAtomsFrom();
diff --git a/ui/base/x/x11_os_exchange_data_provider.cc b/ui/base/x/x11_os_exchange_data_provider.cc index e7a374f..ef6463f 100644 --- a/ui/base/x/x11_os_exchange_data_provider.cc +++ b/ui/base/x/x11_os_exchange_data_provider.cc
@@ -97,9 +97,9 @@ base::RefCountedString::TakeString(&utf8)); format_map_.Insert(gfx::GetAtom(kMimeTypeText), mem); - format_map_.Insert(gfx::GetAtom(kText), mem); - format_map_.Insert(gfx::GetAtom(kString), mem); - format_map_.Insert(gfx::GetAtom(kUtf8String), mem); + format_map_.Insert(gfx::GetAtom(kMimeTypeLinuxText), mem); + format_map_.Insert(gfx::GetAtom(kMimeTypeLinuxString), mem); + format_map_.Insert(gfx::GetAtom(kMimeTypeLinuxUtf8String), mem); } void XOSExchangeDataProvider::SetURL(const GURL& url,
diff --git a/ui/chromeos/colors/cros_colors.json5 b/ui/chromeos/colors/cros_colors.json5 index 760d3627..44171f27 100644 --- a/ui/chromeos/colors/cros_colors.json5 +++ b/ui/chromeos/colors/cros_colors.json5
@@ -26,6 +26,18 @@ light: "$google_grey_700", dark: "$google_grey_500", }, + text_color_alert: { + light: "$google_red_600", + dark: "$google_red_300", + }, + text_color_warning: { + light: "$google_yellow_600", + dark: "$google_yellow_300", + }, + text_color_positive: { + light: "$google_green_600", + dark: "$google_green_300", + }, bg_color: { light: "#ffffff", @@ -36,7 +48,18 @@ light: "$google_grey_700", dark: "$google_grey_200", }, - + icon_color_alert: { + light: "$google_red_600", + dark: "$google_red_300", + }, + icon_color_warning: { + light: "$google_yellow_600", + dark: "$google_yellow_300", + }, + icon_color_positive: { + light: "$google_green_600", + dark: "$google_green_300", + }, icon_color_prominent: { light: "$google_blue_600", dark: "$google_blue_300", @@ -73,8 +96,7 @@ link_color: "$google_blue_700", /* button-primary */ - button_background_color_primary: - "$icon_color_prominent", + button_background_color_primary: "$icon_color_prominent", button_label_color_primary: { light: "$google_grey_200", dark: "$google_grey_900", @@ -97,8 +119,7 @@ }, /* button-secondary */ - button_label_color_secondary: - "$icon_color_prominent", + button_label_color_secondary: "$icon_color_prominent", button_stroke_color_secondary: { light: "$google_grey_300", dark: "$google_grey_700",
diff --git a/ui/chromeos/translations/ui_chromeos_strings_af.xtb b/ui/chromeos/translations/ui_chromeos_strings_af.xtb index 027011a..98507b0 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_af.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_af.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">'n Lêer met die naam "<ph name="FILENAME" />" bestaan reeds. Wat wil jy doen?</translation> <translation id="2121825465123208577">Verander grootte</translation> <translation id="2136953289241069843">Transliterasie (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Kan nie "<ph name="PATH" />" oopmaak nie: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Ongeldige karakter: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Viëtnamese sleutelbord (TCVN)</translation> <translation id="2168214441502403371">Persiese sleutelbord</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_am.xtb b/ui/chromeos/translations/ui_chromeos_strings_am.xtb index 6269f85..dadbba1 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_am.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_am.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">«<ph name="FILENAME" />» የሚባል ፋይል አስቀድሞ አለ። ምን ማድረግ ይፈልጋሉ?</translation> <translation id="2121825465123208577">መጠን ቀይር</translation> <translation id="2136953289241069843">በቋንቋ ፊደል መጻፍ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">«<ph name="PATH" />»ን መክፈት አልተቻለም፦ <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">ልክ ያልሆነ ቁምፊ፦ <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">የቪዬትናምኛ ቁልፍ ሰሌዳ (ቲሲቪኤን)</translation> <translation id="2168214441502403371">የፋርስ ቁልፍ ሰሌዳ</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ar.xtb b/ui/chromeos/translations/ui_chromeos_strings_ar.xtb index 8dd9d86..f3e53fd9 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ar.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ar.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">هناك ملف بالاسم "<ph name="FILENAME" />" موجود فعلاً. ما الإجراء الذي تريد تنفيذه؟</translation> <translation id="2121825465123208577">تغيير الحجم</translation> <translation id="2136953289241069843">التحويل الصوتي (ناماستي ← नमस्कार)</translation> -<translation id="2138867954865495510">يتعذَّر فتح "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">حرف غير صالح: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">لوحة المفاتيح الفيتنامية (TCVN)</translation> <translation id="2168214441502403371">لوحة المفاتيح الفارسية</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_as.xtb b/ui/chromeos/translations/ui_chromeos_strings_as.xtb index 940e021..fa92578 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_as.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_as.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" নামৰ এটা ফাইল ইতিমধ্যে আছেই। আপুনি কি কৰিব বিচাৰে?</translation> <translation id="2121825465123208577">আকাৰ সলনি কৰক</translation> <translation id="2136953289241069843">লিপ্যন্তৰণ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" খুলিবলৈ সক্ষম নহ’ল: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">অমান্য বৰ্ণ: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">ভিয়েটনামীজ কীব’ৰ্ড (TCVN)</translation> <translation id="2168214441502403371">পার্চীয়ান কীব’র্ড</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_az.xtb b/ui/chromeos/translations/ui_chromeos_strings_az.xtb index 3433d43..5bd5e86 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_az.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_az.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" adlı fayl artıq mövcuddur. Nə etmək istəyirsiniz?</translation> <translation id="2121825465123208577">Ölçüsünü dəyişin</translation> <translation id="2136953289241069843">Transliterasiya (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" faylını açmaq alınmadı: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Yanlış simvol: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vyetnam klaviaturası (TCVN)</translation> <translation id="2168214441502403371">Fars klaviaturası</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_be.xtb b/ui/chromeos/translations/ui_chromeos_strings_be.xtb index 527e106..410a602 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_be.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_be.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Файл пад назвай "<ph name="FILENAME" />" ужо існуе. Што трэба зрабіць?</translation> <translation id="2121825465123208577">Змяніць памер</translation> <translation id="2136953289241069843">Транслітарацыя (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Не ўдалося адкрыць "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Недапушчальны сімвал: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">В'етнамская клавіятура (TCVN)</translation> <translation id="2168214441502403371">Персідская раскладка</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_bg.xtb b/ui/chromeos/translations/ui_chromeos_strings_bg.xtb index 9a544b1..d345b07 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_bg.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_bg.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Вече съществува файл с име „<ph name="FILENAME" />“. Какво искате да направите?</translation> <translation id="2121825465123208577">Преоразмеряване</translation> <translation id="2136953289241069843">Транслитерация (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">„<ph name="PATH" />“ не може да се отвори: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Невалиден знак: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Виетнамска клавиатура (TCVN)</translation> <translation id="2168214441502403371">Персийска клавиатура</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_bn.xtb b/ui/chromeos/translations/ui_chromeos_strings_bn.xtb index bce6b4a..8418a1e 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_bn.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_bn.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" নামের একটি ফাইল ইতিমধ্যেই বিদ্যমান৷ আপনি কী করতে চান?</translation> <translation id="2121825465123208577">ছোট বড় করুন</translation> <translation id="2136953289241069843">লিপ্যন্তরকরণ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" খোলা যাচ্ছে না: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">ভুল অক্ষর: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">ভিয়েতনামি কীবোর্ড (TCVN)</translation> <translation id="2168214441502403371">ফার্সি কীবোর্ড</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_bs.xtb b/ui/chromeos/translations/ui_chromeos_strings_bs.xtb index 281f2bdf..4aec9f2 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_bs.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_bs.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Već postoji fajl naziva "<ph name="FILENAME" />". Šta želite uraditi?</translation> <translation id="2121825465123208577">Promijeni veličinu</translation> <translation id="2136953289241069843">Transliterirani tekst (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Nije moguće otvoriti "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Nevažeći znak: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vijetnamska tastatura (TCVN)</translation> <translation id="2168214441502403371">Perzijska tastatura</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ca.xtb b/ui/chromeos/translations/ui_chromeos_strings_ca.xtb index b304207..d9b4879 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ca.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ca.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">El nom de fitxer "<ph name="FILENAME" />" ja existeix. Què voleu fer?</translation> <translation id="2121825465123208577">Canvia la mida</translation> <translation id="2136953289241069843">Transliteració (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">No es pot obrir "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Caràcter no vàlid: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Teclat vietnamita (TCVN)</translation> <translation id="2168214441502403371">Teclat persa</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_cs.xtb b/ui/chromeos/translations/ui_chromeos_strings_cs.xtb index 65e2ddc..14cc999 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_cs.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_cs.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Soubor s názvem <ph name="FILENAME" /> již existuje. Co chcete udělat?</translation> <translation id="2121825465123208577">Změnit velikost</translation> <translation id="2136953289241069843">Přepis (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Soubor „<ph name="PATH" />“ nelze otevřít: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Neplatný znak: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamská klávesnice (TCVN)</translation> <translation id="2168214441502403371">Perská klávesnice</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_da.xtb b/ui/chromeos/translations/ui_chromeos_strings_da.xtb index 76aa048b..03cd382 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_da.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_da.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Der findes allerede en fil med navnet "<ph name="FILENAME" />". Hvad vil du foretage dig?</translation> <translation id="2121825465123208577">Tilpas størrelse</translation> <translation id="2136953289241069843">Translitteration (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" kan ikke åbnes: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Ugyldigt tegn: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamesisk tastatur (TCVN)</translation> <translation id="2168214441502403371">Persisk tastatur</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_de.xtb b/ui/chromeos/translations/ui_chromeos_strings_de.xtb index a1ef7727..ee7a68e 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_de.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_de.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Eine Datei mit dem Namen "<ph name="FILENAME" />" existiert bereits. Was möchten Sie tun?</translation> <translation id="2121825465123208577">Größe anpassen</translation> <translation id="2136953289241069843">Transliteration (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" kann nicht geöffnet werden: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Ungültiges Zeichen: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamesische Tastatur (TCVN)</translation> <translation id="2168214441502403371">Persische Tastatur</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_el.xtb b/ui/chromeos/translations/ui_chromeos_strings_el.xtb index ec9d77a9..4448aea 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_el.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_el.xtb
@@ -109,7 +109,6 @@ <translation id="2085470240340828803">Υπάρχει ήδη αρχείο με το όνομα "<ph name="FILENAME" />". Τι θέλετε να γίνει;</translation> <translation id="2121825465123208577">Προσαρμογή μεγέθους</translation> <translation id="2136953289241069843">Μεταγραφή (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Δεν είναι δυνατό το άνοιγμα της διαδομής "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Μη έγκυρος χαρακτήρας: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Πληκτρολόγιο Βιετναμικών (TCVN)</translation> <translation id="2168214441502403371">Πληκτρολόγιο Περσικών</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_en-GB.xtb b/ui/chromeos/translations/ui_chromeos_strings_en-GB.xtb index 1ee1c336..5df6460 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_en-GB.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_en-GB.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">A file named "<ph name="FILENAME" />" already exists. What do you want to do?</translation> <translation id="2121825465123208577">Re-size</translation> <translation id="2136953289241069843">Transliteration (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Unable to open '<ph name="PATH" />': <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Invalid character: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamese keyboard (TCVN)</translation> <translation id="2168214441502403371">Persian keyboard</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_es-419.xtb b/ui/chromeos/translations/ui_chromeos_strings_es-419.xtb index e4a68fae..cff3a9d 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_es-419.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_es-419.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Ya existe un archivo llamado "<ph name="FILENAME" />". ¿Qué acción quieres realizar?</translation> <translation id="2121825465123208577">Ajustar tamaño</translation> <translation id="2136953289241069843">Transliteración (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">No se puede abrir "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Carácter no válido: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Teclado vietnamita (TCVN)</translation> <translation id="2168214441502403371">Teclado persa</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_es.xtb b/ui/chromeos/translations/ui_chromeos_strings_es.xtb index 01cabc5..de3502d 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_es.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_es.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Ya existe un archivo "<ph name="FILENAME" />". ¿Qué quieres hacer?</translation> <translation id="2121825465123208577">Modificar tamaño</translation> <translation id="2136953289241069843">Transliteración (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">No se puede abrir "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Carácter no válido: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Teclado vietnamita (TCVN)</translation> <translation id="2168214441502403371">Teclado persa</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_et.xtb b/ui/chromeos/translations/ui_chromeos_strings_et.xtb index 4e816123..f1a1967 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_et.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_et.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Fail nimega „<ph name="FILENAME" />” on juba olemas. Mida te teha soovite?</translation> <translation id="2121825465123208577">Muuda suurust</translation> <translation id="2136953289241069843">Transliteratsioon (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Teed „<ph name="PATH" />” ei saanud avada: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Sobimatu tähemärk: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnami klaviatuur (TCVN)</translation> <translation id="2168214441502403371">Pärsia klaviatuur</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_eu.xtb b/ui/chromeos/translations/ui_chromeos_strings_eu.xtb index f50053a..5be49426 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_eu.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_eu.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Badago "<ph name="FILENAME" />" izeneko fitxategi bat. Zer egin nahi duzu?</translation> <translation id="2121825465123208577">Aldatu tamaina</translation> <translation id="2136953289241069843">Transliterazioa (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Ezin da ireki "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Karaktere honek ez du balio: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Teklatu vietnamdarra (TCVN)</translation> <translation id="2168214441502403371">Teklatu persiarra</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_fa.xtb b/ui/chromeos/translations/ui_chromeos_strings_fa.xtb index b708449..8796a8a 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_fa.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_fa.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">فایلی با نام «<ph name="FILENAME" />» از قبل وجود دارد. میخواهید چه کاری انجام دهید؟</translation> <translation id="2121825465123208577">تغییر اندازه</translation> <translation id="2136953289241069843">نویسهگردانی (namaste ← नमस्कार)</translation> -<translation id="2138867954865495510">«<ph name="PATH" />» باز نشد: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">نویسه نامعتبر: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">صفحهکلید ویتنامی (TCVN)</translation> <translation id="2168214441502403371">صفحهکلید فارسی</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_fi.xtb b/ui/chromeos/translations/ui_chromeos_strings_fi.xtb index 7f09a72..c256fb8 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_fi.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_fi.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Tiedosto <ph name="FILENAME" /> on jo olemassa. Mitä haluat tehdä?</translation> <translation id="2121825465123208577">Muuta kokoa</translation> <translation id="2136953289241069843">Translitterointi (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Kohteen <ph name="PATH" /> avaaminen epäonnistui: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Virheellinen merkki: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamilainen näppäimistö (TCVN)</translation> <translation id="2168214441502403371">Persialainen näppäimistö</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_fil.xtb b/ui/chromeos/translations/ui_chromeos_strings_fil.xtb index 47d04a3..3a1675fc7 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_fil.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_fil.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Umiiral na ang isang file na may pangalang "<ph name="FILENAME" />". Ano ang gusto mong gawin?</translation> <translation id="2121825465123208577">Baguhin ang laki</translation> <translation id="2136953289241069843">Transliteration (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Hindi mabuksan ang "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Invalid na character: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamese keyboard (TCVN)</translation> <translation id="2168214441502403371">Persian keyboard</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_fr-CA.xtb b/ui/chromeos/translations/ui_chromeos_strings_fr-CA.xtb index da75369c..0adeac5 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_fr-CA.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_fr-CA.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Un fichier nommé « <ph name="FILENAME" /> » existe déjà. Que voulez-vous faire?</translation> <translation id="2121825465123208577">Redimensionner</translation> <translation id="2136953289241069843">Translittération (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Impossible d'ouvrir « <ph name="PATH" /> » : <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Caractère incorrect : <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Clavier vietnamien (TCVN)</translation> <translation id="2168214441502403371">Clavier perse</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_fr.xtb b/ui/chromeos/translations/ui_chromeos_strings_fr.xtb index 7f38a7a..991558f 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_fr.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_fr.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Le fichier "<ph name="FILENAME" />" existe déjà. Que voulez-vous faire ?</translation> <translation id="2121825465123208577">Redimensionner</translation> <translation id="2136953289241069843">Translittération (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Impossible d'ouvrir "<ph name="PATH" />" : <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Caractère non valide : <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Clavier vietnamien (TCVN)</translation> <translation id="2168214441502403371">Clavier persan</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_gl.xtb b/ui/chromeos/translations/ui_chromeos_strings_gl.xtb index cfcd4b8..fc2530b 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_gl.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_gl.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Xa existe un ficheiro denominado "<ph name="FILENAME" />". Que queres facer?</translation> <translation id="2121825465123208577">Cambiar tamaño</translation> <translation id="2136953289241069843">Transliteración (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Non se puido abrir "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Carácter non válido: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Teclado vietnamita (TCVN)</translation> <translation id="2168214441502403371">Teclado persa</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_gu.xtb b/ui/chromeos/translations/ui_chromeos_strings_gu.xtb index 67b01d9..1e8d3ef 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_gu.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_gu.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" નામની ફાઇલ પહેલાંથી અસ્તિત્વમાં છે. તમે શું કરવા માંગો છો?</translation> <translation id="2121825465123208577">આકાર બદલો</translation> <translation id="2136953289241069843">લિવ્યંતરણ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />"ને ખોલવામાં અસમર્થ: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">અમાન્ય અક્ષર: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">વિયેતનામીસ કીબોર્ડ (TCVN)</translation> <translation id="2168214441502403371">ફારસી કીબોર્ડ</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_hi.xtb b/ui/chromeos/translations/ui_chromeos_strings_hi.xtb index 4a46b2f..757aaf6 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_hi.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_hi.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" नाम की फ़ाइल पहले से मौजूद है. आप क्या करना चाहते हैं?</translation> <translation id="2121825465123208577">आकार बदलें</translation> <translation id="2136953289241069843">लिप्यंतरण (namaste → नमस्ते)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" : <ph name="ERROR_MESSAGE" /> नहीं खोला जा सकता</translation> <translation id="2163152940313951844">अमान्य वर्ण : <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">वियतनामी कीबोर्ड (TCVN)</translation> <translation id="2168214441502403371">पारसी कीबोर्ड</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_hr.xtb b/ui/chromeos/translations/ui_chromeos_strings_hr.xtb index 3696842..505101a 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_hr.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_hr.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Datoteka pod nazivom "<ph name="FILENAME" />" već postoji. Što želite napraviti?</translation> <translation id="2121825465123208577">Promijeni veličinu</translation> <translation id="2136953289241069843">transliteracija (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Nije moguće otvoriti "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Nevažeći znak: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">vijetnamska tipkovnica (TCVN)</translation> <translation id="2168214441502403371">perzijska tipkovnica</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_hu.xtb b/ui/chromeos/translations/ui_chromeos_strings_hu.xtb index 791d689..aab67a8 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_hu.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_hu.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Már létezik „<ph name="FILENAME" />” nevű fájl. Mit szeretne tenni?</translation> <translation id="2121825465123208577">Átméretezés</translation> <translation id="2136953289241069843">Átírás (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">„<ph name="PATH" />” megnyitása sikertelen: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Érvénytelen karakter: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnami billentyűzet (TCVN)</translation> <translation id="2168214441502403371">Perzsa billentyűzet</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_hy.xtb b/ui/chromeos/translations/ui_chromeos_strings_hy.xtb index 7d075f7..7a426688 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_hy.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_hy.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">«<ph name="FILENAME" />» անունով ֆայլ արդեն առկա է: Ի՞նչ եք ցանկանում անել:</translation> <translation id="2121825465123208577">Չափափոխել</translation> <translation id="2136953289241069843">Տառադարձություն (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Չհաջողվեց բացել «<ph name="PATH" />» ֆայլը։ <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Անվավեր գրանշան՝ <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Վիետնամերենի ստեղնաշար (TCVN)</translation> <translation id="2168214441502403371">Պարսկերենի ստեղնաշար</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_id.xtb b/ui/chromeos/translations/ui_chromeos_strings_id.xtb index 4ec6741..9721bdeb 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_id.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_id.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">File bernama "<ph name="FILENAME" />" sudah ada. Apa yang ingin Anda lakukan?</translation> <translation id="2121825465123208577">Ubah ukuran</translation> <translation id="2136953289241069843">Transliterasi (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Tidak dapat membuka "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Karakter tidak valid: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Keyboard Vietnam (TCVN)</translation> <translation id="2168214441502403371">Keyboard Persia</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_is.xtb b/ui/chromeos/translations/ui_chromeos_strings_is.xtb index 5bf5a7b..5c054f8 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_is.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_is.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Skrá með heitið „<ph name="FILENAME" />“ er þegar fyrir hendi. Hvað viltu gera?</translation> <translation id="2121825465123208577">Breyta stærð</translation> <translation id="2136953289241069843">Umritun (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Ekki tókst að opna „<ph name="PATH" />“: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Ógildur stafur: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Víetnamskt lyklaborð (TCVN)</translation> <translation id="2168214441502403371">Persneskt lyklaborð</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_it.xtb b/ui/chromeos/translations/ui_chromeos_strings_it.xtb index 4ead1786..7f74a47 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_it.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_it.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Esiste già un file denominato "<ph name="FILENAME" />". Che cosa vuoi fare?</translation> <translation id="2121825465123208577">Ridimensiona</translation> <translation id="2136953289241069843">Traslitterazione (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Impossibile aprire "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Carattere non valido: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Tastiera Vietnamita (TCVN)</translation> <translation id="2168214441502403371">Tastiera Persiano</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_iw.xtb b/ui/chromeos/translations/ui_chromeos_strings_iw.xtb index 6f40e92..fff92426 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_iw.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_iw.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">כבר קיים קובץ בשם "<ph name="FILENAME" />". מה ברצונך לעשות?</translation> <translation id="2121825465123208577">שנה גודל</translation> <translation id="2136953289241069843">תעתוק (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">לא ניתן לפתוח את "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">תו לא חוקי: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">מקלדת וייטנאמית (TCVN)</translation> <translation id="2168214441502403371">מקלדת פרסית</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ja.xtb b/ui/chromeos/translations/ui_chromeos_strings_ja.xtb index 50b4eb3..3789335d 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ja.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ja.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">「<ph name="FILENAME" />」という名前のファイルは既に存在します。どのように処理しますか?</translation> <translation id="2121825465123208577">サイズを変更</translation> <translation id="2136953289241069843">文字変換(namaste → नमस्कार)</translation> -<translation id="2138867954865495510">「<ph name="PATH" />」を開くことができません: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">「<ph name="CHARACTER_NAME" />」は無効な文字です。</translation> <translation id="2164862903024139959">ベトナム語キーボード(TCVN) </translation> <translation id="2168214441502403371">ペルシャ語キーボード</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ka.xtb b/ui/chromeos/translations/ui_chromeos_strings_ka.xtb index 884a00c..dcc7b10 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ka.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ka.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">ფაილი სახელად „<ph name="FILENAME" />“ უკვე არსებობს. რისი გაკეთება გსურთ?</translation> <translation id="2121825465123208577">ზომის შეცვლა</translation> <translation id="2136953289241069843">ტრანსლიტერაცია (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">„<ph name="PATH" />“ ვერ გაიხსნა: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">არასწორი სიმბოლო: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">ვიეტნამური კლავიატურა (TCVN)</translation> <translation id="2168214441502403371">სპარსული კლავიატურა</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_kk.xtb b/ui/chromeos/translations/ui_chromeos_strings_kk.xtb index d9cbb81..722e9ab 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_kk.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_kk.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" атты файл бұрыннан бар. Не істегіңіз келеді?</translation> <translation id="2121825465123208577">Өлшемін өзгерту</translation> <translation id="2136953289241069843">Транслитерация (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" ашылмады: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Жарамсыз таңба: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Вьетнам пернетақтасы (TCVN)</translation> <translation id="2168214441502403371">Парсы пернетақтасы</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_km.xtb b/ui/chromeos/translations/ui_chromeos_strings_km.xtb index c49cdce6..5ea3201 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_km.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_km.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">ឯកសារដែលមានឈ្មោះ "<ph name="FILENAME" />" មានរួចទៅហើយ។ តើអ្នកចង់ធ្វើដូចម្តេច?</translation> <translation id="2121825465123208577">ប្ដូរទំហំ</translation> <translation id="2136953289241069843">ការសរសេរតាមសូរស័ព្ទ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">មិនអាចបើក "<ph name="PATH" />"៖ <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">តួអក្សរមិនត្រឹមត្រូវ៖ <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">ក្តារចុចវៀតណាម (TCVN)</translation> <translation id="2168214441502403371">ក្តារចុចពែក</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_kn.xtb b/ui/chromeos/translations/ui_chromeos_strings_kn.xtb index 34305c08..17089f5 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_kn.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_kn.xtb
@@ -103,7 +103,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" ಹೆಸರಿನ ಫೈಲ್ ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ. ನೀವು ಏನು ಮಾಡಬೇಕೆಂದು ಬಯಸುವಿರಿ?</translation> <translation id="2121825465123208577">ಮರುಗಾತ್ರ</translation> <translation id="2136953289241069843">ಲಿಪ್ಯಂತರಣ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" ತೆರೆಯಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">ಅಮಾನ್ಯ ಅಕ್ಷರ: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">ವಿಯೆಟ್ನಾಮೀಸ್ ಕೀಬೋರ್ಡ್ (TCVN)</translation> <translation id="2168214441502403371">ಪರ್ಷಿಯನ್ ಕೀಬೋರ್ಡ್</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ko.xtb b/ui/chromeos/translations/ui_chromeos_strings_ko.xtb index 5a28aec..28b542b 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ko.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ko.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">이름이 '<ph name="FILENAME" />'인 파일이 이미 존재합니다. 원하는 작업을 선택하세요.</translation> <translation id="2121825465123208577">크기 조정</translation> <translation id="2136953289241069843">음역(namaste → नमस्कार)</translation> -<translation id="2138867954865495510">'<ph name="PATH" />'을(를) 열 수 없음. <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">잘못된 문자: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">베트남어 키보드(TCVN)</translation> <translation id="2168214441502403371">페르시아어 키보드</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ky.xtb b/ui/chromeos/translations/ui_chromeos_strings_ky.xtb index 933e8d15..a5e3a1d8 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ky.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ky.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" деген файл мурунтан эле бар. Эмне кыласыз?</translation> <translation id="2121825465123208577">Өлчөмүн өзгөртүү</translation> <translation id="2136953289241069843">Транслитерация (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" ачылган жок: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Жараксыз символ: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Вьетнамча баскычтоп (TCVN)</translation> <translation id="2168214441502403371">Персче баскычтоп</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_lo.xtb b/ui/chromeos/translations/ui_chromeos_strings_lo.xtb index 52ec102..48906369 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_lo.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_lo.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">ມີໄຟລ໌ຊື່ "<ph name="FILENAME" />" ຢູ່ຮຽບຮ້ອຍແລ້ວ. ທ່ານຕ້ອງການເຮັດອັນໃດ?</translation> <translation id="2121825465123208577">ປ່ຽນຂະໜາດ</translation> <translation id="2136953289241069843">ການປ່ຽນຖ່າຍຕົວອັກສອນ (namaste →ນາມາສເຕະ)</translation> -<translation id="2138867954865495510">ບໍ່ສາມາດເປີດ "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">ຕົວອັກສອນໃຊ້ບໍ່ໄດ້: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">ຄີບອດພາສາຫວຽດນາມ (TCVN)</translation> <translation id="2168214441502403371">ຄີບອດພາສາເປີເຊຍ</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_lt.xtb b/ui/chromeos/translations/ui_chromeos_strings_lt.xtb index 224cdd4..7e12323f 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_lt.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_lt.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Failas pavadinimu „<ph name="FILENAME" />“ jau yra. Ką norite daryti?</translation> <translation id="2121825465123208577">Keisti dydį</translation> <translation id="2136953289241069843">Transliteracija (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Nepavyko atidaryti „<ph name="PATH" />“: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Netinkamas simbolis: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamietiška klaviatūra (TCVN)</translation> <translation id="2168214441502403371">Persiška klaviatūra</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_lv.xtb b/ui/chromeos/translations/ui_chromeos_strings_lv.xtb index 7acfc7d..16ff8709 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_lv.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_lv.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Fails ar nosaukumu “<ph name="FILENAME" />” jau pastāv. Kā vēlaties rīkoties?</translation> <translation id="2121825465123208577">Mainīt lielumu</translation> <translation id="2136953289241069843">Transliterācija (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Nevar atvērt “<ph name="PATH" />”: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Nederīga rakstzīme: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vjetnamiešu valodas tastatūra (TCVN)</translation> <translation id="2168214441502403371">Persiešu valodas tastatūra</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_mk.xtb b/ui/chromeos/translations/ui_chromeos_strings_mk.xtb index 72660ab..976e712 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_mk.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_mk.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Датотека со име „<ph name="FILENAME" />“ веќе постои. Што сакате да направите?</translation> <translation id="2121825465123208577">Промени големина</translation> <translation id="2136953289241069843">Транслитерација (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Не може да се отвори „<ph name="PATH" />“: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Неважечки знак: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">виетнамска тастатура (TCVN)</translation> <translation id="2168214441502403371">персиска тастатура</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ml.xtb b/ui/chromeos/translations/ui_chromeos_strings_ml.xtb index cce9e637..0a5f9746 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ml.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ml.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" എന്ന പേരിൽ ഒരു ഫയൽ ഇതിനകം നിലവിലുണ്ട്. നിങ്ങൾ എന്തുചെയ്യാൻ പോകുന്നു?</translation> <translation id="2121825465123208577">വലുപ്പംമാറ്റുക</translation> <translation id="2136953289241069843">ലിപ്യന്തരണം (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" തുറക്കാനായില്ല: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">അസാധുവായ പ്രതീകം: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">വിയറ്റ്നാമീസ് കീബോർഡ് (TCVN)</translation> <translation id="2168214441502403371">പേർഷ്യൻ കീബോർഡ്</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_mn.xtb b/ui/chromeos/translations/ui_chromeos_strings_mn.xtb index 50190ade..286c66c 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_mn.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_mn.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" файл нь аль хэдийн байна. Та юу хийхийг хүсэж байна вэ?</translation> <translation id="2121825465123208577">Хэмжээг өөрчлөх</translation> <translation id="2136953289241069843">Хөрвүүлэлт (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />"-г нээх боломжгүй байна: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Хүчингүй тэмдэгт: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Вьетнам хэлний гар (TCVN)</translation> <translation id="2168214441502403371">Перс хэлний гар</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_mr.xtb b/ui/chromeos/translations/ui_chromeos_strings_mr.xtb index 92126a6f..b277b20 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_mr.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_mr.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" नावाची फाईल आधीपासूनच विद्यमान आहे. तुम्ही काय करू इच्छिता?</translation> <translation id="2121825465123208577">आकार बदला</translation> <translation id="2136953289241069843">लिप्यंतरण (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" उघडू शकत नाही: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">चुकीचा वर्ण: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">व्हिएतनामी कीबोर्ड (TCVN)</translation> <translation id="2168214441502403371">पर्शियन कीबोर्ड</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ms.xtb b/ui/chromeos/translations/ui_chromeos_strings_ms.xtb index 954520cd..a4cbe78 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ms.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ms.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Fail bernama "<ph name="FILENAME" />" sudah ada. Apa yang anda mahu lakukan?</translation> <translation id="2121825465123208577">Ubah saiz</translation> <translation id="2136953289241069843">Pengalihan huruf (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Tidak dapat membuka "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Aksara tidak sah: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Papan kekunci bahasa Vietnam (TCVN)</translation> <translation id="2168214441502403371">Papan kekunci bahasa Parsi</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_my.xtb b/ui/chromeos/translations/ui_chromeos_strings_my.xtb index 2e68260c..c0fa2f20 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_my.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_my.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">ဖိုင် အမည် "<ph name="FILENAME" />" ရှိနှင့်နေပြီ။ သင် ဘယ်လို လုပ်စေချင်ပါသလဲ?</translation> <translation id="2121825465123208577">အရွယ်အစားပြောင်းရန်</translation> <translation id="2136953289241069843">အက္ခရာဖလှယ်မှု (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" ကို ဖွင့်၍မရပါ- <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">အက္ခရာ မမှန်ကန်ပါ- <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">ဗီယက်နမ် ကီးဘုတ် (TCVN)</translation> <translation id="2168214441502403371">ပါရှား ကီးဘုတ်</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ne.xtb b/ui/chromeos/translations/ui_chromeos_strings_ne.xtb index f859055c..96da23e 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ne.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ne.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" नाम गरेको फाइल पहिले नै विद्यमान छ। तपाईं के गर्न चाहनुहुन्छ?</translation> <translation id="2121825465123208577">पुनःआकार मिलाउनुहोस्</translation> <translation id="2136953289241069843">ट्रान्सलिटेरेशन (नमस्ते → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" खोल्न सकिएन: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">अमान्य वर्ण: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">भियतनामी किबोर्ड (TCVN)</translation> <translation id="2168214441502403371">फारसी किबोर्ड</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_nl.xtb b/ui/chromeos/translations/ui_chromeos_strings_nl.xtb index 038a961..d2cd298 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_nl.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_nl.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Er bestaat al een bestand met de naam '<ph name="FILENAME" />'. Wat wil je doen?</translation> <translation id="2121825465123208577">Formaat aanpassen</translation> <translation id="2136953289241069843">Transliteratie (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Kan '<ph name="PATH" />' niet openen: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Ongeldig teken: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamees toetsenbord (TCVN)</translation> <translation id="2168214441502403371">Perzisch toetsenbord</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_no.xtb b/ui/chromeos/translations/ui_chromeos_strings_no.xtb index ae8d3d7..41adcd9 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_no.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_no.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Det finnes allerede en fil med navnet «<ph name="FILENAME" />». Hva ønsker du å gjøre?</translation> <translation id="2121825465123208577">Endre størrelse</translation> <translation id="2136953289241069843">Translitterasjon (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Kan ikke åpne «<ph name="PATH" />»: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Ugyldig tegn: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamesisk tastatur (TCVN)</translation> <translation id="2168214441502403371">Persisk tastatur</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_or.xtb b/ui/chromeos/translations/ui_chromeos_strings_or.xtb index e071f8c1..b7095ed 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_or.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_or.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" ନାମକ ଗୋଟିଏ ଫାଇଲ୍ ପୂର୍ବରୁ ବିଦ୍ୟମାନ ଅଛି। ଆପଣ କ’ଣ କରିବାକୁ ଚାହାନ୍ତି?</translation> <translation id="2121825465123208577">ଆକାର ବଦଳାନ୍ତୁ</translation> <translation id="2136953289241069843">ଟ୍ରାନ୍ସଲିଟ୍ରେସନ୍ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />": <ph name="ERROR_MESSAGE" /> ଖୋଲିବାକୁ ଅକ୍ଷମ</translation> <translation id="2163152940313951844">ଅବୈଧ ବର୍ଣ୍ଣ: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">ଭିଏତ୍ନାମିଜ୍ କୀବୋର୍ଡ (TCVN)</translation> <translation id="2168214441502403371">ପରସୀଆନ୍ କୀ'ବୋର୍ଡ</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_pa.xtb b/ui/chromeos/translations/ui_chromeos_strings_pa.xtb index 2ac8688..91730ef 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_pa.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_pa.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" ਨਾਮਕ ਫਾਈਲ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। ਤੁਸੀਂ ਕੀ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?</translation> <translation id="2121825465123208577">ਆਕਾਰ ਬਦਲੋ</translation> <translation id="2136953289241069843">ਲਿਪਾਂਤਰਨ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" ਨੂੰ ਖੋਲ੍ਹਣ ਦੇ ਅਯੋਗ: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">ਅਵੈਧ ਅੱਖਰ-ਚਿੰਨ੍ਹ: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">ਵੀਅਤਨਾਮੀ ਕੀ-ਬੋਰਡ (TCVN)</translation> <translation id="2168214441502403371">ਫ਼ਾਰਸੀ ਕੀ-ਬੋਰਡ</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_pl.xtb b/ui/chromeos/translations/ui_chromeos_strings_pl.xtb index ef94745..d401fa4 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_pl.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_pl.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Plik o nazwie „<ph name="FILENAME" />” już istnieje. Co chcesz zrobić?</translation> <translation id="2121825465123208577">Zmień rozmiar</translation> <translation id="2136953289241069843">Transliteracja (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Nie można otworzyć „<ph name="PATH" />”: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Nieprawidłowy znak: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Klawiatura wietnamska (TCVN)</translation> <translation id="2168214441502403371">Klawiatura perska</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_pt-BR.xtb b/ui/chromeos/translations/ui_chromeos_strings_pt-BR.xtb index fb0ace2..f6f7fec 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_pt-BR.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_pt-BR.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Já existe um arquivo chamado "<ph name="FILENAME" />". O que você quer fazer?</translation> <translation id="2121825465123208577">Redimensionar</translation> <translation id="2136953289241069843">Transliteração (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Não foi possível abrir "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Caractere inválido: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Teclado vietnamita (TCVN)</translation> <translation id="2168214441502403371">Teclado persa</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_pt-PT.xtb b/ui/chromeos/translations/ui_chromeos_strings_pt-PT.xtb index 48c4efb0..4900e09 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_pt-PT.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_pt-PT.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Já existe um ficheiro com o nome "<ph name="FILENAME" />". O que pretende fazer?</translation> <translation id="2121825465123208577">Redimensionar</translation> <translation id="2136953289241069843">Transliteração (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Não é possível abrir "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Caráter inválido: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Teclado vietnamita (TCVN)</translation> <translation id="2168214441502403371">Teclado persa</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ro.xtb b/ui/chromeos/translations/ui_chromeos_strings_ro.xtb index 7d6faa19c..f3ff3f9c 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ro.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ro.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Există deja un fișier numit „<ph name="FILENAME" />”. Ce doriți să faceți?</translation> <translation id="2121825465123208577">Redimensionează</translation> <translation id="2136953289241069843">Transliterație (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Nu se poate deschide „<ph name="PATH" />”: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Caracter nevalid: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Tastatură vietnameză (TCVN)</translation> <translation id="2168214441502403371">Tastatură persană</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ru.xtb b/ui/chromeos/translations/ui_chromeos_strings_ru.xtb index 9c3dd3b5..35876c13 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ru.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ru.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Файл <ph name="FILENAME" /> уже существует. Выберите необходимое действие.</translation> <translation id="2121825465123208577">Изменить размер</translation> <translation id="2136953289241069843">Транслитерация (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Не удалось открыть <ph name="PATH" />. <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Недопустимый символ: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Вьетнамская раскладка (TCVN)</translation> <translation id="2168214441502403371">Персидская раскладка</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_si.xtb b/ui/chromeos/translations/ui_chromeos_strings_si.xtb index c1f855b1..286ff3c 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_si.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_si.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803"><ph name="FILENAME" /> නමැති ගොනුවක් දැනටමත් පවතී. ඔබට එය යළි පිහිටුවීමට අවශ්යද?</translation> <translation id="2121825465123208577">ප්රතිප්රමාණ කිරීම</translation> <translation id="2136953289241069843">අක්ෂර පරිවර්තනය (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" විවෘත කළ නොහැක: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">අවලංගු අනුලකුණ: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">වියට්නාම යතුරු පුවරුව (TCVN)</translation> <translation id="2168214441502403371">පර්සියානු යතුරු පුවරුව</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_sk.xtb b/ui/chromeos/translations/ui_chromeos_strings_sk.xtb index 9decfc8..9463428 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_sk.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_sk.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Súbor s názvom <ph name="FILENAME" /> už existuje. Čo chcete urobiť?</translation> <translation id="2121825465123208577">Zmeniť veľkosť</translation> <translation id="2136953289241069843">Prepis (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Cestu <ph name="PATH" /> sa nepodarilo otvoriť: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Neplatný znak: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamská klávesnica (TCVN)</translation> <translation id="2168214441502403371">Perzská klávesnica</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_sl.xtb b/ui/chromeos/translations/ui_chromeos_strings_sl.xtb index bb710737..2127aa28 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_sl.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_sl.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Datoteka z imenom »<ph name="FILENAME" />« že obstaja. Kaj želite storiti?</translation> <translation id="2121825465123208577">Spreminjanje velikosti</translation> <translation id="2136953289241069843">Prečrkovanje (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Ni mogoče odpreti poti »<ph name="PATH" />«: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Neveljavni znak: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Tipkovnica za vietnamščino (TCVN)</translation> <translation id="2168214441502403371">Tipkovnica za perzijščino</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_sq.xtb b/ui/chromeos/translations/ui_chromeos_strings_sq.xtb index ddc1895..3cb017c 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_sq.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_sq.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Skedari me emrin "<ph name="FILENAME" />" ekziston. Çfarë do të bësh?</translation> <translation id="2121825465123208577">Ndrysho madhësinë</translation> <translation id="2136953289241069843">Transliterimi (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Është e pamundur hapja e "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Karakter i pavlefshëm: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Tastiera vietnameze (TCVN)</translation> <translation id="2168214441502403371">Tastiera persiane</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_sr-Latn.xtb b/ui/chromeos/translations/ui_chromeos_strings_sr-Latn.xtb index 2322b7bd8..f0c0375d 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_sr-Latn.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_sr-Latn.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Datoteka sa nazivom „<ph name="FILENAME" />“ već postoji. Šta želite da uradite?</translation> <translation id="2121825465123208577">Promeni veličinu</translation> <translation id="2136953289241069843">Transliteracija (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Otvaranje „<ph name="PATH" />“ nije uspelo: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Nevažeći znak: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vijetnamska tastatura (TCVN)</translation> <translation id="2168214441502403371">Persijska tastatura</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_sr.xtb b/ui/chromeos/translations/ui_chromeos_strings_sr.xtb index 8c4e9bb1..4a5b284 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_sr.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_sr.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Датотека са називом „<ph name="FILENAME" />“ већ постоји. Шта желите да урадите?</translation> <translation id="2121825465123208577">Промени величину</translation> <translation id="2136953289241069843">Транслитерација (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Отварање „<ph name="PATH" />“ није успело: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Неважећи знак: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Вијетнамска тастатура (TCVN)</translation> <translation id="2168214441502403371">Персијска тастатура</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_sv.xtb b/ui/chromeos/translations/ui_chromeos_strings_sv.xtb index a52fce1..8ae5b36 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_sv.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_sv.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Det finns redan en fil med namnet <ph name="FILENAME" />. Vad vill du göra?</translation> <translation id="2121825465123208577">Ändra storlek</translation> <translation id="2136953289241069843">Translitterering (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Det går inte att öppna <ph name="PATH" />: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Ogiltigt tecken: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Tangentbord för vietnamesiska (TCVN)</translation> <translation id="2168214441502403371">Tangentbord för persiska</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_sw.xtb b/ui/chromeos/translations/ui_chromeos_strings_sw.xtb index 3e5f877f..a65765f 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_sw.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_sw.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Tayari faili iitwayo "<ph name="FILENAME" />" ipo. Unataka kufanya nini?</translation> <translation id="2121825465123208577">Badilisha ukubwa</translation> <translation id="2136953289241069843">Unukuzi wa mfumo wa kuandika (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Haiwezi kufungua "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Herufi si sahihi: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Kibodi ya Kivietnamu (TCVN)</translation> <translation id="2168214441502403371">Kibodi ya Kiajemi</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ta.xtb b/ui/chromeos/translations/ui_chromeos_strings_ta.xtb index 01fc737..581922b 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ta.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ta.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" எனப் பெயரிடப்பட்ட கோப்பானது ஏற்கனவே உள்ளது. என்ன செய்ய விரும்புகிறீர்கள்?</translation> <translation id="2121825465123208577">அளவு மாற்று</translation> <translation id="2136953289241069843">ஒலிபெயர்ப்பு (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />"ஐத் திறக்க முடியவில்லை: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">செல்லாத எழுத்து: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">வியட்நாமிய விசைப்பலகை (TCVN)</translation> <translation id="2168214441502403371">பெர்சியன் விசைப்பலகை</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_te.xtb b/ui/chromeos/translations/ui_chromeos_strings_te.xtb index 7290f374..8c778465 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_te.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_te.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" ఫైల్ పేరు ఇప్పటికే ఉంది. మీరు ఏమి చేయాలనుకుంటున్నారు?</translation> <translation id="2121825465123208577">పరిమాణం మార్చు</translation> <translation id="2136953289241069843">లిప్యంతరీకరణ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />"ని తెరవడం సాధ్యపడలేదు: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">చెల్లని అక్షరం: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">వియత్నామీస్ కీబోర్డ్ (TCVN)</translation> <translation id="2168214441502403371">పర్షియన్ కీబోర్డ్</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_th.xtb b/ui/chromeos/translations/ui_chromeos_strings_th.xtb index 3887b59..32ad705 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_th.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_th.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">มีไฟล์ที่ชื่อว่า "<ph name="FILENAME" />" อยู่แล้ว คุณต้องการทำอย่างไร</translation> <translation id="2121825465123208577">ปรับขนาด</translation> <translation id="2136953289241069843">การทับศัพท์ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">เปิด "<ph name="PATH" />" ไม่ได้: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">อักขระไม่ถูกต้อง: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">แป้นพิมพ์ภาษาเวียดนาม (TCVN)</translation> <translation id="2168214441502403371">แป้นพิมพ์ภาษาเปอร์เซีย</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_tr.xtb b/ui/chromeos/translations/ui_chromeos_strings_tr.xtb index 7b9f36d..382e1205 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_tr.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_tr.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" adını taşıyan bir dosya zaten var. Ne yapmak istiyorsunuz?</translation> <translation id="2121825465123208577">Yeniden Boyutlandır</translation> <translation id="2136953289241069843">Harf çevirisi (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" açılamıyor: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Geçersiz karakter: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vietnamca klavye (TCVN)</translation> <translation id="2168214441502403371">Farsça klavye</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_uk.xtb b/ui/chromeos/translations/ui_chromeos_strings_uk.xtb index fa36a1e..bea61fde 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_uk.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_uk.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Файл із назвою "<ph name="FILENAME" />" уже існує. Що робити?</translation> <translation id="2121825465123208577">Змінити розмір</translation> <translation id="2136953289241069843">Транслітерація (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Не вдається відкрити шлях <ph name="PATH" />: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Недійсний символ: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">В’єтнамська клавіатура (TCVN)</translation> <translation id="2168214441502403371">Перська клавіатура</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_ur.xtb b/ui/chromeos/translations/ui_chromeos_strings_ur.xtb index 0fa091a..2850829 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_ur.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_ur.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">"<ph name="FILENAME" />" نام کی ایک فائل پہلے سے موجود ہے۔ آپ کیا کرنا چاہتے ہیں؟</translation> <translation id="2121825465123208577">سائز تبدیل کریں</translation> <translation id="2136953289241069843">نقل حرفی (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">"<ph name="PATH" />" کھولنے سے قاصر: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">غلط حرف: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">ویتنامی کی بورڈ (TCVN)</translation> <translation id="2168214441502403371">فارسی کی بورڈ</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_uz.xtb b/ui/chromeos/translations/ui_chromeos_strings_uz.xtb index 7b573e1e3..538f560 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_uz.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_uz.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">“<ph name="FILENAME" />” nomli fayl allaqachon mavjud. Kerakli amalni tanlang.</translation> <translation id="2121825465123208577">O‘lchamini o‘zgartirish</translation> <translation id="2136953289241069843">Transliteratsiya (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">“<ph name="PATH" />” ochilmadi: <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Yaroqsiz belgi: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Vyetnam klaviaturasi (TCVN)</translation> <translation id="2168214441502403371">Fors klaviaturasi</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_vi.xtb b/ui/chromeos/translations/ui_chromeos_strings_vi.xtb index 5d5045a..9328b93 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_vi.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_vi.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Tệp có tên "<ph name="FILENAME" />" đã tồn tại. Bạn muốn làm gì?</translation> <translation id="2121825465123208577">Đổi kích thước</translation> <translation id="2136953289241069843">Chuyển ngữ (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Không thể mở "<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Ký tự không hợp lệ: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Bàn phím tiếng Việt (TCVN)</translation> <translation id="2168214441502403371">Bàn phím tiếng Ba Tư</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_zh-CN.xtb b/ui/chromeos/translations/ui_chromeos_strings_zh-CN.xtb index a62fff1..38975e2 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_zh-CN.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_zh-CN.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">名为“<ph name="FILENAME" />”的文件已存在,要如何处理?</translation> <translation id="2121825465123208577">调整大小</translation> <translation id="2136953289241069843">音译(namaste → नमस्कार)</translation> -<translation id="2138867954865495510">无法打开“<ph name="PATH" />”:<ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">字符无效:<ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">越南语键盘(TCVN)</translation> <translation id="2168214441502403371">波斯语键盘</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_zh-HK.xtb b/ui/chromeos/translations/ui_chromeos_strings_zh-HK.xtb index 8fa5792c..9a69235a 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_zh-HK.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_zh-HK.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">名稱為「<ph name="FILENAME" />」的檔案已經存在,您想要怎麼做?</translation> <translation id="2121825465123208577">調整大小</translation> <translation id="2136953289241069843">音譯 (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">無法開啟「<ph name="PATH" />」:<ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">無效的字元:<ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">越南文鍵盤 (TCVN)</translation> <translation id="2168214441502403371">波斯文鍵盤</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_zh-TW.xtb b/ui/chromeos/translations/ui_chromeos_strings_zh-TW.xtb index 766b72e..64affe7 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_zh-TW.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_zh-TW.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">名稱為「<ph name="FILENAME" />」的檔案已經存在,你想要怎麼做?</translation> <translation id="2121825465123208577">調整大小</translation> <translation id="2136953289241069843">音譯 (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">無法開啟「<ph name="PATH" />」:<ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">無效的字元:<ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">越南文鍵盤 (TCVN)</translation> <translation id="2168214441502403371">波斯文鍵盤</translation>
diff --git a/ui/chromeos/translations/ui_chromeos_strings_zu.xtb b/ui/chromeos/translations/ui_chromeos_strings_zu.xtb index 0834abb..da74b01f 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_zu.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_zu.xtb
@@ -107,7 +107,6 @@ <translation id="2085470240340828803">Ifayela elinegama le-"<ph name="FILENAME" />" selivele likhona. Yini ofuna ukuyenza?</translation> <translation id="2121825465123208577">Shintsha usayizi</translation> <translation id="2136953289241069843">Ukuguqula amagama (namaste → नमस्कार)</translation> -<translation id="2138867954865495510">Ayikwazi ukuvula i-"<ph name="PATH" />": <ph name="ERROR_MESSAGE" /></translation> <translation id="2163152940313951844">Inhlamvu engavumelekile: <ph name="CHARACTER_NAME" /></translation> <translation id="2164862903024139959">Ikhibhodi ye-Vietnamese (TCVN)</translation> <translation id="2168214441502403371">Ikhibhodi ye-Persian</translation>
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index 40ba38fe..8e739da0 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -698,8 +698,7 @@ } void Compositor::FrameIntervalUpdated(base::TimeDelta interval) { - refresh_rate_ = - base::Time::kMicrosecondsPerSecond / interval.InMicrosecondsF(); + refresh_rate_ = interval.ToHz(); } void Compositor::OnFirstSurfaceActivation(
diff --git a/ui/events/devices/x11/device_data_manager_x11.cc b/ui/events/devices/x11/device_data_manager_x11.cc index a383aa4f..dde084c 100644 --- a/ui/events/devices/x11/device_data_manager_x11.cc +++ b/ui/events/devices/x11/device_data_manager_x11.cc
@@ -263,7 +263,7 @@ // Find all the touchpad devices. const XDeviceList& dev_list = ui::DeviceListCacheX11::GetInstance()->GetXDeviceList(connection); - x11::Atom xi_touchpad = gfx::GetAtom(XI_TOUCHPAD); + x11::Atom xi_touchpad = gfx::GetAtom("TOUCHPAD"); for (const auto& device : dev_list) { if (device.device_type == xi_touchpad) touchpads_[device.device_id] = true;
diff --git a/ui/events/devices/x11/device_data_manager_x11.h b/ui/events/devices/x11/device_data_manager_x11.h index f6187bd..1484a0a 100644 --- a/ui/events/devices/x11/device_data_manager_x11.h +++ b/ui/events/devices/x11/device_data_manager_x11.h
@@ -339,7 +339,7 @@ DeviceDataManagerX11::ScrollInfo::AxisInfo* axis, double valuator) const; - static const int kMaxXIEventType = XI_LASTEVENT + 1; + static const int kMaxXIEventType = 32; static const int kMaxSlotNum = 10; // Major opcode for the XInput extension. Used to identify XInput events.
diff --git a/ui/events/devices/x11/touch_factory_x11.cc b/ui/events/devices/x11/touch_factory_x11.cc index adcdd86..3eb7d6c1 100644 --- a/ui/events/devices/x11/touch_factory_x11.cc +++ b/ui/events/devices/x11/touch_factory_x11.cc
@@ -200,42 +200,35 @@ // the events from uninteresting devices. We do the latter because that's // simpler. - XDisplay* display = gfx::GetXDisplay(); + auto* connection = x11::Connection::Get(); - unsigned char mask[XIMaskLen(XI_LASTEVENT)]; - memset(mask, 0, sizeof(mask)); + x11::Input::EventMask mask{}; - SetXinputMask(mask, x11::Input::CrossingEvent::Enter); - SetXinputMask(mask, x11::Input::CrossingEvent::Leave); - SetXinputMask(mask, x11::Input::CrossingEvent::FocusIn); - SetXinputMask(mask, x11::Input::CrossingEvent::FocusOut); + SetXinputMask(&mask, x11::Input::CrossingEvent::Enter); + SetXinputMask(&mask, x11::Input::CrossingEvent::Leave); + SetXinputMask(&mask, x11::Input::CrossingEvent::FocusIn); + SetXinputMask(&mask, x11::Input::CrossingEvent::FocusOut); - SetXinputMask(mask, x11::Input::DeviceEvent::TouchBegin); - SetXinputMask(mask, x11::Input::DeviceEvent::TouchUpdate); - SetXinputMask(mask, x11::Input::DeviceEvent::TouchEnd); + SetXinputMask(&mask, x11::Input::DeviceEvent::TouchBegin); + SetXinputMask(&mask, x11::Input::DeviceEvent::TouchUpdate); + SetXinputMask(&mask, x11::Input::DeviceEvent::TouchEnd); - SetXinputMask(mask, x11::Input::DeviceEvent::ButtonPress); - SetXinputMask(mask, x11::Input::DeviceEvent::ButtonRelease); - SetXinputMask(mask, x11::Input::DeviceEvent::Motion); + SetXinputMask(&mask, x11::Input::DeviceEvent::ButtonPress); + SetXinputMask(&mask, x11::Input::DeviceEvent::ButtonRelease); + SetXinputMask(&mask, x11::Input::DeviceEvent::Motion); // HierarchyChanged and DeviceChanged allow X11EventSource to still pick up // these events. - SetXinputMask(mask, x11::Input::HierarchyEvent::opcode); - SetXinputMask(mask, x11::Input::DeviceChangedEvent::opcode); + SetXinputMask(&mask, x11::Input::HierarchyEvent::opcode); + SetXinputMask(&mask, x11::Input::DeviceChangedEvent::opcode); #if defined(OS_CHROMEOS) - // XGrabKey() must be replaced with XI2 keyboard grab if XI2 key events are - // enabled on desktop Linux. if (base::SysInfo::IsRunningOnChromeOS()) { - SetXinputMask(mask, x11::Input::DeviceEvent::KeyPress); - SetXinputMask(mask, x11::Input::DeviceEvent::KeyRelease); + SetXinputMask(&mask, x11::Input::DeviceEvent::KeyPress); + SetXinputMask(&mask, x11::Input::DeviceEvent::KeyRelease); } #endif - XIEventMask evmask; - evmask.deviceid = XIAllDevices; - evmask.mask_len = sizeof(mask); - evmask.mask = mask; - XISelectEvents(display, static_cast<uint32_t>(window), &evmask, 1); - XFlush(display); + connection->xinput().XISelectEvents({window, {mask}}); + connection->Flush(); } void TouchFactory::SetTouchDeviceList(
diff --git a/ui/events/gestures/physics_based_fling_curve.cc b/ui/events/gestures/physics_based_fling_curve.cc index 9a715080..3f6067b 100644 --- a/ui/events/gestures/physics_based_fling_curve.cc +++ b/ui/events/gestures/physics_based_fling_curve.cc
@@ -22,8 +22,8 @@ inline gfx::Vector2dF GetVelocityAtTime(const gfx::Vector2dF& current_offset, const gfx::Vector2dF& prev_offset, - double delta) { - return gfx::ScaleVector2d(current_offset - prev_offset, (1 / delta)); + base::TimeDelta delta) { + return gfx::ScaleVector2d(current_offset - prev_offset, delta.ToHz()); } float GetOffset(float velocity, float deceleration, float duration) { @@ -123,9 +123,8 @@ if (x < 1.0f) { double progress = bezier_.Solve(x); *offset = GetPositionAtTime(distance_, progress); - *velocity = - GetVelocityAtTime(*offset, prev_offset_, - (elapsed_time - previous_time_delta_).InSecondsF()); + *velocity = GetVelocityAtTime(*offset, prev_offset_, + elapsed_time - previous_time_delta_); prev_offset_ = *offset; previous_time_delta_ = elapsed_time; still_active = true;
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc index 1146cf4..ce95db8 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -356,9 +356,7 @@ SetBoolPropertyForOneType( DT_MOUSE, "Mouse Reverse Scrolling", input_device_settings_.mouse_reverse_scroll_enabled); - SetBoolPropertyForOneType( - DT_MOUSE, "Mouse High Resolution Scrolling", - base::FeatureList::IsEnabled(ui::kEnableHighResolutionMouseScrolling)); + SetBoolPropertyForOneType(DT_MOUSE, "Mouse High Resolution Scrolling", true); SetBoolPropertyForOneType(DT_TOUCHPAD, "Tap Paused", input_device_settings_.tap_to_click_paused);
diff --git a/ui/events/ozone/features.cc b/ui/events/ozone/features.cc index 0c160ac..b7ca1671 100644 --- a/ui/events/ozone/features.cc +++ b/ui/events/ozone/features.cc
@@ -9,9 +9,6 @@ const base::Feature kEnableHeuristicPalmDetectionFilter{ "EnableHeuristicPalmDetectionFilter", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kEnableHighResolutionMouseScrolling{ - "EnableHighResolutionMouseScrolling", base::FEATURE_ENABLED_BY_DEFAULT}; - const base::Feature kEnableNeuralPalmDetectionFilter{ "EnableNeuralPalmDetectionFilter", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ui/events/ozone/features.h b/ui/events/ozone/features.h index 9832b90..8237ff4 100644 --- a/ui/events/ozone/features.h +++ b/ui/events/ozone/features.h
@@ -14,9 +14,6 @@ extern const base::Feature kEnableHeuristicPalmDetectionFilter; COMPONENT_EXPORT(EVENTS_OZONE) -extern const base::Feature kEnableHighResolutionMouseScrolling; - -COMPONENT_EXPORT(EVENTS_OZONE) extern const base::Feature kEnableNeuralPalmDetectionFilter; COMPONENT_EXPORT(EVENTS_OZONE)
diff --git a/ui/events/platform/x11/x11_hotplug_event_handler.cc b/ui/events/platform/x11/x11_hotplug_event_handler.cc index 328145da..30a5bb7 100644 --- a/ui/events/platform/x11/x11_hotplug_event_handler.cc +++ b/ui/events/platform/x11/x11_hotplug_event_handler.cc
@@ -35,12 +35,6 @@ #include "ui/gfx/x/x11_atom_cache.h" #include "ui/gfx/x/x11_types.h" -#ifndef XI_PROP_PRODUCT_ID -#define XI_PROP_PRODUCT_ID "Device Product ID" -#endif - -#undef Absolute - namespace ui { namespace { @@ -79,21 +73,28 @@ base::OnceClosure hotplug_finished_callback; }; -// Stores a copy of the XIValuatorClassInfo values so X11 device processing can -// happen on a worker thread. This is needed since X11 structs are not copyable. +// Identical to FP3232_TO_DOUBLE from libxi's XExtInt.c +double Fp3232ToDouble(const x11::Input::Fp3232& x) { + return static_cast<double>(x.integral) + + static_cast<double>(x.frac) / (1ULL << 32); +} + +// Stores a copy of the x11::Input::ValuatorClass values so X11 device +// processing can happen on a worker thread. This is needed since X11 structs +// are not copyable. struct ValuatorClassInfo { - explicit ValuatorClassInfo(const XIValuatorClassInfo& info) + explicit ValuatorClassInfo(const x11::Input::ValuatorClass& info) : label(static_cast<x11::Atom>(info.label)), - max(info.max), - min(info.min), + max(Fp3232ToDouble(info.max)), + min(Fp3232ToDouble(info.min)), mode(info.mode), number(info.number) {} x11::Atom label; double max; double min; - int mode; - int number; + x11::Input::ValuatorMode mode; + uint16_t number; }; // Stores a copy of the XITouchClassInfo values so X11 device processing can @@ -156,12 +157,6 @@ x11::Atom mt_position_y; }; -// Identical to FP3232_TO_DOUBLE from libxi's XExtInt.c -double Fp3232ToDouble(const x11::Input::Fp3232& x) { - return static_cast<double>(x.integral) + - static_cast<double>(x.frac) / (1ULL << 32); -} - // Returns true if |name| is the name of a known invalid keyboard device. Note, // this may return false negatives. bool IsKnownInvalidKeyboardDevice(const std::string& name) { @@ -414,13 +409,13 @@ continue; x11::Atom type = device.device_type; - if (type == gfx::GetAtom(XI_KEYBOARD)) + if (type == gfx::GetAtom("KEYBOARD")) device_types[id] = DEVICE_TYPE_KEYBOARD; - else if (type == gfx::GetAtom(XI_MOUSE)) + else if (type == gfx::GetAtom("MOUSE")) device_types[id] = DEVICE_TYPE_MOUSE; - else if (type == gfx::GetAtom(XI_TOUCHPAD)) + else if (type == gfx::GetAtom("TOUCHPAD")) device_types[id] = DEVICE_TYPE_TOUCHPAD; - else if (type == gfx::GetAtom(XI_TOUCHSCREEN)) + else if (type == gfx::GetAtom("TOUCHSCREEN")) device_types[id] = DEVICE_TYPE_TOUCHSCREEN; }
diff --git a/ui/events/test/events_test_utils_x11.cc b/ui/events/test/events_test_utils_x11.cc index b62fdb6d..a8e6d790 100644 --- a/ui/events/test/events_test_utils_x11.cc +++ b/ui/events/test/events_test_utils_x11.cc
@@ -11,6 +11,7 @@ #include "base/notreached.h" #include "base/stl_util.h" #include "ui/events/devices/x11/touch_factory_x11.h" +#include "ui/events/devices/x11/xinput_util.h" #include "ui/events/event_constants.h" #include "ui/events/event_utils.h" #include "ui/events/keycodes/keyboard_code_conversion_x.h" @@ -227,7 +228,7 @@ dev_event->detail = XButtonEventButton(type, flags); dev_event->event_x = ToFp1616(location.x()), dev_event->event_y = ToFp1616(location.y()), - XISetMask(dev_event->button_mask.data(), XButtonEventButton(type, flags)); + SetXinputMask(dev_event->button_mask.data(), XButtonEventButton(type, flags)); // Setup an empty valuator list for generic button events. SetUpValuators(std::vector<Valuator>());
diff --git a/ui/events/x/events_x_utils.cc b/ui/events/x/events_x_utils.cc index 3dc690b3..8ab4ce1 100644 --- a/ui/events/x/events_x_utils.cc +++ b/ui/events/x/events_x_utils.cc
@@ -20,6 +20,7 @@ #include "ui/events/devices/x11/device_data_manager_x11.h" #include "ui/events/devices/x11/device_list_cache_x11.h" #include "ui/events/devices/x11/touch_factory_x11.h" +#include "ui/events/devices/x11/xinput_util.h" #include "ui/events/keycodes/keyboard_code_conversion_x.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" @@ -226,7 +227,7 @@ int GetButtonMaskForX2Event(const x11::Input::DeviceEvent& xievent) { int buttonflags = 0; for (size_t i = 0; i < 32 * xievent.button_mask.size(); i++) { - if (XIMaskIsSet(xievent.button_mask.data(), i)) { + if (ui::IsXinputMaskSet(xievent.button_mask.data(), i)) { int button = (xievent.sourceid == xievent.deviceid) ? ui::DeviceDataManagerX11::GetInstance()->GetMappedButton(i) @@ -787,6 +788,10 @@ return XModifierStateWatcher::GetInstance()->state() & Mod1Mask; } +int GetModifierKeyState() { + return XModifierStateWatcher::GetInstance()->state(); +} + void ResetTimestampRolloverCountersForTesting() { g_last_seen_timestamp_ms = 0; g_rollover_ms = 0;
diff --git a/ui/events/x/events_x_utils.h b/ui/events/x/events_x_utils.h index 5d7659b..4dbca2f 100644 --- a/ui/events/x/events_x_utils.h +++ b/ui/events/x/events_x_utils.h
@@ -91,6 +91,10 @@ // Uses the XModifierStateWatcher to determine if alt is pressed or not. EVENTS_X_EXPORT bool IsAltPressed(); +// Proxies the XModifierStateWatcher::state() to return the current state of +// modifier keys. +EVENTS_X_EXPORT int GetModifierKeyState(); + EVENTS_X_EXPORT void ResetTimestampRolloverCountersForTesting(); } // namespace ui
diff --git a/ui/file_manager/file_manager/common/js/util.js b/ui/file_manager/file_manager/common/js/util.js index 1bb1438..93e4980 100644 --- a/ui/file_manager/file_manager/common/js/util.js +++ b/ui/file_manager/file_manager/common/js/util.js
@@ -1409,12 +1409,30 @@ }; /** - * Returns true when FilesZipNoNacl is enabled. + * Returns true when FilesZipMount feature is enabled. * TODO(crbug.com/912236) Remove once transition to new ZIP system is finished. * @return {boolean} */ -util.isZipNoNacl = () => { - return loadTimeData.getBoolean('ZIP_NO_NACL'); +util.isZipMountEnabled = () => { + return loadTimeData.getBoolean('ZIP_MOUNT'); +}; + +/** + * Returns true when FilesZipPack feature is enabled. + * TODO(crbug.com/912236) Remove once transition to new ZIP system is finished. + * @return {boolean} + */ +util.isZipPackEnabled = () => { + return loadTimeData.getBoolean('ZIP_PACK'); +}; + +/** + * Returns true when FilesZipUnpack feature is enabled. + * TODO(crbug.com/912236) Remove once transition to new ZIP system is finished. + * @return {boolean} + */ +util.isZipUnpackEnabled = () => { + return loadTimeData.getBoolean('ZIP_UNPACK'); }; /**
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index d5301e82..03991cb 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -1796,7 +1796,7 @@ return; } - if (util.isZipNoNacl()) { + if (util.isZipPackEnabled()) { // TODO(crbug.com/912236) Implement and remove error notification. const item = new ProgressCenterItem(); item.id = 'no_zip';
diff --git a/ui/file_manager/file_manager/foreground/js/file_tasks.js b/ui/file_manager/file_manager/foreground/js/file_tasks.js index bb4dd73..95357ae2 100644 --- a/ui/file_manager/file_manager/foreground/js/file_tasks.js +++ b/ui/file_manager/file_manager/foreground/js/file_tasks.js
@@ -128,9 +128,9 @@ task.taskId !== FileTasks.ZIP_ARCHIVER_ZIP_USING_TMP_TASK_ID); // The Files App and the Zip Archiver are two extensions that can handle ZIP - // files. Depending on the state of the ZipNoNaCl flag, we want to filter - // out one of these extensions. - const toExclude = util.isZipNoNacl() ? + // files. Depending on the state of the FilesZipMount feature, we want to + // filter out one of these extensions. + const toExclude = util.isZipMountEnabled() ? FileTasks.ZIP_ARCHIVER_UNZIP_TASK_ID : FileTasks.FILES_OPEN_ZIP_TASK_ID; tasks = tasks.filter(task => task.taskId !== toExclude);
diff --git a/ui/file_manager/file_manager/test/js/strings.js b/ui/file_manager/file_manager/test/js/strings.js index 8b40b80e..65770ba66 100644 --- a/ui/file_manager/file_manager/test/js/strings.js +++ b/ui/file_manager/file_manager/test/js/strings.js
@@ -22,7 +22,9 @@ 'PLUGIN_VM_ENABLED': true, 'UNIFIED_MEDIA_VIEW_ENABLED': false, 'UI_LOCALE': 'en_US', - 'ZIP_NO_NACL': false, + 'ZIP_MOUNT': false, + 'ZIP_PACK': false, + 'ZIP_UNPACK': false, 'language': 'en-US', 'textdirection': 'ltr', });
diff --git a/ui/gfx/mac/io_surface.cc b/ui/gfx/mac/io_surface.cc index 8e8d763..fdb5fbc 100644 --- a/ui/gfx/mac/io_surface.cc +++ b/ui/gfx/mac/io_surface.cc
@@ -58,10 +58,16 @@ case gfx::BufferFormat::RGBA_F16: DCHECK_EQ(plane, 0); return 8; - case gfx::BufferFormat::YUV_420_BIPLANAR: - static int32_t bytes_per_element[] = {1, 2}; + case gfx::BufferFormat::YUV_420_BIPLANAR: { + constexpr int32_t bytes_per_element[] = {1, 2}; DCHECK_LT(static_cast<size_t>(plane), base::size(bytes_per_element)); return bytes_per_element[plane]; + } + case gfx::BufferFormat::P010: { + constexpr int32_t bytes_per_element[] = {2, 4}; + DCHECK_LT(static_cast<size_t>(plane), base::size(bytes_per_element)); + return bytes_per_element[plane]; + } case gfx::BufferFormat::R_16: case gfx::BufferFormat::RG_88: case gfx::BufferFormat::BGR_565: @@ -69,7 +75,6 @@ case gfx::BufferFormat::RGBX_8888: case gfx::BufferFormat::RGBA_1010102: case gfx::BufferFormat::YVU_420: - case gfx::BufferFormat::P010: NOTREACHED(); return 0; } @@ -92,6 +97,8 @@ return 'RGhA'; case gfx::BufferFormat::YUV_420_BIPLANAR: return '420v'; + case gfx::BufferFormat::P010: + return 'x420'; case gfx::BufferFormat::R_16: case gfx::BufferFormat::RG_88: case gfx::BufferFormat::BGR_565: @@ -101,7 +108,6 @@ // Technically RGBA_1010102 should be accepted as 'R10k', but then it won't // be supported by CGLTexImageIOSurface2D(), so it's best to reject it here. case gfx::BufferFormat::YVU_420: - case gfx::BufferFormat::P010: NOTREACHED(); return 0; }
diff --git a/ui/gfx/x/connection.cc b/ui/gfx/x/connection.cc index 1896ca9..2e957a0 100644 --- a/ui/gfx/x/connection.cc +++ b/ui/gfx/x/connection.cc
@@ -50,12 +50,14 @@ return static_cast<SignedType>(t0 - u0); } -XDisplay* OpenNewXDisplay() { +XDisplay* OpenNewXDisplay(const std::string& address) { if (!XInitThreads()) return nullptr; std::string display_str = - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kX11Display); + address.empty() + ? base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kX11Display) + : address; return XOpenDisplay(display_str.empty() ? nullptr : display_str.c_str()); } @@ -206,7 +208,8 @@ return instance; } -Connection::Connection() : XProto(this), display_(OpenNewXDisplay()) { +Connection::Connection(const std::string& address) + : XProto(this), display_(OpenNewXDisplay(address)) { if (display_) { XSetEventQueueOwner(display_, XCBOwnsEventQueue); @@ -337,6 +340,10 @@ return sym == static_cast<KeySym>(XK_VoidSymbol) ? kNoSymbol : sym; } +std::unique_ptr<Connection> Connection::Clone() const { + return std::make_unique<Connection>(XDisplayString(display_)); +} + void Connection::Dispatch(Delegate* delegate) { DCHECK(display_);
diff --git a/ui/gfx/x/connection.h b/ui/gfx/x/connection.h index dd8b628..a8e7524 100644 --- a/ui/gfx/x/connection.h +++ b/ui/gfx/x/connection.h
@@ -36,7 +36,7 @@ // Gets or creates the singleton connection. static Connection* Get(); - explicit Connection(); + explicit Connection(const std::string& address = ""); ~Connection(); Connection(const Connection&) = delete; @@ -93,6 +93,8 @@ // Access the event buffer. Clients can add, delete, or modify events. std::list<Event>& events() { return events_; } + std::unique_ptr<Connection> Clone() const; + private: friend class FutureBase;
diff --git a/ui/gfx/x/event.cc b/ui/gfx/x/event.cc index e70104e..4ce77f0 100644 --- a/ui/gfx/x/event.cc +++ b/ui/gfx/x/event.cc
@@ -4,15 +4,6 @@ #include "ui/gfx/x/event.h" -#include <X11/Xlibint.h> -#include <X11/extensions/XInput2.h> - -// Xlibint.h defines those as macros, which breaks the C++ versions in -// the std namespace. -#undef max -#undef min -#undef Data - #include <cstring> #include "base/check_op.h"
diff --git a/ui/gfx/x/event.h b/ui/gfx/x/event.h index 2ca6cdba..5ad11ca 100644 --- a/ui/gfx/x/event.h +++ b/ui/gfx/x/event.h
@@ -6,7 +6,6 @@ #define UI_GFX_X_EVENT_H_ #include <X11/Xlib.h> -#include <X11/extensions/XInput2.h> #include <xcb/xcb.h> #include <cstdint>
diff --git a/ui/gfx/x/gen_xproto.py b/ui/gfx/x/gen_xproto.py index 349485e..f5df00a7 100644 --- a/ui/gfx/x/gen_xproto.py +++ b/ui/gfx/x/gen_xproto.py
@@ -189,6 +189,7 @@ 'COLORMAP': 'ColorMap', 'Connection': 'RandRConnection', 'CP': 'CreatePictureAttribute', + 'CS': 'ClientSpec', 'CW': 'CreateWindowAttribute', 'DAMAGE': 'DamageId', 'DIRECTFORMAT': 'DirectFormat',
diff --git a/ui/gfx/x/x11.h b/ui/gfx/x/x11.h index 6568d0f7..c1ee10a 100644 --- a/ui/gfx/x/x11.h +++ b/ui/gfx/x/x11.h
@@ -23,15 +23,9 @@ #include <X11/Xregion.h> #include <X11/Xutil.h> #include <X11/cursorfont.h> -#include <X11/extensions/XI2.h> -#include <X11/extensions/XInput.h> -#include <X11/extensions/XInput2.h> -#include <X11/extensions/XIproto.h> #include <X11/extensions/XShm.h> -#include <X11/extensions/XTest.h> #include <X11/extensions/Xfixes.h> #include <X11/extensions/Xrender.h> -#include <X11/extensions/record.h> #include <X11/extensions/sync.h> // Define XK_xxx before the #include of <X11/keysym.h> so that <X11/keysym.h> @@ -90,12 +84,6 @@ #undef RootWindow // Defined by X11/Xlib.h #undef DestroyAll // Defined by X11/X.h to 0 #undef Always // Defined by X11/X.h to 2 -#undef AddToList // Defined by X11/extensions/XI.h to 0 -#undef COUNT // Defined by X11/extensions/XI.h to 0 -#undef CREATE // Defined by X11/extensions/XI.h to 1 -#undef DeviceAdded // Defined by X11/extensions/XI.h to 0 -#undef DeviceMode // Defined by X11/extensions/XI.h to 1 -#undef DeviceRemoved // Defined by X11/extensions/XI.h to 1 #undef FocusIn // Defined by X.h to 9 #undef FocusOut // Defined by X.h to 10 #undef None // Defined by X11/X.h to 0L
diff --git a/ui/gl/gl_image_io_surface.mm b/ui/gl/gl_image_io_surface.mm index 7c1d651..94b1fcdc2 100644 --- a/ui/gl/gl_image_io_surface.mm +++ b/ui/gl/gl_image_io_surface.mm
@@ -50,6 +50,7 @@ case GL_RGB10_A2_EXT: case GL_RGB_YCBCR_420V_CHROMIUM: case GL_RGB_YCBCR_422_CHROMIUM: + case GL_RGB_YCBCR_P010_CHROMIUM: case GL_RGBA: return true; default: @@ -73,12 +74,13 @@ return GL_RGBA; case gfx::BufferFormat::YUV_420_BIPLANAR: return GL_RGB_YCBCR_420V_CHROMIUM; + case gfx::BufferFormat::P010: + return GL_RGB_YCBCR_P010_CHROMIUM; case gfx::BufferFormat::BGR_565: case gfx::BufferFormat::RGBA_4444: case gfx::BufferFormat::RGBX_8888: case gfx::BufferFormat::RGBA_1010102: case gfx::BufferFormat::YVU_420: - case gfx::BufferFormat::P010: NOTREACHED() << gfx::BufferFormatToString(format); return 0; } @@ -246,10 +248,13 @@ } GLImageIOSurface::BindOrCopy GLImageIOSurface::ShouldBindOrCopy() { - // YUV_420_BIPLANAR is not supported by BindTexImage. - // CopyTexImage is supported by this format as that performs conversion to RGB - // as part of the copy operation. - return format_ == gfx::BufferFormat::YUV_420_BIPLANAR ? COPY : BIND; + // YUV_420_BIPLANAR and P010 are not supported by BindTexImage. CopyTexImage + // is supported by these formats as that performs conversion to RGB as part of + // the copy operation. + return (format_ == gfx::BufferFormat::YUV_420_BIPLANAR || + format_ == gfx::BufferFormat::P010) + ? COPY + : BIND; } bool GLImageIOSurface::BindTexImage(unsigned target) { @@ -339,12 +344,15 @@ glBindTexture(target, rgb_texture); }))); + const auto src_type = + format_ == gfx::BufferFormat::P010 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE; + CGLContextObj cgl_context = CGLGetCurrentContext(); { glBindTexture(GL_TEXTURE_RECTANGLE_ARB, yuv_to_rgb_converter->y_texture()); CGLError cgl_error = CGLTexImageIOSurface2D( cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RED, size_.width(), - size_.height(), GL_RED, GL_UNSIGNED_BYTE, io_surface_, 0); + size_.height(), GL_RED, src_type, io_surface_, 0); if (cgl_error != kCGLNoError) { LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the Y plane. " << cgl_error; @@ -355,7 +363,7 @@ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, yuv_to_rgb_converter->uv_texture()); CGLError cgl_error = CGLTexImageIOSurface2D( cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RG, size_.width() / 2, - size_.height() / 2, GL_RG, GL_UNSIGNED_BYTE, io_surface_, 1); + size_.height() / 2, GL_RG, src_type, io_surface_, 1); if (cgl_error != kCGLNoError) { LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the UV plane. " << cgl_error; @@ -363,7 +371,7 @@ } } - yuv_to_rgb_converter->CopyYUV420ToRGB(target, size_, rgb_texture); + yuv_to_rgb_converter->CopyYUV420ToRGB(target, size_, rgb_texture, src_type); return true; } @@ -506,6 +514,7 @@ case gfx::BufferFormat::RGBA_F16: case gfx::BufferFormat::BGRA_1010102: case gfx::BufferFormat::YUV_420_BIPLANAR: + case gfx::BufferFormat::P010: return true; case gfx::BufferFormat::R_16: case gfx::BufferFormat::RG_88: @@ -514,7 +523,6 @@ case gfx::BufferFormat::RGBX_8888: case gfx::BufferFormat::RGBA_1010102: case gfx::BufferFormat::YVU_420: - case gfx::BufferFormat::P010: return false; }
diff --git a/ui/gl/gl_image_io_surface_egl.mm b/ui/gl/gl_image_io_surface_egl.mm index dc0d2706..39d7ef89 100644 --- a/ui/gl/gl_image_io_surface_egl.mm +++ b/ui/gl/gl_image_io_surface_egl.mm
@@ -250,8 +250,11 @@ return false; } - if (format_ != gfx::BufferFormat::YUV_420_BIPLANAR) + // TODO(crbug.com/1115621): We should support gfx::BufferFormat::P010 here, + // but EGL doesn't seem to be able to sample from the P010 Y and UV textures. + if (format_ != gfx::BufferFormat::YUV_420_BIPLANAR) { return false; + } GLContext* gl_context = GLContext::GetCurrent(); DCHECK(gl_context); @@ -361,7 +364,8 @@ return false; } - yuv_to_rgb_converter->CopyYUV420ToRGB(target, size_, rgb_texture); + yuv_to_rgb_converter->CopyYUV420ToRGB(target, size_, rgb_texture, + GL_UNSIGNED_BYTE); if (glGetError() != GL_NO_ERROR) { LOG(ERROR) << "Failed converting from YUV to RGB"; return false;
diff --git a/ui/gl/yuv_to_rgb_converter.cc b/ui/gl/yuv_to_rgb_converter.cc index d086804..090fd55 100644 --- a/ui/gl/yuv_to_rgb_converter.cc +++ b/ui/gl/yuv_to_rgb_converter.cc
@@ -206,7 +206,8 @@ void YUVToRGBConverter::CopyYUV420ToRGB(unsigned target, const gfx::Size& size, - unsigned rgb_texture) { + unsigned rgb_texture, + unsigned rgb_texture_type) { GLenum source_target_getter = 0; switch (source_texture_target_) { case GL_TEXTURE_2D: @@ -233,8 +234,8 @@ // Allocate the rgb texture. glActiveTexture(old_active_texture); glBindTexture(target, rgb_texture); - glTexImage2D(target, 0, GL_RGB, size.width(), size.height(), - 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + glTexImage2D(target, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB, + rgb_texture_type, nullptr); // Set up and issue the draw call. glActiveTexture(GL_TEXTURE0);
diff --git a/ui/gl/yuv_to_rgb_converter.h b/ui/gl/yuv_to_rgb_converter.h index d228de3..2477a05 100644 --- a/ui/gl/yuv_to_rgb_converter.h +++ b/ui/gl/yuv_to_rgb_converter.h
@@ -28,7 +28,8 @@ void CopyYUV420ToRGB(unsigned target, const gfx::Size& size, - unsigned rgb_texture); + unsigned rgb_texture, + unsigned rgb_texture_type); private: unsigned framebuffer_ = 0;
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 4dbcc4d2..25fb486 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -177,7 +177,7 @@ "//ui/ozone/common", "//ui/ozone/public/mojom/wayland:wayland_mojom", "//ui/platform_window", - "//ui/platform_window/handlers", + "//ui/platform_window/wm", ] if (is_linux && !is_chromeos) { @@ -352,7 +352,7 @@ "//ui/gfx/linux:test_support", "//ui/ozone:platform", "//ui/ozone:test_support", - "//ui/platform_window/handlers", + "//ui/platform_window/wm", ] import("//ui/base/ui_features.gni")
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc index defa1c9..09bb92f 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc
@@ -35,9 +35,9 @@ #include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h" #include "ui/ozone/platform/wayland/test/wayland_test.h" #include "ui/ozone/public/platform_clipboard.h" -#include "ui/platform_window/handlers/wm_drag_handler.h" -#include "ui/platform_window/handlers/wm_drop_handler.h" #include "ui/platform_window/platform_window_init_properties.h" +#include "ui/platform_window/wm/wm_drag_handler.h" +#include "ui/platform_window/wm/wm_drop_handler.h" #include "url/gurl.h" using testing::_;
diff --git a/ui/ozone/platform/wayland/host/wayland_data_offer_base.cc b/ui/ozone/platform/wayland/host/wayland_data_offer_base.cc index 8656f41..cbdd82a 100644 --- a/ui/ozone/platform/wayland/host/wayland_data_offer_base.cc +++ b/ui/ozone/platform/wayland/host/wayland_data_offer_base.cc
@@ -9,14 +9,6 @@ namespace ui { -namespace { - -const char kString[] = "STRING"; -const char kText[] = "TEXT"; -const char kUtf8String[] = "UTF8_STRING"; - -} // namespace - WaylandDataOfferBase::WaylandDataOfferBase() = default; WaylandDataOfferBase::~WaylandDataOfferBase() = default; @@ -26,9 +18,10 @@ if (std::any_of(mime_types_.begin(), mime_types_.end(), [](const std::string& mime_type) { - return mime_type == kString || mime_type == kText || + return mime_type == kMimeTypeLinuxString || + mime_type == kMimeTypeLinuxText || mime_type == kMimeTypeTextUtf8 || - mime_type == kUtf8String; + mime_type == kMimeTypeLinuxUtf8String; })) { mime_types_.push_back(kMimeTypeText); text_plain_mime_type_inserted_ = true;
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.h b/ui/ozone/platform/wayland/host/wayland_event_source.h index 39f5d74..e646df4 100644 --- a/ui/ozone/platform/wayland/host/wayland_event_source.h +++ b/ui/ozone/platform/wayland/host/wayland_event_source.h
@@ -59,6 +59,8 @@ return last_pointer_button_pressed_; } + int keyboard_modifiers() const { return keyboard_modifiers_; } + // Starts polling for events from the wayland connection file descriptor. // This method assumes connection is already estabilished and input objects // are already bound and properly initialized.
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc index 1f24f36..678b149 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.cc
@@ -18,7 +18,7 @@ #include "ui/ozone/platform/wayland/host/wayland_data_drag_controller.h" #include "ui/ozone/platform/wayland/host/wayland_event_source.h" #include "ui/ozone/platform/wayland/host/wayland_window_drag_controller.h" -#include "ui/platform_window/handlers/wm_drop_handler.h" +#include "ui/platform_window/wm/wm_drop_handler.h" namespace ui {
diff --git a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h index 980044f..2776d9c 100644 --- a/ui/ozone/platform/wayland/host/wayland_toplevel_window.h +++ b/ui/ozone/platform/wayland/host/wayland_toplevel_window.h
@@ -8,9 +8,9 @@ #include "build/lacros_buildflags.h" #include "ui/gfx/geometry/vector2d.h" #include "ui/ozone/platform/wayland/host/wayland_window.h" -#include "ui/platform_window/handlers/wm_drag_handler.h" -#include "ui/platform_window/handlers/wm_move_loop_handler.h" -#include "ui/platform_window/handlers/wm_move_resize_handler.h" +#include "ui/platform_window/wm/wm_drag_handler.h" +#include "ui/platform_window/wm/wm_move_loop_handler.h" +#include "ui/platform_window/wm/wm_move_resize_handler.h" namespace ui {
diff --git a/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc index d6aa7c9e..7ad32a4 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_drag_controller_unittest.cc
@@ -31,8 +31,8 @@ #include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h" #include "ui/ozone/platform/wayland/test/wayland_test.h" #include "ui/ozone/test/mock_platform_window_delegate.h" -#include "ui/platform_window/handlers/wm_move_loop_handler.h" #include "ui/platform_window/platform_window_delegate.h" +#include "ui/platform_window/wm/wm_move_loop_handler.h" using testing::_; using testing::Mock;
diff --git a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc index 745e2f8..2626222a 100644 --- a/ui/ozone/platform/wayland/host/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
@@ -30,8 +30,8 @@ #include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h" #include "ui/ozone/platform/wayland/test/wayland_test.h" #include "ui/ozone/test/mock_platform_window_delegate.h" -#include "ui/platform_window/handlers/wm_move_resize_handler.h" #include "ui/platform_window/platform_window_init_properties.h" +#include "ui/platform_window/wm/wm_move_resize_handler.h" using ::testing::_; using ::testing::Eq;
diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc index 1e78bc51..ce7fbe99 100644 --- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc +++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -29,6 +29,7 @@ #include "ui/ozone/platform/wayland/host/wayland_buffer_manager_connector.h" #include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h" #include "ui/ozone/platform/wayland/host/wayland_connection.h" +#include "ui/ozone/platform/wayland/host/wayland_event_source.h" #include "ui/ozone/platform/wayland/host/wayland_input_method_context_factory.h" #include "ui/ozone/platform/wayland/host/wayland_output_manager.h" #include "ui/ozone/platform/wayland/host/wayland_window.h" @@ -138,6 +139,12 @@ return connection_->clipboard(); } + int GetKeyModifiers() const override { + DCHECK(connection_); + DCHECK(connection_->event_source()); + return connection_->event_source()->keyboard_modifiers(); + } + std::unique_ptr<InputMethod> CreateInputMethod( internal::InputMethodDelegate* delegate, gfx::AcceleratedWidget widget) override {
diff --git a/ui/ozone/platform/x11/BUILD.gn b/ui/ozone/platform/x11/BUILD.gn index 44845221..6a50113 100644 --- a/ui/ozone/platform/x11/BUILD.gn +++ b/ui/ozone/platform/x11/BUILD.gn
@@ -58,7 +58,7 @@ "//ui/ozone:ozone_base", "//ui/ozone/common", "//ui/platform_window", - "//ui/platform_window/handlers", + "//ui/platform_window/wm", "//ui/platform_window/x11", ]
diff --git a/ui/ozone/platform/x11/ozone_platform_x11.cc b/ui/ozone/platform/x11/ozone_platform_x11.cc index 633381d..c14645b 100644 --- a/ui/ozone/platform/x11/ozone_platform_x11.cc +++ b/ui/ozone/platform/x11/ozone_platform_x11.cc
@@ -22,6 +22,7 @@ #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" #include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h" #include "ui/events/platform/x11/x11_event_source.h" +#include "ui/events/x/events_x_utils.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/x/x11_types.h" #include "ui/ozone/common/stub_overlay_manager.h" @@ -133,6 +134,8 @@ return gl_egl_utility_.get(); } + int GetKeyModifiers() const override { return GetModifierKeyState(); } + std::unique_ptr<InputMethod> CreateInputMethod( internal::InputMethodDelegate* delegate, gfx::AcceleratedWidget) override {
diff --git a/ui/ozone/platform/x11/x11_clipboard_ozone.cc b/ui/ozone/platform/x11/x11_clipboard_ozone.cc index d4fed35..16a0476 100644 --- a/ui/ozone/platform/x11/x11_clipboard_ozone.cc +++ b/ui/ozone/platform/x11/x11_clipboard_ozone.cc
@@ -25,23 +25,21 @@ const char kChromeSelection[] = "CHROME_SELECTION"; const char kClipboard[] = "CLIPBOARD"; -const char kString[] = "STRING"; const char kTargets[] = "TARGETS"; const char kTimestamp[] = "TIMESTAMP"; -const char kUtf8String[] = "UTF8_STRING"; // Helps to allow conversions for text/plain[;charset=utf-8] <=> [UTF8_]STRING. void ExpandTypes(std::vector<std::string>* list) { bool has_mime_type_text = Contains(*list, ui::kMimeTypeText); - bool has_string = Contains(*list, kString); + bool has_string = Contains(*list, kMimeTypeLinuxString); bool has_mime_type_utf8 = Contains(*list, kMimeTypeTextUtf8); - bool has_utf8_string = Contains(*list, kUtf8String); + bool has_utf8_string = Contains(*list, kMimeTypeLinuxUtf8String); if (has_mime_type_text && !has_string) - list->push_back(kString); + list->push_back(kMimeTypeLinuxString); if (has_string && !has_mime_type_text) list->push_back(ui::kMimeTypeText); if (has_mime_type_utf8 && !has_utf8_string) - list->push_back(kUtf8String); + list->push_back(kMimeTypeLinuxUtf8String); if (has_utf8_string && !has_mime_type_utf8) list->push_back(kMimeTypeTextUtf8); } @@ -163,9 +161,11 @@ std::string key = target_name; // Allow conversions for text/plain[;charset=utf-8] <=> [UTF8_]STRING. - if (key == kUtf8String && !Contains(offer_data_map, kUtf8String)) { + if (key == kMimeTypeLinuxUtf8String && + !Contains(offer_data_map, kMimeTypeLinuxUtf8String)) { key = kMimeTypeTextUtf8; - } else if (key == kString && !Contains(offer_data_map, kString)) { + } else if (key == kMimeTypeLinuxString && + !Contains(offer_data_map, kMimeTypeLinuxString)) { key = kMimeTypeText; } auto it = offer_data_map.find(key); @@ -314,9 +314,9 @@ std::string target = selection_state.data_mime_type; if (!Contains(selection_state.mime_types, target)) { if (target == kMimeTypeText) { - target = kString; + target = kMimeTypeLinuxString; } else if (target == kMimeTypeTextUtf8) { - target = kUtf8String; + target = kMimeTypeLinuxUtf8String; } }
diff --git a/ui/ozone/public/ozone_platform.cc b/ui/ozone/public/ozone_platform.cc index f08c81e..c7027b2 100644 --- a/ui/ozone/public/ozone_platform.cc +++ b/ui/ozone/public/ozone_platform.cc
@@ -95,6 +95,11 @@ return nullptr; } +int OzonePlatform::GetKeyModifiers() const { + // Platform may override this to provide the current state of modifier keys. + return 0; +} + bool OzonePlatform::IsNativePixmapConfigSupported( gfx::BufferFormat format, gfx::BufferUsage usage) const {
diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h index 9e741f52..4bcc8a5 100644 --- a/ui/ozone/public/ozone_platform.h +++ b/ui/ozone/public/ozone_platform.h
@@ -175,6 +175,10 @@ gfx::AcceleratedWidget widget) = 0; virtual PlatformGLEGLUtility* GetPlatformGLEGLUtility(); + // Returns a bitmask of EventFlags showing the state of Alt, Shift and Ctrl + // keys that came with the most recent UI event. + virtual int GetKeyModifiers() const; + // Returns true if the specified buffer format is supported. virtual bool IsNativePixmapConfigSupported(gfx::BufferFormat format, gfx::BufferUsage usage) const;
diff --git a/ui/platform_window/handlers/BUILD.gn b/ui/platform_window/wm/BUILD.gn similarity index 81% rename from ui/platform_window/handlers/BUILD.gn rename to ui/platform_window/wm/BUILD.gn index 48fe42ba..96937273 100644 --- a/ui/platform_window/handlers/BUILD.gn +++ b/ui/platform_window/wm/BUILD.gn
@@ -2,8 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -component("handlers") { - output_name = "platform_window_handler_libs" +component("wm") { + output_name = "platform_window_wm" sources = [ "wm_drag_handler.cc", @@ -16,7 +16,7 @@ "wm_move_resize_handler.h", ] - defines = [ "IS_HANDLERS_IMPL" ] + defines = [ "IS_WM_IMPL" ] deps = [ "//ui/base",
diff --git a/ui/platform_window/handlers/DEPS b/ui/platform_window/wm/DEPS similarity index 100% rename from ui/platform_window/handlers/DEPS rename to ui/platform_window/wm/DEPS
diff --git a/ui/platform_window/handlers/wm_drag_handler.cc b/ui/platform_window/wm/wm_drag_handler.cc similarity index 92% rename from ui/platform_window/handlers/wm_drag_handler.cc rename to ui/platform_window/wm/wm_drag_handler.cc index 7d1b208..ea8b1df 100644 --- a/ui/platform_window/handlers/wm_drag_handler.cc +++ b/ui/platform_window/wm/wm_drag_handler.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 "ui/platform_window/handlers/wm_drag_handler.h" +#include "ui/platform_window/wm/wm_drag_handler.h" #include "ui/base/class_property.h" #include "ui/platform_window/platform_window.h"
diff --git a/ui/platform_window/handlers/wm_drag_handler.h b/ui/platform_window/wm/wm_drag_handler.h similarity index 89% rename from ui/platform_window/handlers/wm_drag_handler.h rename to ui/platform_window/wm/wm_drag_handler.h index 67e9eeb..769554c4 100644 --- a/ui/platform_window/handlers/wm_drag_handler.h +++ b/ui/platform_window/wm/wm_drag_handler.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 UI_PLATFORM_WINDOW_HANDLERS_WM_DRAG_HANDLER_H_ -#define UI_PLATFORM_WINDOW_HANDLERS_WM_DRAG_HANDLER_H_ +#ifndef UI_PLATFORM_WINDOW_WM_WM_DRAG_HANDLER_H_ +#define UI_PLATFORM_WINDOW_WM_WM_DRAG_HANDLER_H_ #include "base/component_export.h" #include "ui/base/dragdrop/drag_drop_types.h" @@ -17,7 +17,7 @@ class PlatformWindow; class OSExchangeData; -class COMPONENT_EXPORT(HANDLERS) WmDragHandler { +class COMPONENT_EXPORT(WM) WmDragHandler { public: // During the drag operation, the handler may send updates class Delegate { @@ -59,12 +59,12 @@ virtual void CancelDrag() = 0; }; -COMPONENT_EXPORT(HANDLERS) +COMPONENT_EXPORT(WM) void SetWmDragHandler(PlatformWindow* platform_window, WmDragHandler* drag_handler); -COMPONENT_EXPORT(HANDLERS) +COMPONENT_EXPORT(WM) WmDragHandler* GetWmDragHandler(const PlatformWindow& platform_window); } // namespace ui -#endif // UI_PLATFORM_WINDOW_HANDLERS_WM_DRAG_HANDLER_H_ +#endif // UI_PLATFORM_WINDOW_WM_WM_DRAG_HANDLER_H_
diff --git a/ui/platform_window/handlers/wm_drop_handler.cc b/ui/platform_window/wm/wm_drop_handler.cc similarity index 92% rename from ui/platform_window/handlers/wm_drop_handler.cc rename to ui/platform_window/wm/wm_drop_handler.cc index 5a981c8..87ea9973 100644 --- a/ui/platform_window/handlers/wm_drop_handler.cc +++ b/ui/platform_window/wm/wm_drop_handler.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 "ui/platform_window/handlers/wm_drop_handler.h" +#include "ui/platform_window/wm/wm_drop_handler.h" #include "ui/base/class_property.h" #include "ui/platform_window/platform_window.h"
diff --git a/ui/platform_window/handlers/wm_drop_handler.h b/ui/platform_window/wm/wm_drop_handler.h similarity index 88% rename from ui/platform_window/handlers/wm_drop_handler.h rename to ui/platform_window/wm/wm_drop_handler.h index bd8fd35..2096843 100644 --- a/ui/platform_window/handlers/wm_drop_handler.h +++ b/ui/platform_window/wm/wm_drop_handler.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 UI_PLATFORM_WINDOW_HANDLERS_WM_DROP_HANDLER_H_ -#define UI_PLATFORM_WINDOW_HANDLERS_WM_DROP_HANDLER_H_ +#ifndef UI_PLATFORM_WINDOW_WM_WM_DROP_HANDLER_H_ +#define UI_PLATFORM_WINDOW_WM_WM_DROP_HANDLER_H_ #include <memory> @@ -17,7 +17,7 @@ class PlatformWindow; class OSExchangeData; -class COMPONENT_EXPORT(HANDLERS) WmDropHandler { +class COMPONENT_EXPORT(WM) WmDropHandler { public: // Notifies that drag has entered the window. // |point| is in the coordinate space of the PlatformWindow. @@ -53,12 +53,12 @@ virtual ~WmDropHandler() = default; }; -COMPONENT_EXPORT(HANDLERS) +COMPONENT_EXPORT(WM) void SetWmDropHandler(PlatformWindow* platform_window, WmDropHandler* drop_handler); -COMPONENT_EXPORT(HANDLERS) +COMPONENT_EXPORT(WM) WmDropHandler* GetWmDropHandler(const PlatformWindow& platform_window); } // namespace ui -#endif // UI_PLATFORM_WINDOW_HANDLERS_WM_DROP_HANDLER_H_ +#endif // UI_PLATFORM_WINDOW_WM_WM_DROP_HANDLER_H_
diff --git a/ui/platform_window/handlers/wm_move_loop_handler.cc b/ui/platform_window/wm/wm_move_loop_handler.cc similarity index 92% rename from ui/platform_window/handlers/wm_move_loop_handler.cc rename to ui/platform_window/wm/wm_move_loop_handler.cc index 07ec6477..d5a9170 100644 --- a/ui/platform_window/handlers/wm_move_loop_handler.cc +++ b/ui/platform_window/wm/wm_move_loop_handler.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 "ui/platform_window/handlers/wm_move_loop_handler.h" +#include "ui/platform_window/wm/wm_move_loop_handler.h" #include "ui/base/class_property.h" #include "ui/platform_window/platform_window.h"
diff --git a/ui/platform_window/handlers/wm_move_loop_handler.h b/ui/platform_window/wm/wm_move_loop_handler.h similarity index 74% rename from ui/platform_window/handlers/wm_move_loop_handler.h rename to ui/platform_window/wm/wm_move_loop_handler.h index cbe0c21..f7c311c 100644 --- a/ui/platform_window/handlers/wm_move_loop_handler.h +++ b/ui/platform_window/wm/wm_move_loop_handler.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 UI_PLATFORM_WINDOW_HANDLERS_WM_MOVE_LOOP_HANDLER_H_ -#define UI_PLATFORM_WINDOW_HANDLERS_WM_MOVE_LOOP_HANDLER_H_ +#ifndef UI_PLATFORM_WINDOW_WM_WM_MOVE_LOOP_HANDLER_H_ +#define UI_PLATFORM_WINDOW_WM_WM_MOVE_LOOP_HANDLER_H_ #include "base/component_export.h" @@ -16,7 +16,7 @@ class PlatformWindow; // Handler that starts interactive move loop for the PlatformWindow. -class COMPONENT_EXPORT(HANDLERS) WmMoveLoopHandler { +class COMPONENT_EXPORT(WM) WmMoveLoopHandler { public: // Starts a move loop for tab drag controller. Returns true on success or // false on fail/cancel. @@ -29,12 +29,12 @@ virtual ~WmMoveLoopHandler() {} }; -COMPONENT_EXPORT(HANDLERS) +COMPONENT_EXPORT(WM) void SetWmMoveLoopHandler(PlatformWindow* platform_window, WmMoveLoopHandler* drag_handler); -COMPONENT_EXPORT(HANDLERS) +COMPONENT_EXPORT(WM) WmMoveLoopHandler* GetWmMoveLoopHandler(const PlatformWindow& platform_window); } // namespace ui -#endif // UI_PLATFORM_WINDOW_HANDLERS_WM_MOVE_LOOP_HANDLER_H_ +#endif // UI_PLATFORM_WINDOW_WM_WM_MOVE_LOOP_HANDLER_H_
diff --git a/ui/platform_window/handlers/wm_move_resize_handler.cc b/ui/platform_window/wm/wm_move_resize_handler.cc similarity index 92% rename from ui/platform_window/handlers/wm_move_resize_handler.cc rename to ui/platform_window/wm/wm_move_resize_handler.cc index 5faa080..d3b2862 100644 --- a/ui/platform_window/handlers/wm_move_resize_handler.cc +++ b/ui/platform_window/wm/wm_move_resize_handler.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 "ui/platform_window/handlers/wm_move_resize_handler.h" +#include "ui/platform_window/wm/wm_move_resize_handler.h" #include "ui/base/class_property.h" #include "ui/platform_window/platform_window.h"
diff --git a/ui/platform_window/handlers/wm_move_resize_handler.h b/ui/platform_window/wm/wm_move_resize_handler.h similarity index 88% rename from ui/platform_window/handlers/wm_move_resize_handler.h rename to ui/platform_window/wm/wm_move_resize_handler.h index 436fecc..8f0bb008 100644 --- a/ui/platform_window/handlers/wm_move_resize_handler.h +++ b/ui/platform_window/wm/wm_move_resize_handler.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 UI_PLATFORM_WINDOW_HANDLERS_WM_MOVE_RESIZE_HANDLER_H_ -#define UI_PLATFORM_WINDOW_HANDLERS_WM_MOVE_RESIZE_HANDLER_H_ +#ifndef UI_PLATFORM_WINDOW_WM_WM_MOVE_RESIZE_HANDLER_H_ +#define UI_PLATFORM_WINDOW_WM_WM_MOVE_RESIZE_HANDLER_H_ #include "base/component_export.h" @@ -15,7 +15,7 @@ class PlatformWindow; -class COMPONENT_EXPORT(HANDLERS) WmMoveResizeHandler { +class COMPONENT_EXPORT(WM) WmMoveResizeHandler { public: // A system window manager starts interactive drag or resize of a window based // on the |hittest| value. The |hittest| value identifies in which direction @@ -52,13 +52,13 @@ virtual ~WmMoveResizeHandler() {} }; -COMPONENT_EXPORT(HANDLERS) +COMPONENT_EXPORT(WM) void SetWmMoveResizeHandler(PlatformWindow* platform_window, WmMoveResizeHandler* move_resize_handler); -COMPONENT_EXPORT(HANDLERS) +COMPONENT_EXPORT(WM) WmMoveResizeHandler* GetWmMoveResizeHandler( const PlatformWindow& platform_window); } // namespace ui -#endif // UI_PLATFORM_WINDOW_HANDLERS_WM_MOVE_RESIZE_HANDLER_H_ +#endif // UI_PLATFORM_WINDOW_WM_WM_MOVE_RESIZE_HANDLER_H_
diff --git a/ui/platform_window/x11/BUILD.gn b/ui/platform_window/x11/BUILD.gn index 1fdb8c6..47eae58 100644 --- a/ui/platform_window/x11/BUILD.gn +++ b/ui/platform_window/x11/BUILD.gn
@@ -25,7 +25,7 @@ "//ui/platform_window", "//ui/platform_window/common", "//ui/platform_window/extensions", - "//ui/platform_window/handlers", + "//ui/platform_window/wm", ] defines = [ "X11_WINDOW_IMPLEMENTATION" ]
diff --git a/ui/platform_window/x11/x11_window.cc b/ui/platform_window/x11/x11_window.cc index a1d56f5..c0ba5c3 100644 --- a/ui/platform_window/x11/x11_window.cc +++ b/ui/platform_window/x11/x11_window.cc
@@ -28,7 +28,7 @@ #include "ui/platform_window/common/platform_window_defaults.h" #include "ui/platform_window/extensions/workspace_extension_delegate.h" #include "ui/platform_window/extensions/x11_extension_delegate.h" -#include "ui/platform_window/handlers/wm_drop_handler.h" +#include "ui/platform_window/wm/wm_drop_handler.h" #include "ui/platform_window/x11/x11_topmost_window_finder.h" #include "ui/platform_window/x11/x11_window_manager.h"
diff --git a/ui/platform_window/x11/x11_window.h b/ui/platform_window/x11/x11_window.h index a479792..69705f96 100644 --- a/ui/platform_window/x11/x11_window.h +++ b/ui/platform_window/x11/x11_window.h
@@ -14,11 +14,11 @@ #include "ui/gfx/x/event.h" #include "ui/platform_window/extensions/workspace_extension.h" #include "ui/platform_window/extensions/x11_extension.h" -#include "ui/platform_window/handlers/wm_drag_handler.h" -#include "ui/platform_window/handlers/wm_move_loop_handler.h" -#include "ui/platform_window/handlers/wm_move_resize_handler.h" #include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_init_properties.h" +#include "ui/platform_window/wm/wm_drag_handler.h" +#include "ui/platform_window/wm/wm_move_loop_handler.h" +#include "ui/platform_window/wm/wm_move_resize_handler.h" #include "ui/platform_window/x11/x11_window_export.h" namespace ui {
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index 8f87186e..e4f2a50 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd
@@ -712,6 +712,11 @@ Win </message> </if> + <if expr="chromeos"> + <message name="IDS_APP_FULLSCREEN_KEY" desc="This refers to the 'Fullscreen' media key on certain keyboards."> + Fullscreen + </message> + </if> <!-- Accelerator format --> <message name="IDS_APP_ACCELERATOR_WITH_MODIFIER" desc="Accelerator with a modifier key">
diff --git a/ui/strings/ui_strings_grd/IDS_APP_FULLSCREEN_KEY.png.sha1 b/ui/strings/ui_strings_grd/IDS_APP_FULLSCREEN_KEY.png.sha1 new file mode 100644 index 0000000..36a4234e --- /dev/null +++ b/ui/strings/ui_strings_grd/IDS_APP_FULLSCREEN_KEY.png.sha1
@@ -0,0 +1 @@ +36a5013c7a18ff69d3b4e8c759bdf83414358fe5 \ No newline at end of file
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 819a72c..83337bb 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -726,7 +726,7 @@ "//ui/aura", "//ui/events", "//ui/platform_window", - "//ui/platform_window/handlers", + "//ui/platform_window/wm", "//ui/touch_selection", "//ui/wm", "//ui/wm/public", @@ -1166,7 +1166,7 @@ "//ui/gl:test_support", "//ui/native_theme", "//ui/native_theme:test_support", - "//ui/platform_window/handlers", + "//ui/platform_window/wm", "//ui/resources", "//ui/resources:ui_test_pak", "//ui/strings", @@ -1382,7 +1382,7 @@ deps += [ "//ui/events/platform", "//ui/platform_window", - "//ui/platform_window/handlers", + "//ui/platform_window/wm", ] }
diff --git a/ui/views/bubble/bubble_dialog_model_host.cc b/ui/views/bubble/bubble_dialog_model_host.cc index 1c48c029..9aaeca73e 100644 --- a/ui/views/bubble/bubble_dialog_model_host.cc +++ b/ui/views/bubble/bubble_dialog_model_host.cc
@@ -75,9 +75,11 @@ button_mask |= field->model_field_id(GetPassKey()); SetButtons(button_mask); - SetButtonLabel( - static_cast<ui::DialogButton>(field->model_field_id(GetPassKey())), - button->label()); + if (!button->label().empty()) { + SetButtonLabel( + static_cast<ui::DialogButton>(field->model_field_id(GetPassKey())), + button->label()); + } } // Populate dialog using the observer functions to make sure they use the same
diff --git a/ui/views/controls/menu/menu_config.h b/ui/views/controls/menu/menu_config.h index c84d1377..e64b3934 100644 --- a/ui/views/controls/menu/menu_config.h +++ b/ui/views/controls/menu/menu_config.h
@@ -208,6 +208,30 @@ // Margins for footnotes (HIGHLIGHTED item at the end of a menu). int footnote_vertical_margin = 11; + // New Badge ----------------------------------------------------------------- + // Note that there are a few differences between Views and Mac constants here + // that are due to the fact that the rendering is different and therefore + // tweaks to the spacing need to be made to achieve the same visual result. + + // Difference in the font size (in pixels) between menu label font and "new" + // badge font size. + static constexpr int kNewBadgeFontSizeAdjustment = -1; + + // Space between primary text and "new" badge. + static constexpr int kNewBadgeHorizontalMargin = 8; + + // Highlight padding around "new" text. + static constexpr int kNewBadgeInternalPadding = 4; + static constexpr int kNewBadgeInternalPaddingTopMac = 1; + + // The baseline offset of the "new" badge image to the menu text baseline. + static constexpr int kNewBadgeBaslineOffsetMac = -4; + + // The corner radius of the rounded rect for the "new" badge. + static constexpr int kNewBadgeCornerRadius = 3; + static_assert(kNewBadgeCornerRadius <= kNewBadgeInternalPadding, + "New badge corner radius should not exceed padding."); + private: // Configures a MenuConfig as appropriate for the current platform. void Init();
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc index db64400..e275417 100644 --- a/ui/views/controls/menu/menu_controller_unittest.cc +++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -877,12 +877,10 @@ INSTANTIATE_TEST_SUITE_P(All, MenuControllerTest, testing::Bool()); -#if defined(USE_X11) +#if defined(USE_AURA) // Tests that an event targeter which blocks events will be honored by the menu // event dispatcher. TEST_F(MenuControllerTest, EventTargeter) { - if (features::IsUsingOzonePlatform()) - return; { // With the aura::NullWindowTargeter instantiated and assigned we expect // the menu to not handle the key event. @@ -896,8 +894,7 @@ TestAsyncEscapeKey(); EXPECT_EQ(MenuController::ExitType::kAll, menu_exit_type()); } - -#endif // defined(USE_X11) +#endif // defined(USE_AURA) #if defined(USE_X11) // Tests that touch event ids are released correctly. See crbug.com/439051 for
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc index 1b111dd..f14eb80 100644 --- a/ui/views/controls/menu/menu_item_view.cc +++ b/ui/views/controls/menu/menu_item_view.cc
@@ -53,21 +53,6 @@ namespace { -// Difference in the font size (in pixels) between menu label font and "new" -// badge font size. -constexpr int kNewBadgeFontSizeAdjustment = -1; - -// Space between primary text and "new" badge. -constexpr int kNewBadgeHorizontalMargin = 8; - -// Highlight size around "new" badge. -constexpr gfx::Insets kNewBadgeInternalPadding{4}; - -// The corner radius of the rounded rect for the "new" badge. -constexpr int kNewBadgeCornerRadius = 3; -static_assert(kNewBadgeCornerRadius <= kNewBadgeInternalPadding.left(), - "New badge corner radius should not exceed padding."); - // Returns the appropriate font to use for the "new" badge based on the font // currently being used to render the title of the menu item. gfx::FontList DeriveNewBadgeFont(const gfx::FontList& primary_font) { @@ -76,8 +61,8 @@ // add a small degree of bold to prevent color smearing/blurring due to font // smoothing. This ensures readability on all platforms and in both light and // dark modes. - return primary_font.DeriveWithSizeDelta(kNewBadgeFontSizeAdjustment) - .DeriveWithWeight(gfx::Font::Weight::MEDIUM); + return primary_font.Derive(MenuConfig::kNewBadgeFontSizeAdjustment, + gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM); } // Returns the horizontal space required for the "new" badge. @@ -86,7 +71,8 @@ l10n_util::GetStringUTF16(IDS_MENU_ITEM_NEW_BADGE); gfx::FontList badge_font = DeriveNewBadgeFont(primary_font); return gfx::GetStringWidth(new_text, badge_font) + - kNewBadgeInternalPadding.width() + 2 * kNewBadgeHorizontalMargin; + 2 * MenuConfig::kNewBadgeInternalPadding + + 2 * MenuConfig::kNewBadgeHorizontalMargin; } // Returns the highlight rect for the "new" badge given the font and text rect @@ -94,8 +80,8 @@ gfx::Rect GetNewBadgeRectOutsetAroundText(const gfx::FontList& badge_font, const gfx::Rect& badge_text_rect) { gfx::Rect badge_rect = badge_text_rect; - badge_rect.Inset( - -gfx::AdjustVisualBorderForFont(badge_font, kNewBadgeInternalPadding)); + badge_rect.Inset(-gfx::AdjustVisualBorderForFont( + badge_font, gfx::Insets(MenuConfig::kNewBadgeInternalPadding))); return badge_rect; } @@ -1038,7 +1024,7 @@ DrawNewBadge( canvas, gfx::Point(label_start + gfx::GetStringWidth(title(), style.font_list) + - kNewBadgeHorizontalMargin, + MenuConfig::kNewBadgeHorizontalMargin, top_margin), style.font_list, flags); } @@ -1370,7 +1356,7 @@ gfx::Rect badge_text_bounds(unmirrored_badge_start, gfx::GetStringSize(new_text, badge_font)); badge_text_bounds.Offset( - kNewBadgeInternalPadding.left(), + MenuConfig::kNewBadgeInternalPadding, gfx::GetFontCapHeightCenterOffset(primary_font, badge_font)); if (base::i18n::IsRTL()) badge_text_bounds.set_x(GetMirroredXForRect(badge_text_bounds)); @@ -1382,7 +1368,7 @@ new_flags.setColor(background_color); canvas->DrawRoundRect( GetNewBadgeRectOutsetAroundText(badge_font, badge_text_bounds), - kNewBadgeCornerRadius, new_flags); + MenuConfig::kNewBadgeCornerRadius, new_flags); // Render the badge text. const SkColor foreground_color = GetNativeTheme()->GetSystemColor(
diff --git a/ui/views/controls/menu/menu_runner.h b/ui/views/controls/menu/menu_runner.h index e6b8476..5029f456 100644 --- a/ui/views/controls/menu/menu_runner.h +++ b/ui/views/controls/menu/menu_runner.h
@@ -67,7 +67,6 @@ // The menu is a nested context menu. For example, click a folder on the // bookmark bar, then right click an entry to get its context menu. - // Currently implies FORCE_VIEWS. IS_NESTED = 1 << 1, // Used for showing a menu during a drop operation. This does NOT block the @@ -109,10 +108,6 @@ // Indicates that the menu should show mnemonics. SHOULD_SHOW_MNEMONICS = 1 << 10, - - // Indicates that the menu contains Views-only features, and therefore - // should not be rendered using a native system menu. - FORCE_VIEWS = 1 << 11, }; // Creates a new MenuRunner, which may use a native menu if available.
diff --git a/ui/views/controls/menu/menu_runner_impl.cc b/ui/views/controls/menu/menu_runner_impl.cc index 4450eea..a350498 100644 --- a/ui/views/controls/menu/menu_runner_impl.cc +++ b/ui/views/controls/menu/menu_runner_impl.cc
@@ -24,10 +24,15 @@ #endif #if defined(USE_X11) -#include "ui/base/ui_base_features.h" #include "ui/events/x/events_x_utils.h" // nogncheck #endif +#if defined(USE_OZONE) +#include "ui/base/ui_base_features.h" +#include "ui/events/event_constants.h" +#include "ui/ozone/public/ozone_platform.h" +#endif + namespace views { namespace { @@ -45,6 +50,22 @@ } } +#if defined(USE_X11) || defined(USE_OZONE) +bool IsAltPressed() { +#if defined(USE_OZONE) + if (features::IsUsingOzonePlatform()) { + return (ui::OzonePlatform::GetInstance()->GetKeyModifiers() & + ui::EF_ALT_DOWN) != 0; + } +#endif +#if defined(USE_X11) + return ui::IsAltPressed(); +#else + return false; +#endif +} +#endif // defined(USE_X11) || degined(USE_OZONE) + } // namespace namespace internal { @@ -242,10 +263,8 @@ // Show mnemonics if the button has focus or alt is pressed. #if defined(OS_WIN) show_mnemonics |= ui::win::IsAltPressed(); -#elif defined(USE_X11) - // TODO(https://crbug.com/1098203): fix mnemonics for Ozone/Linux. - if (!features::IsUsingOzonePlatform()) - show_mnemonics |= ui::IsAltPressed(); +#elif defined(USE_X11) || defined(USE_OZONE) + show_mnemonics |= IsAltPressed(); #elif defined(OS_APPLE) show_mnemonics = false; #endif
diff --git a/ui/views/controls/menu/menu_runner_impl_cocoa.h b/ui/views/controls/menu/menu_runner_impl_cocoa.h index d24e6915..ce54769f 100644 --- a/ui/views/controls/menu/menu_runner_impl_cocoa.h +++ b/ui/views/controls/menu/menu_runner_impl_cocoa.h
@@ -14,6 +14,7 @@ #include "ui/views/controls/menu/menu_runner_impl_interface.h" @class MenuControllerCocoa; +@class MenuControllerDelegate; namespace views { namespace test { @@ -45,6 +46,9 @@ // The Cocoa menu controller that this instance is bridging. base::scoped_nsobject<MenuControllerCocoa> menu_controller_; + // The delegate for the |menu_controller_|. + base::scoped_nsobject<MenuControllerDelegate> menu_delegate_; + // Are we in run waiting for it to return? bool running_;
diff --git a/ui/views/controls/menu/menu_runner_impl_cocoa.mm b/ui/views/controls/menu/menu_runner_impl_cocoa.mm index 2f2e6e17..c51447a 100644 --- a/ui/views/controls/menu/menu_runner_impl_cocoa.mm +++ b/ui/views/controls/menu/menu_runner_impl_cocoa.mm
@@ -4,17 +4,178 @@ #import "ui/views/controls/menu/menu_runner_impl_cocoa.h" +#include "base/mac/mac_util.h" #import "base/message_loop/message_pump_mac.h" +#import "skia/ext/skia_utils_mac.h" #import "ui/base/cocoa/cocoa_base_utils.h" #import "ui/base/cocoa/menu_controller.h" +#include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/models/menu_model.h" #include "ui/events/base_event_utils.h" #include "ui/events/event_utils.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/mac/coordinate_conversion.h" +#include "ui/gfx/platform_font_mac.h" +#include "ui/native_theme/native_theme.h" +#include "ui/strings/grit/ui_strings.h" +#include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_runner_impl_adapter.h" +#include "ui/views/views_features.h" #include "ui/views/widget/widget.h" +namespace { + +NSImage* NewTagImage() { + static NSImage* new_tag = []() { + // 1. Make the attributed string. + + NSString* badge_text = l10n_util::GetNSString(IDS_MENU_ITEM_NEW_BADGE); + + // The preferred font is slightly smaller and slightly more bold than the + // menu font. The size change is required to make it look correct in the + // badge; we add a small degree of bold to prevent color smearing/blurring + // due to font smoothing. This ensures readability on all platforms and in + // both light and dark modes. + gfx::Font badge_font = gfx::Font( + new gfx::PlatformFontMac(gfx::PlatformFontMac::SystemFontType::kMenu)); + badge_font = + badge_font.Derive(views::MenuConfig::kNewBadgeFontSizeAdjustment, + gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM); + + NSColor* badge_text_color = skia::SkColorToSRGBNSColor( + ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor( + ui::NativeTheme::kColorId_TextOnProminentButtonColor)); + + NSDictionary* badge_attrs = @{ + NSFontAttributeName : badge_font.GetNativeFont(), + NSForegroundColorAttributeName : badge_text_color, + }; + + NSMutableAttributedString* badge_attr_string = + [[NSMutableAttributedString alloc] initWithString:badge_text + attributes:badge_attrs]; + + if (base::mac::IsOS10_10()) { + // The system font for 10.10 is Helvetica Neue, and when used for this + // "new tag" the letters look cramped. Track it out so that there's some + // breathing room. There is no tracking attribute, so instead add kerning + // to all but the last character. + [badge_attr_string + addAttribute:NSKernAttributeName + value:@0.4 + range:NSMakeRange(0, [badge_attr_string length] - 1)]; + } + + // 2. Calculate the size required. + + NSSize badge_size = [badge_attr_string size]; + badge_size.width = trunc(badge_size.width); + badge_size.height = trunc(badge_size.height); + + badge_size.width += 2 * views::MenuConfig::kNewBadgeInternalPadding + + 2 * views::MenuConfig::kNewBadgeHorizontalMargin; + badge_size.height += views::MenuConfig::kNewBadgeInternalPaddingTopMac; + + // 3. Craft the image. + + return [[NSImage + imageWithSize:badge_size + flipped:NO + drawingHandler:^(NSRect dest_rect) { + NSRect badge_frame = NSInsetRect( + dest_rect, views::MenuConfig::kNewBadgeHorizontalMargin, 0); + NSBezierPath* rounded_badge_rect = [NSBezierPath + bezierPathWithRoundedRect:badge_frame + xRadius:views::MenuConfig::kNewBadgeCornerRadius + yRadius:views::MenuConfig:: + kNewBadgeCornerRadius]; + NSColor* badge_color = skia::SkColorToSRGBNSColor( + ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor( + ui::NativeTheme::kColorId_ProminentButtonColor)); + [badge_color set]; + [rounded_badge_rect fill]; + + NSPoint badge_text_location = NSMakePoint( + NSMinX(badge_frame) + views::MenuConfig::kNewBadgeInternalPadding, + NSMinY(badge_frame) + + views::MenuConfig::kNewBadgeInternalPaddingTopMac); + [badge_attr_string drawAtPoint:badge_text_location]; + + return YES; + }] retain]; + }(); + + return new_tag; +} + +} // namespace + +@interface NewTagAttachmentCell : NSTextAttachmentCell +@end + +@implementation NewTagAttachmentCell + +- (instancetype)init { + if (self = [super init]) { + self.image = NewTagImage(); + } + return self; +} + +- (NSPoint)cellBaselineOffset { + return NSMakePoint(0, views::MenuConfig::kNewBadgeBaslineOffsetMac); +} + +- (NSSize)cellSize { + return [self.image size]; +} + +@end + +@interface MenuControllerDelegate : NSObject <MenuControllerCocoaDelegate> +@end + +@implementation MenuControllerDelegate + +- (void)controllerWillAddItem:(NSMenuItem*)menuItem + fromModel:(ui::MenuModel*)model + atIndex:(NSInteger)index { + static const bool feature_enabled = + base::FeatureList::IsEnabled(views::features::kEnableNewBadgeOnMenuItems); + if (!feature_enabled || !model->IsNewFeatureAt(index)) + return; + + // TODO(avi): When moving to 10.11 as the minimum macOS, switch to using + // NSTextAttachment's |image| and |bounds| properties and avoid the whole + // NSTextAttachmentCell subclassing mishegas. + base::scoped_nsobject<NSTextAttachment> attachment( + [[NSTextAttachment alloc] init]); + attachment.get().attachmentCell = + [[[NewTagAttachmentCell alloc] init] autorelease]; + + // Starting in 10.13, if an attributed string is set as a menu item title, and + // NSFontAttributeName is not specified for it, it is automatically rendered + // in a font matching other menu items. Prior to then, a menu item with no + // specified font is rendered in Helvetica. In addition, while the + // documentation says that -[NSFont menuFontOfSize:0] gives the standard menu + // font, that doesn't actually match up. Therefore, specify a font that + // visually matches. + NSDictionary* attrs = nil; + if (base::mac::IsAtMostOS10_12()) + attrs = @{NSFontAttributeName : [NSFont menuFontOfSize:14]}; + + base::scoped_nsobject<NSMutableAttributedString> attrTitle( + [[NSMutableAttributedString alloc] initWithString:menuItem.title + attributes:attrs]); + [attrTitle + appendAttributedString:[NSAttributedString + attributedStringWithAttachment:attachment]]; + + menuItem.attributedTitle = attrTitle; +} + +@end + namespace views { namespace internal { namespace { @@ -124,7 +285,7 @@ int32_t run_types, base::RepeatingClosure on_menu_closed_callback) { if ((run_types & MenuRunner::CONTEXT_MENU) && - !(run_types & (MenuRunner::IS_NESTED | MenuRunner::FORCE_VIEWS))) { + !(run_types & (MenuRunner::IS_NESTED))) { return new MenuRunnerImplCocoa(menu_model, std::move(on_menu_closed_callback)); } @@ -139,8 +300,11 @@ delete_after_run_(false), closing_event_time_(base::TimeTicks()), on_menu_closed_callback_(std::move(on_menu_closed_callback)) { - menu_controller_.reset([[MenuControllerCocoa alloc] initWithModel:menu - useWithPopUpButtonCell:NO]); + menu_delegate_.reset([[MenuControllerDelegate alloc] init]); + menu_controller_.reset([[MenuControllerCocoa alloc] + initWithModel:menu + delegate:menu_delegate_.get() + useWithPopUpButtonCell:NO]); } bool MenuRunnerImplCocoa::IsRunning() const {
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index bfa802b..087876d 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -1888,8 +1888,7 @@ const gfx::Range& range) { base::UmaHistogramEnumeration("InputMethod.Assistive.Autocorrect.Count", TextInputClient::SubClass::kTextField); - model_->SetAutocorrectRange(autocorrect_text, range); - return true; + return model_->SetAutocorrectRange(autocorrect_text, range); } #endif
diff --git a/ui/views/controls/textfield/textfield_model.cc b/ui/views/controls/textfield/textfield_model.cc index 75801b0..24514cb 100644 --- a/ui/views/controls/textfield/textfield_model.cc +++ b/ui/views/controls/textfield/textfield_model.cc
@@ -756,26 +756,38 @@ #if defined(OS_CHROMEOS) bool TextfieldModel::SetAutocorrectRange(const base::string16& autocorrect_text, const gfx::Range& autocorrect_range) { - // TODO(crbug.com/1108170): Use original text to create the Undo window. - original_text_ = render_text_->GetTextFromRange(autocorrect_range); - uint32_t autocorrect_range_start = autocorrect_range.start(); + // Clears autocorrect range if text is empty. + if (autocorrect_text.empty() || autocorrect_range == gfx::Range()) { + autocorrect_range_ = gfx::Range(); + original_text_ = base::EmptyString16(); + } else { + // TODO(crbug.com/1108170): Use original text to create the Undo window. + base::string16 current_text = + render_text_->GetTextFromRange(autocorrect_range); + // current text should always be valid. + if (current_text.empty()) + return false; - // TODO(crbug.com/1108170): Update the autocorrect range when the composition - // changes for ChromeOS. The current autocorrect_range_ does not get updated - // when composition changes or more text is committed. - autocorrect_range_ = - gfx::Range(autocorrect_range_start, - autocorrect_text.length() + autocorrect_range_start); + original_text_ = std::move(current_text); + uint32_t autocorrect_range_start = autocorrect_range.start(); - base::string16 before_text = - render_text_->GetTextFromRange(gfx::Range(0, autocorrect_range.start())); - base::string16 after_text = render_text_->GetTextFromRange(gfx::Range( - autocorrect_range.end(), - std::max(autocorrect_range.end(), - static_cast<uint32_t>(render_text_->text().length())))); - base::string16 new_text = - before_text.append(autocorrect_text).append(after_text); - SetRenderTextText(new_text); + // TODO(crbug.com/1108170): Update the autocorrect range when the + // composition changes for ChromeOS. The current autocorrect_range_ does not + // get updated when composition changes or more text is committed. + autocorrect_range_ = + gfx::Range(autocorrect_range_start, + autocorrect_text.length() + autocorrect_range_start); + + base::string16 before_text = render_text_->GetTextFromRange( + gfx::Range(0, autocorrect_range.start())); + base::string16 after_text = render_text_->GetTextFromRange(gfx::Range( + autocorrect_range.end(), + std::max(autocorrect_range.end(), + static_cast<uint32_t>(render_text_->text().length())))); + base::string16 new_text = + before_text.append(autocorrect_text).append(after_text); + SetRenderTextText(new_text); + } return true; } #endif
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index 9a092d5..74e95ff 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -3075,20 +3075,6 @@ } #if defined(OS_CHROMEOS) -TEST_F(TextfieldTest, SetAutocorrectRangeTextWithNoInitalText) { - InitTextfield(); - ui::TextInputClient* client = textfield_; - client->SetAutocorrectRange(ASCIIToUTF16("text replacement"), - gfx::Range(0, 0)); - - gfx::Range autocorrect_range = client->GetAutocorrectRange(); - EXPECT_EQ(autocorrect_range, gfx::Range(0, 16)); - - base::string16 text; - client->GetTextFromRange(gfx::Range(0, 16), &text); - EXPECT_EQ(text, UTF8ToUTF16("text replacement")); -} - TEST_F(TextfieldTest, SetAutocorrectRangeText) { InitTextfield(); ui::TextInputClient* client = textfield_; @@ -3122,6 +3108,62 @@ EXPECT_EQ(text, UTF8ToUTF16("Initial text replacement")); } +TEST_F(TextfieldTest, DoesNotSetAutocorrectRangeWhenRangeGivenIsInvalid) { + InitTextfield(); + ui::TextInputClient* client = textfield_; + + ui::CompositionText composition; + composition.text = UTF8ToUTF16("Initial"); + client->SetCompositionText(composition); + + EXPECT_FALSE(client->SetAutocorrectRange(ASCIIToUTF16("text replacement"), + gfx::Range(8, 11))); + EXPECT_EQ(gfx::Range(0, 0), client->GetAutocorrectRange()); + gfx::Range range; + client->GetTextRange(&range); + base::string16 text; + client->GetTextFromRange(range, &text); + EXPECT_EQ(composition.text, text); +} + +TEST_F(TextfieldTest, + ClearsAutocorrectRangeWhenSetAutocorrectRangeWithEmptyText) { + InitTextfield(); + ui::TextInputClient* client = textfield_; + + ui::CompositionText composition; + composition.text = UTF8ToUTF16("Initial"); + client->SetCompositionText(composition); + + EXPECT_TRUE( + client->SetAutocorrectRange(base::EmptyString16(), gfx::Range(0, 2))); + EXPECT_EQ(gfx::Range(0, 0), client->GetAutocorrectRange()); + gfx::Range range; + client->GetTextRange(&range); + base::string16 text; + client->GetTextFromRange(range, &text); + EXPECT_EQ(composition.text, text); +} + +TEST_F(TextfieldTest, + ClearsAutocorrectRangeWhenSetAutocorrectRangeWithEmptyRange) { + InitTextfield(); + ui::TextInputClient* client = textfield_; + + ui::CompositionText composition; + composition.text = UTF8ToUTF16("Initial"); + client->SetCompositionText(composition); + + EXPECT_TRUE( + client->SetAutocorrectRange(UTF8ToUTF16("Test"), gfx::Range(0, 0))); + EXPECT_EQ(gfx::Range(0, 0), client->GetAutocorrectRange()); + gfx::Range range; + client->GetTextRange(&range); + base::string16 text; + client->GetTextFromRange(range, &text); + EXPECT_EQ(composition.text, text); +} + TEST_F(TextfieldTest, GetAutocorrectCharacterBoundsTest) { InitTextfield(); ui::TextInputClient* client = textfield_;
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h index 413f86b..e2420a3a 100644 --- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h +++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h
@@ -15,8 +15,8 @@ #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/gfx/geometry/point_f.h" #include "ui/gfx/native_widget_types.h" -#include "ui/platform_window/handlers/wm_drag_handler.h" -#include "ui/platform_window/handlers/wm_drop_handler.h" +#include "ui/platform_window/wm/wm_drag_handler.h" +#include "ui/platform_window/wm/wm_drop_handler.h" #include "ui/views/views_export.h" namespace aura {
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc index 522d3c5..90c68e1d 100644 --- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc +++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc
@@ -14,9 +14,9 @@ #include "ui/aura/window_tree_host.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h" #include "ui/base/dragdrop/os_exchange_data.h" -#include "ui/platform_window/handlers/wm_drag_handler.h" -#include "ui/platform_window/handlers/wm_drop_handler.h" #include "ui/platform_window/platform_window.h" +#include "ui/platform_window/wm/wm_drag_handler.h" +#include "ui/platform_window/wm/wm_drop_handler.h" #include "ui/views/test/views_test_base.h" #include "ui/views/views_delegate.h" #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc index d8ee9bd..0bdc147 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc
@@ -19,8 +19,8 @@ #include "ui/display/screen.h" #include "ui/events/event.h" #include "ui/platform_window/extensions/x11_extension.h" -#include "ui/platform_window/handlers/wm_move_resize_handler.h" #include "ui/platform_window/platform_window_init_properties.h" +#include "ui/platform_window/wm/wm_move_resize_handler.h" #include "ui/views/linux_ui/linux_ui.h" #include "ui/views/views_delegate.h" #include "ui/views/widget/desktop_aura/window_event_filter_linux.h"
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux_interactive_uitest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux_interactive_uitest.cc index 1fc52c6..1a917b6 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux_interactive_uitest.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux_interactive_uitest.cc
@@ -7,8 +7,8 @@ #include "ui/aura/client/aura_constants.h" #include "ui/aura/window_tree_host_platform.h" #include "ui/base/hit_test.h" -#include "ui/platform_window/handlers/wm_move_resize_handler.h" #include "ui/platform_window/platform_window.h" +#include "ui/platform_window/wm/wm_move_resize_handler.h" #include "ui/views/test/widget_test.h" #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" #include "ui/views/widget/desktop_aura/window_event_filter_linux.h"
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc index c5737541..0013596f 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -21,9 +21,9 @@ #include "ui/display/screen.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/platform_window/extensions/workspace_extension.h" -#include "ui/platform_window/handlers/wm_move_loop_handler.h" #include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_init_properties.h" +#include "ui/platform_window/wm/wm_move_loop_handler.h" #include "ui/views/corewm/tooltip_aura.h" #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.h" #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
diff --git a/ui/views/widget/desktop_aura/window_event_filter_linux.cc b/ui/views/widget/desktop_aura/window_event_filter_linux.cc index 90557d2..439142a 100644 --- a/ui/views/widget/desktop_aura/window_event_filter_linux.cc +++ b/ui/views/widget/desktop_aura/window_event_filter_linux.cc
@@ -14,7 +14,7 @@ #include "ui/display/screen.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" -#include "ui/platform_window/handlers/wm_move_resize_handler.h" +#include "ui/platform_window/wm/wm_move_resize_handler.h" #include "ui/views/linux_ui/linux_ui.h" #include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h" #include "ui/views/widget/native_widget_aura.h"
diff --git a/ui/views/widget/native_widget_mac_unittest.mm b/ui/views/widget/native_widget_mac_unittest.mm index 948034f..5e21b84 100644 --- a/ui/views/widget/native_widget_mac_unittest.mm +++ b/ui/views/widget/native_widget_mac_unittest.mm
@@ -1937,98 +1937,6 @@ widget->CloseNow(); } -// Test that NativeWidgetMac::SchedulePaintInRect correctly passes the dirtyRect -// parameter to BridgedContentView::drawRect, for a titled window (window with a -// toolbar). -TEST_F(NativeWidgetMacTest, SchedulePaintInRect_Titled) { - Widget* widget = CreateTopLevelPlatformWidget(); - - gfx::Rect screen_rect(50, 50, 100, 100); - widget->SetBounds(screen_rect); - - // Setup the mock content view for the NSWindow, so that we can intercept - // drawRect. - NSWindow* window = widget->GetNativeWindow().GetNativeNSWindow(); - base::scoped_nsobject<MockBridgedView> mock_bridged_view( - [[MockBridgedView alloc] init]); - // Reset drawRect count. - [mock_bridged_view setDrawRectCount:0]; - [window setContentView:mock_bridged_view]; - - // Ensure the initial draw of the window is done. - while ([mock_bridged_view drawRectCount] == 0) - base::RunLoop().RunUntilIdle(); - - // Add a dummy view to the widget. This will cause SchedulePaint to be called - // on the dummy view. - View* dummy_view = new View(); - gfx::Rect dummy_bounds(25, 30, 10, 15); - dummy_view->SetBoundsRect(dummy_bounds); - // Reset drawRect count. - [mock_bridged_view setDrawRectCount:0]; - widget->GetContentsView()->AddChildView(dummy_view); - - // SchedulePaint is asyncronous. Wait for drawRect: to be called. - while ([mock_bridged_view drawRectCount] == 0) - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(1u, [mock_bridged_view drawRectCount]); - int client_area_height = widget->GetClientAreaBoundsInScreen().height(); - // These are expected dummy_view bounds in AppKit coordinate system. The y - // coordinate of rect origin is calculated as: - // client_area_height - 30 (dummy_view's y coordinate) - 15 (dummy view's - // height). - gfx::Rect expected_appkit_bounds(25, client_area_height - 45, 10, 15); - EXPECT_NSEQ(expected_appkit_bounds.ToCGRect(), - [mock_bridged_view lastDirtyRect]); - widget->CloseNow(); -} - -// Test that NativeWidgetMac::SchedulePaintInRect correctly passes the dirtyRect -// parameter to BridgedContentView::drawRect, for a borderless window. -TEST_F(NativeWidgetMacTest, SchedulePaintInRect_Borderless) { - Widget* widget = CreateTopLevelFramelessPlatformWidget(); - - gfx::Rect screen_rect(50, 50, 100, 100); - widget->SetBounds(screen_rect); - - // Setup the mock content view for the NSWindow, so that we can intercept - // drawRect. - NSWindow* window = widget->GetNativeWindow().GetNativeNSWindow(); - base::scoped_nsobject<MockBridgedView> mock_bridged_view( - [[MockBridgedView alloc] init]); - // Reset drawRect count. - [mock_bridged_view setDrawRectCount:0]; - [window setContentView:mock_bridged_view]; - - // Ensure the initial draw of the window is done. - while ([mock_bridged_view drawRectCount] == 0) - base::RunLoop().RunUntilIdle(); - - // Add a dummy view to the widget. This will cause SchedulePaint to be called - // on the dummy view. - View* dummy_view = new View(); - gfx::Rect dummy_bounds(25, 30, 10, 15); - dummy_view->SetBoundsRect(dummy_bounds); - // Reset drawRect count. - [mock_bridged_view setDrawRectCount:0]; - widget->GetRootView()->AddChildView(dummy_view); - - // SchedulePaint is asyncronous. Wait for drawRect: to be called. - while ([mock_bridged_view drawRectCount] == 0) - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(1u, [mock_bridged_view drawRectCount]); - // These are expected dummy_view bounds in AppKit coordinate system. The y - // coordinate of rect origin is calculated as: - // 100(client area height) - 30 (dummy_view's y coordinate) - 15 (dummy view's - // height). - gfx::Rect expected_appkit_bounds(25, 55, 10, 15); - EXPECT_NSEQ(expected_appkit_bounds.ToCGRect(), - [mock_bridged_view lastDirtyRect]); - widget->CloseNow(); -} - // Ensure traversing NSView focus correctly updates the views::FocusManager. TEST_F(NativeWidgetMacTest, ChangeFocusOnChangeFirstResponder) { Widget* widget = CreateTopLevelPlatformWidget();
diff --git a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn index b32ccb8..7cb2726 100644 --- a/ui/webui/resources/cr_components/chromeos/network/BUILD.gn +++ b/ui/webui/resources/cr_components/chromeos/network/BUILD.gn
@@ -252,7 +252,7 @@ # ":network_apnlist.m", # ":network_choose_mobile.m", # ":network_config.m", - # ":network_config_element_behavior.m", + ":network_config_element_behavior.m", # ":network_config_input.m", # ":network_config_select.m", # ":network_config_toggle.m", @@ -333,9 +333,6 @@ js_library("network_config_element_behavior.m") { sources = [ "$root_gen_dir/ui/webui/resources/cr_components/chromeos/network/network_config_element_behavior.m.js" ] - deps = [ - # TODO: Fill those in. - ] extra_deps = [ ":modulize" ] }
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_config_element_behavior.js b/ui/webui/resources/cr_components/chromeos/network/network_config_element_behavior.js index c341b01..95d24a2 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_config_element_behavior.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_config_element_behavior.js
@@ -7,7 +7,7 @@ */ /** @polymerBehavior */ -const NetworkConfigElementBehavior = { +/* #export */ const NetworkConfigElementBehavior = { properties: { disabled: { type: Boolean,
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_config_toggle.html b/ui/webui/resources/cr_components/chromeos/network/network_config_toggle.html index d98ca86..2fc37be 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_config_toggle.html +++ b/ui/webui/resources/cr_components/chromeos/network/network_config_toggle.html
@@ -10,6 +10,12 @@ <dom-module id="network-config-toggle"> <template> <style include="network-shared"> + :host { + cursor: pointer; + } + :host([disabled]) { + cursor: initial; + } cr-policy-network-indicator-mojo { --cr-tooltip-icon-margin-start: var(--cr-controlled-by-spacing); } @@ -21,7 +27,7 @@ } </style> - <div class="property-box" actionable> + <div class="property-box"> <div class="start"> <div aria-hidden="true">[[label]]</div> <div id="sub-label" class="cr-secondary-text" aria-hidden="true">
diff --git a/ui/webui/resources/cr_components/cr_components_resources_v3.grdp b/ui/webui/resources/cr_components/cr_components_resources_v3.grdp index e7268f2..681cdd6 100644 --- a/ui/webui/resources/cr_components/cr_components_resources_v3.grdp +++ b/ui/webui/resources/cr_components/cr_components_resources_v3.grdp
@@ -30,6 +30,10 @@ file="${root_gen_dir}/ui/webui/resources/cr_components/chromeos/network/cr_policy_network_indicator_mojo.m.js" use_base_dir="false" type="BINDATA" /> + <include name="IDR_WEBUI_CHROMEOS_NETWORK_CONFIG_ELEMENT_BEHAVIOR_M_JS" + file="${root_gen_dir}/ui/webui/resources/cr_components/chromeos/network/network_config_element_behavior.m.js" + use_base_dir="false" + type="BINDATA" /> <include name="IDR_WEBUI_CHROMEOS_NETWORK_LISTENER_BEHAVIOR_M_JS" file="${root_gen_dir}/ui/webui/resources/cr_components/chromeos/network/network_listener_behavior.m.js" use_base_dir="false"
diff --git a/ui/webui/resources/cr_elements/shared_vars_css.html b/ui/webui/resources/cr_elements/shared_vars_css.html index a3fb220..6d0cf07b 100644 --- a/ui/webui/resources/cr_elements/shared_vars_css.html +++ b/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -29,6 +29,9 @@ --google-red-600-rgb: 217, 48, 37; /* #d93025 */ --google-red-600: rgb(var(--google-red-600-rgb)); + --google-yellow-50-rgb: 254, 247, 224; /* #fef7e0 */ + --google-yellow-50: rgb(var(--google-yellow-50-rgb)); + /* -refresh differentiate from polymer's color.html. */ --google-blue-refresh-100-rgb: 210, 227, 252; /* #d2e3fc */ --google-blue-refresh-100: rgb(var(--google-blue-refresh-100-rgb));
diff --git a/weblayer/BUILD.gn b/weblayer/BUILD.gn index c9ab2ff..c7ce66c 100644 --- a/weblayer/BUILD.gn +++ b/weblayer/BUILD.gn
@@ -212,6 +212,8 @@ "browser/no_state_prefetch/prerender_manager_factory.h", "browser/no_state_prefetch/prerender_processor_impl_delegate_impl.cc", "browser/no_state_prefetch/prerender_processor_impl_delegate_impl.h", + "browser/no_state_prefetch/prerender_tab_helper.cc", + "browser/no_state_prefetch/prerender_tab_helper.h", "browser/page_load_metrics_initialize.cc", "browser/page_load_metrics_initialize.h", "browser/page_specific_content_settings_delegate.cc",
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java index 599fd0d..71788e1 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java
@@ -25,12 +25,6 @@ public final class ChildProcessServiceImpl extends IChildProcessService.Stub { private ChildProcessService mService; - // This should only be called in M80 or below. - @UsedByReflection("WebLayer") - public static IBinder create(Service service, Context appContext) { - return create(service, appContext, WebLayerImpl.createRemoteContextV80(appContext)); - } - @UsedByReflection("WebLayer") public static IBinder create(Service service, Context appContext, Context remoteContext) { ClassLoaderContextWrapperFactory.setResourceOverrideContext(remoteContext);
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java index 78be271..a2931a0 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
@@ -123,12 +123,6 @@ WebLayerImpl() {} @Override - public void loadAsyncV80( - IObjectWrapper appContextWrapper, IObjectWrapper loadedCallbackWrapper) { - loadAsync(appContextWrapper, null, loadedCallbackWrapper); - } - - @Override public void loadAsync(IObjectWrapper appContextWrapper, IObjectWrapper remoteContextWrapper, IObjectWrapper loadedCallbackWrapper) { StrictModeWorkaround.apply(); @@ -153,11 +147,6 @@ } @Override - public void loadSyncV80(IObjectWrapper appContextWrapper) { - loadSync(appContextWrapper, null); - } - - @Override public void loadSync(IObjectWrapper appContextWrapper, IObjectWrapper remoteContextWrapper) { StrictModeWorkaround.apply(); init(appContextWrapper, remoteContextWrapper); @@ -305,12 +294,6 @@ } @Override - public ICrashReporterController getCrashReporterControllerV80(IObjectWrapper appContext) { - StrictModeWorkaround.apply(); - return getCrashReporterController(appContext, null); - } - - @Override public ICrashReporterController getCrashReporterController( IObjectWrapper appContext, IObjectWrapper remoteContext) { StrictModeWorkaround.apply(); @@ -372,20 +355,6 @@ WebLayerImplJni.get().registerExternalExperimentIDs(trialName, experimentIDs); } - /** - * Creates a remote context. This should only be used for backwards compatibility when the - * client was not sending the remote context. - */ - public static Context createRemoteContextV80(Context appContext) { - try { - return appContext.createPackageContext( - WebViewFactory.getLoadedPackageInfo().packageName, - Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE); - } catch (PackageManager.NameNotFoundException e) { - throw new AndroidRuntimeException(e); - } - } - public static Intent createIntent() { if (sClient == null) { throw new IllegalStateException("WebLayer should have been initialized already."); @@ -482,9 +451,7 @@ } Context appContext = ObjectWrapper.unwrap(appContextWrapper, Context.class); Context remoteContext = ObjectWrapper.unwrap(remoteContextWrapper, Context.class); - if (remoteContext == null) { - remoteContext = createRemoteContextV80(appContext); - } + assert remoteContext != null; ClassLoaderContextWrapperFactory.setResourceOverrideContext(remoteContext); // Wrap the app context so that it can be used to load WebLayer implementation classes. appContext = ClassLoaderContextWrapperFactory.get(appContext);
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl index 7c8af14..965b11e 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl +++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl
@@ -16,12 +16,8 @@ import org.chromium.weblayer_private.interfaces.IWebLayerClient; interface IWebLayer { - // Deprecated, use loadAsync(). - void loadAsyncV80(in IObjectWrapper appContext, - in IObjectWrapper loadedCallback) = 1; - - // Deprecated, use loadSync(). - void loadSyncV80(in IObjectWrapper appContext) = 2; + // ID 1 was loadAsyncV80 and was removed in M86. + // ID 2 was loadSyncV80 and was removed in M86. // Creates the WebLayer counterpart to a BrowserFragment - a BrowserFragmentImpl // @@ -41,9 +37,7 @@ // Returns whether or not the DevTools remote debugging server is enabled. boolean isRemoteDebuggingEnabled() = 6; - // Deprecated, use getCrashReporterController(). - ICrashReporterController getCrashReporterControllerV80( - in IObjectWrapper appContext) = 7; + // ID 7 was getCrashReporterControllerV80 and was removed in M86. // Initializes WebLayer and starts loading. //
diff --git a/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc b/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc new file mode 100644 index 0000000..3b2d204 --- /dev/null +++ b/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc
@@ -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. + +#include "weblayer/browser/no_state_prefetch/prerender_tab_helper.h" + +#include "components/prerender/browser/prerender_manager.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/web_contents.h" +#include "weblayer/browser/no_state_prefetch/prerender_manager_factory.h" + +namespace weblayer { + +PrerenderTabHelper::PrerenderTabHelper(content::WebContents* web_contents) + : content::WebContentsObserver(web_contents) {} + +PrerenderTabHelper::~PrerenderTabHelper() = default; + +void PrerenderTabHelper::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (!navigation_handle->IsInMainFrame() || + !navigation_handle->HasCommitted() || navigation_handle->IsErrorPage()) { + return; + } + + prerender::PrerenderManager* prerender_manager = + PrerenderManagerFactory::GetForBrowserContext( + web_contents()->GetBrowserContext()); + + if (prerender_manager && + !prerender_manager->IsWebContentsPrerendering(web_contents(), nullptr)) + prerender_manager->RecordNavigation(navigation_handle->GetURL()); +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(PrerenderTabHelper) + +} // namespace weblayer \ No newline at end of file
diff --git a/weblayer/browser/no_state_prefetch/prerender_tab_helper.h b/weblayer/browser/no_state_prefetch/prerender_tab_helper.h new file mode 100644 index 0000000..996abda8 --- /dev/null +++ b/weblayer/browser/no_state_prefetch/prerender_tab_helper.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 WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_TAB_HELPER_H_ +#define WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_TAB_HELPER_H_ + +#include "base/macros.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace content { +class WebContents; +} + +namespace prerender { +class PrerenderManager; +} + +namespace weblayer { + +// Notifies the prerender::PrerenderManager with the events happening in the +// prerendered WebContents. +class PrerenderTabHelper + : public content::WebContentsObserver, + public content::WebContentsUserData<PrerenderTabHelper> { + public: + ~PrerenderTabHelper() override; + PrerenderTabHelper(const PrerenderTabHelper&) = delete; + PrerenderTabHelper& operator=(const PrerenderTabHelper&) = delete; + + // content::WebContentsObserver implementation. + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + + private: + explicit PrerenderTabHelper(content::WebContents* web_contents); + friend class content::WebContentsUserData<PrerenderTabHelper>; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); +}; + +} // namespace weblayer + +#endif // WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_TAB_HELPER_H_ \ No newline at end of file
diff --git a/weblayer/browser/tab_impl.cc b/weblayer/browser/tab_impl.cc index 535ca4c..49497db9 100644 --- a/weblayer/browser/tab_impl.cc +++ b/weblayer/browser/tab_impl.cc
@@ -62,6 +62,7 @@ #include "weblayer/browser/infobar_service.h" #include "weblayer/browser/js_communication/web_message_host_factory_wrapper.h" #include "weblayer/browser/navigation_controller_impl.h" +#include "weblayer/browser/no_state_prefetch/prerender_tab_helper.h" #include "weblayer/browser/page_load_metrics_initialize.h" #include "weblayer/browser/page_specific_content_settings_delegate.h" #include "weblayer/browser/password_manager_driver_factory.h" @@ -340,6 +341,9 @@ base::BindRepeating(&OpenCaptivePortalLoginTabInWebContents, web_contents_.get())); #endif + + // PrerenderTabHelper adds a WebContentsObserver. + PrerenderTabHelper::CreateForWebContents(web_contents_.get()); } TabImpl::~TabImpl() {
diff --git a/weblayer/public/java/org/chromium/weblayer/ChildProcessService.java b/weblayer/public/java/org/chromium/weblayer/ChildProcessService.java index 2103c19a..eab6bf02 100644 --- a/weblayer/public/java/org/chromium/weblayer/ChildProcessService.java +++ b/weblayer/public/java/org/chromium/weblayer/ChildProcessService.java
@@ -30,19 +30,11 @@ WebLayer.disableWebViewCompatibilityMode(); Context appContext = getApplicationContext(); Context remoteContext = WebLayer.getOrCreateRemoteContext(appContext); - if (WebLayer.getSupportedMajorVersion(appContext) < 81) { - mImpl = IChildProcessService.Stub.asInterface( - (IBinder) remoteContext.getClassLoader() - .loadClass("org.chromium.weblayer_private.ChildProcessServiceImpl") - .getMethod("create", Service.class, Context.class) - .invoke(null, this, appContext)); - } else { - mImpl = IChildProcessService.Stub.asInterface( - (IBinder) remoteContext.getClassLoader() - .loadClass("org.chromium.weblayer_private.ChildProcessServiceImpl") - .getMethod("create", Service.class, Context.class, Context.class) - .invoke(null, this, appContext, remoteContext)); - } + mImpl = IChildProcessService.Stub.asInterface( + (IBinder) remoteContext.getClassLoader() + .loadClass("org.chromium.weblayer_private.ChildProcessServiceImpl") + .getMethod("create", Service.class, Context.class, Context.class) + .invoke(null, this, appContext, remoteContext)); mImpl.onCreate(); } catch (Exception e) { throw new APICallException(e);
diff --git a/weblayer/public/java/org/chromium/weblayer/CrashReporterController.java b/weblayer/public/java/org/chromium/weblayer/CrashReporterController.java index f353173..2427baea 100644 --- a/weblayer/public/java/org/chromium/weblayer/CrashReporterController.java +++ b/weblayer/public/java/org/chromium/weblayer/CrashReporterController.java
@@ -135,15 +135,10 @@ return this; } try { - if (WebLayer.getSupportedMajorVersion(appContext) < 81) { - mImpl = WebLayer.getIWebLayer(appContext) - .getCrashReporterControllerV80(ObjectWrapper.wrap(appContext)); - } else { - mImpl = WebLayer.getIWebLayer(appContext) - .getCrashReporterController(ObjectWrapper.wrap(appContext), - ObjectWrapper.wrap( - WebLayer.getOrCreateRemoteContext(appContext))); - } + mImpl = WebLayer.getIWebLayer(appContext) + .getCrashReporterController(ObjectWrapper.wrap(appContext), + ObjectWrapper.wrap( + WebLayer.getOrCreateRemoteContext(appContext))); mImpl.setClient(new CrashReporterControllerClientImpl()); } catch (Exception e) { throw new APICallException(e);
diff --git a/weblayer/public/java/org/chromium/weblayer/WebLayer.java b/weblayer/public/java/org/chromium/weblayer/WebLayer.java index aa06e21e..65a10076 100644 --- a/weblayer/public/java/org/chromium/weblayer/WebLayer.java +++ b/weblayer/public/java/org/chromium/weblayer/WebLayer.java
@@ -306,20 +306,11 @@ return; } try { - if (getMajorVersion() < 81) { - getIWebLayer(appContext) - .loadAsyncV80(ObjectWrapper.wrap(appContext), - ObjectWrapper.wrap((ValueCallback<Boolean>) result -> { - onWebLayerReady(); - })); - } else { - getIWebLayer(appContext) - .loadAsync(ObjectWrapper.wrap(appContext), - ObjectWrapper.wrap(getOrCreateRemoteContext(appContext)), - ObjectWrapper.wrap((ValueCallback<Boolean>) result -> { - onWebLayerReady(); - })); - } + getIWebLayer(appContext) + .loadAsync(ObjectWrapper.wrap(appContext), + ObjectWrapper.wrap(getOrCreateRemoteContext(appContext)), + ObjectWrapper.wrap( + (ValueCallback<Boolean>) result -> { onWebLayerReady(); })); } catch (Exception e) { throw new APICallException(e); } @@ -335,13 +326,9 @@ return null; } try { - if (getMajorVersion() < 81) { - getIWebLayer(appContext).loadSyncV80(ObjectWrapper.wrap(appContext)); - } else { - getIWebLayer(appContext) - .loadSync(ObjectWrapper.wrap(appContext), - ObjectWrapper.wrap(getOrCreateRemoteContext(appContext))); - } + getIWebLayer(appContext) + .loadSync(ObjectWrapper.wrap(appContext), + ObjectWrapper.wrap(getOrCreateRemoteContext(appContext))); onWebLayerReady(); return mWebLayer; } catch (Exception e) {
diff --git a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java index 4d38b9c3..81bd6f5 100644 --- a/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java +++ b/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
@@ -4,6 +4,8 @@ package org.chromium.weblayer.shell; +import static android.util.Patterns.WEB_URL; + import android.app.Activity; import android.content.ClipData; import android.content.ClipboardManager; @@ -19,7 +21,6 @@ import android.view.MenuItem; import android.view.View; import android.view.WindowManager; -import android.webkit.URLUtil; import android.widget.EditText; import android.widget.ImageButton; import android.widget.PopupMenu; @@ -356,11 +357,7 @@ if (getCurrentDisplayUrl() != null) { return; } - String startupUrl = getUrlFromIntent(getIntent()); - if (TextUtils.isEmpty(startupUrl) || !URLUtil.isValidUrl(startupUrl)) { - startupUrl = "https://google.com"; - } - loadUrl(startupUrl); + loadUrl(getUrlFromIntent(getIntent())); } /* Returns the Url for the current tab as a String, or null if there is no @@ -515,8 +512,21 @@ return fragment; } - public void loadUrl(String url) { - mBrowser.getActiveTab().getNavigationController().navigate(Uri.parse(sanitizeUrl(url))); + public void loadUrl(String input) { + String sanitized = sanitizeUrl(input); + + Uri uri; + if (WEB_URL.matcher(sanitized).matches()) { + uri = Uri.parse(sanitized); + } else if (TextUtils.isEmpty(input)) { + uri = Uri.parse("https://google.com"); + } else { + uri = Uri.parse("https://google.com/search") + .buildUpon() + .appendQueryParameter("q", input) + .build(); + } + mBrowser.getActiveTab().getNavigationController().navigate(uri); } private static String getUrlFromIntent(Intent intent) {