diff --git a/DEPS b/DEPS index 8bcd4d5cb..34418bf 100644 --- a/DEPS +++ b/DEPS
@@ -111,11 +111,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': '7e4c630e73995659fbbd8ab496f66aee64b5b474', + 'skia_revision': '92694bea2840317e62de361d965f11f68cccd009', # 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': '1ef470c48d917990ec028db06331d44e25f14664', + 'v8_revision': '14d9c29330036d87823b15706a4ebcf076b3df83', # 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. @@ -123,7 +123,7 @@ # 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': '672267fcc74feff4693eee1a72d1d20edda84d2d', + 'angle_revision': '683bb0130ca2c9a06fd02141861ac97ca859b9c1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -163,7 +163,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': '428854931e683b405da20d2f404073f51c5a183d', + 'freetype_revision': 'f56830ed406f90f6f53ee6367f2068a0f27bf90b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling HarfBuzz # and whatever else without interference from each other. @@ -171,7 +171,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': 'ed6fe0f638403e1afd377e38975e4fd430f53432', + 'catapult_revision': '38911d8ac8b22226b63f465e5bdb8cadebeed786', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -670,7 +670,7 @@ }, 'src/third_party/custom_tabs_client/src': { - 'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + '7ad890c969e7fcae8cd078c1f109f2aadd0793ee', + 'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + '873e69c103480c501fafdacf06e90febadeeff9c', 'condition': 'checkout_android', }, @@ -1004,7 +1004,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '78f4835a7135f700c092f7f66d26780b4f7e484a', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'd612e27088b86490416758a002b3b21a345be3fb', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1156,7 +1156,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '0d55c887e92b645f6effe753528323ab2ffd94c2', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '01c68b8001774cea0e17f9b23ddebb9a2bb1f43c', + Var('webrtc_git') + '/src.git' + '@' + '1803bb247055669e9da4a082077078960de62a7f', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1187,7 +1187,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0c93d9ffc58387938cce7eaf7507ca99c3bcbd81', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@9322d68816d4a9341db3a51f0568c7885f6adb6c', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/java/strings/android_webview_strings.grd b/android_webview/java/strings/android_webview_strings.grd index ab911684b..3dd5770 100644 --- a/android_webview/java/strings/android_webview_strings.grd +++ b/android_webview/java/strings/android_webview_strings.grd
@@ -50,6 +50,7 @@ <file lang="am" path="translations/android_webview_strings_am.xtb" /> <file lang="ar" path="translations/android_webview_strings_ar.xtb" /> <file lang="bg" path="translations/android_webview_strings_bg.xtb" /> + <file lang="bn" path="translations/android_webview_strings_bn.xtb" /> <file lang="ca" path="translations/android_webview_strings_ca.xtb" /> <file lang="cs" path="translations/android_webview_strings_cs.xtb" /> <file lang="da" path="translations/android_webview_strings_da.xtb" /> @@ -58,10 +59,12 @@ <file lang="en-GB" path="translations/android_webview_strings_en-GB.xtb" /> <file lang="es" path="translations/android_webview_strings_es.xtb" /> <file lang="es-419" path="translations/android_webview_strings_es-419.xtb" /> + <file lang="et" path="translations/android_webview_strings_et.xtb" /> <file lang="fa" path="translations/android_webview_strings_fa.xtb" /> <file lang="fi" path="translations/android_webview_strings_fi.xtb" /> <file lang="fil" path="translations/android_webview_strings_fil.xtb" /> <file lang="fr" path="translations/android_webview_strings_fr.xtb" /> + <file lang="gu" path="translations/android_webview_strings_gu.xtb" /> <file lang="hi" path="translations/android_webview_strings_hi.xtb" /> <file lang="hr" path="translations/android_webview_strings_hr.xtb" /> <file lang="hu" path="translations/android_webview_strings_hu.xtb" /> @@ -70,8 +73,12 @@ <file lang="iw" path="translations/android_webview_strings_iw.xtb" /> <file lang="ja" path="translations/android_webview_strings_ja.xtb" /> <file lang="ko" path="translations/android_webview_strings_ko.xtb" /> + <file lang="kn" path="translations/android_webview_strings_kn.xtb" /> <file lang="lt" path="translations/android_webview_strings_lt.xtb" /> <file lang="lv" path="translations/android_webview_strings_lv.xtb" /> + <file lang="ml" path="translations/android_webview_strings_ml.xtb" /> + <file lang="mr" path="translations/android_webview_strings_mr.xtb" /> + <file lang="ms" path="translations/android_webview_strings_ms.xtb" /> <file lang="nl" path="translations/android_webview_strings_nl.xtb" /> <file lang="no" path="translations/android_webview_strings_no.xtb" /> <file lang="pl" path="translations/android_webview_strings_pl.xtb" /> @@ -84,6 +91,8 @@ <file lang="sr" path="translations/android_webview_strings_sr.xtb" /> <file lang="sv" path="translations/android_webview_strings_sv.xtb" /> <file lang="sw" path="translations/android_webview_strings_sw.xtb" /> + <file lang="ta" path="translations/android_webview_strings_ta.xtb" /> + <file lang="te" path="translations/android_webview_strings_te.xtb" /> <file lang="th" path="translations/android_webview_strings_th.xtb" /> <file lang="tr" path="translations/android_webview_strings_tr.xtb" /> <file lang="uk" path="translations/android_webview_strings_uk.xtb" />
diff --git a/android_webview/java/strings/translations/android_webview_strings_bn.xtb b/android_webview/java/strings/translations/android_webview_strings_bn.xtb new file mode 100644 index 0000000..2cf5e639 --- /dev/null +++ b/android_webview/java/strings/translations/android_webview_strings_bn.xtb
@@ -0,0 +1,6 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="bn"> +<translation id="3572484393913897457">System WebView licences</translation> +<translation id="8916631167640856213">This functionality is not supported in this version of Android.</translation> +</translationbundle> \ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_et.xtb b/android_webview/java/strings/translations/android_webview_strings_et.xtb new file mode 100644 index 0000000..d8d57ae6 --- /dev/null +++ b/android_webview/java/strings/translations/android_webview_strings_et.xtb
@@ -0,0 +1,6 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="et"> +<translation id="3572484393913897457">System WebView licences</translation> +<translation id="8916631167640856213">This functionality is not supported in this version of Android.</translation> +</translationbundle> \ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_gu.xtb b/android_webview/java/strings/translations/android_webview_strings_gu.xtb new file mode 100644 index 0000000..00d2aab --- /dev/null +++ b/android_webview/java/strings/translations/android_webview_strings_gu.xtb
@@ -0,0 +1,6 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="gu"> +<translation id="3572484393913897457">System WebView licences</translation> +<translation id="8916631167640856213">This functionality is not supported in this version of Android.</translation> +</translationbundle> \ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_kn.xtb b/android_webview/java/strings/translations/android_webview_strings_kn.xtb new file mode 100644 index 0000000..93cc81ff --- /dev/null +++ b/android_webview/java/strings/translations/android_webview_strings_kn.xtb
@@ -0,0 +1,6 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="kn"> +<translation id="3572484393913897457">System WebView licences</translation> +<translation id="8916631167640856213">This functionality is not supported in this version of Android.</translation> +</translationbundle> \ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_ml.xtb b/android_webview/java/strings/translations/android_webview_strings_ml.xtb new file mode 100644 index 0000000..cb62ba1 --- /dev/null +++ b/android_webview/java/strings/translations/android_webview_strings_ml.xtb
@@ -0,0 +1,6 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ml"> +<translation id="3572484393913897457">System WebView licences</translation> +<translation id="8916631167640856213">This functionality is not supported in this version of Android.</translation> +</translationbundle> \ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_mr.xtb b/android_webview/java/strings/translations/android_webview_strings_mr.xtb new file mode 100644 index 0000000..29eda3cd --- /dev/null +++ b/android_webview/java/strings/translations/android_webview_strings_mr.xtb
@@ -0,0 +1,6 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="mr"> +<translation id="3572484393913897457">System WebView licences</translation> +<translation id="8916631167640856213">This functionality is not supported in this version of Android.</translation> +</translationbundle> \ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_ms.xtb b/android_webview/java/strings/translations/android_webview_strings_ms.xtb new file mode 100644 index 0000000..ed0e9d0e --- /dev/null +++ b/android_webview/java/strings/translations/android_webview_strings_ms.xtb
@@ -0,0 +1,6 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ms"> +<translation id="3572484393913897457">System WebView licences</translation> +<translation id="8916631167640856213">This functionality is not supported in this version of Android.</translation> +</translationbundle> \ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_ta.xtb b/android_webview/java/strings/translations/android_webview_strings_ta.xtb new file mode 100644 index 0000000..20012f0a --- /dev/null +++ b/android_webview/java/strings/translations/android_webview_strings_ta.xtb
@@ -0,0 +1,6 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ta"> +<translation id="3572484393913897457">System WebView licences</translation> +<translation id="8916631167640856213">This functionality is not supported in this version of Android.</translation> +</translationbundle> \ No newline at end of file
diff --git a/android_webview/java/strings/translations/android_webview_strings_te.xtb b/android_webview/java/strings/translations/android_webview_strings_te.xtb new file mode 100644 index 0000000..6a9b547 --- /dev/null +++ b/android_webview/java/strings/translations/android_webview_strings_te.xtb
@@ -0,0 +1,6 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="te"> +<translation id="3572484393913897457">System WebView licences</translation> +<translation id="8916631167640856213">This functionality is not supported in this version of Android.</translation> +</translationbundle> \ No newline at end of file
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 3802484..c86d537 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -487,6 +487,8 @@ "magnifier/magnifier_scale_utils.h", "magnifier/partial_magnification_controller.cc", "magnifier/partial_magnification_controller.h", + "media/media_notification_controller.cc", + "media/media_notification_controller.h", "media_controller.cc", "media_controller.h", "metrics/demo_session_metrics_recorder.cc", @@ -1343,6 +1345,7 @@ "//components/discardable_memory/public/interfaces", "//mojo/public/cpp/system", "//services/device/public/mojom", + "//services/media_session/public/mojom", "//services/service_manager/public/cpp", "//services/ws:host", "//services/ws:lib", @@ -1411,7 +1414,6 @@ "//net", "//services/content/public/cpp", "//services/data_decoder/public/cpp", - "//services/media_session/public/mojom", "//services/preferences/public/cpp", "//services/service_manager/public/cpp", "//services/ws/gpu_host", @@ -1813,6 +1815,7 @@ "magnifier/magnifier_test_utils.cc", "magnifier/magnifier_test_utils.h", "magnifier/partial_magnification_controller_unittest.cc", + "media/media_notification_controller_unittest.cc", "metrics/demo_session_metrics_recorder_unittest.cc", "metrics/desktop_task_switch_metric_recorder_unittest.cc", "metrics/login_metrics_recorder_unittest.cc",
diff --git a/ash/app_list/model/search/search_result.h b/ash/app_list/model/search/search_result.h index 1dae81620..621a2ac7d 100644 --- a/ash/app_list/model/search/search_result.h +++ b/ash/app_list/model/search/search_result.h
@@ -65,6 +65,13 @@ const Tags& details_tags() const { return metadata_->details_tags; } void set_details_tags(const Tags& tags) { metadata_->details_tags = tags; } + const base::string16& accessible_name() const { + return metadata_->accessible_name; + } + void set_accessible_name(const base::string16& name) { + metadata_->accessible_name = name; + } + float rating() const { return metadata_->rating; } void SetRating(float rating);
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc index b930e27..039a8a3b 100644 --- a/ash/app_list/views/app_list_item_view.cc +++ b/ash/app_list/views/app_list_item_view.cc
@@ -119,8 +119,6 @@ class AppListItemView::IconImageView : public views::ImageView { public: IconImageView() { - SetPaintToLayer(); - layer()->SetFillsBoundsOpaquely(false); set_can_process_events_within_subtree(false); SetVerticalAlignment(views::ImageView::LEADING); } @@ -146,6 +144,7 @@ // Sets a rounded rect mask layer with |corner_radius| and |insets| to clip // the icon. void SetRoundedRectMaskLayer(int corner_radius, const gfx::Insets& insets) { + EnsureLayer(); icon_mask_ = views::Painter::CreatePaintedLayer( views::Painter::CreateSolidRoundRectPainter(SK_ColorBLACK, corner_radius, insets)); @@ -158,6 +157,14 @@ mask_insets_ = insets; } + // Ensure that the view has a layer. + void EnsureLayer() { + if (!layer()) { + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); + } + } + private: // The owner of a mask layer to clip the icon into circle. std::unique_ptr<ui::LayerOwner> icon_mask_; @@ -250,6 +257,9 @@ SetAnimationDuration(0); preview_circle_radius_ = 0; + + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); } AppListItemView::~AppListItemView() { @@ -748,6 +758,8 @@ void AppListItemView::SetBackgroundBlurEnabled(bool enabled) { DCHECK(is_folder_); + if (enabled) + icon_->EnsureLayer(); icon_->layer()->SetBackgroundBlur( enabled ? AppListConfig::instance().blur_radius() : 0); }
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index 7bf3d67..427d925 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -121,33 +121,6 @@ DISALLOW_COPY_AND_ASSIGN(SearchBoxFocusHost); }; -// The view for the App List overlay, which appears as a white rounded -// rectangle with the given radius. -class AppListOverlayView : public views::View { - public: - explicit AppListOverlayView(int corner_radius) - : corner_radius_(corner_radius) { - SetPaintToLayer(); - SetVisible(false); - layer()->SetOpacity(0.0f); - } - - ~AppListOverlayView() override {} - - // Overridden from views::View: - void OnPaint(gfx::Canvas* canvas) override { - cc::PaintFlags flags; - flags.setStyle(cc::PaintFlags::kFill_Style); - flags.setColor(SK_ColorWHITE); - canvas->DrawRoundRect(GetContentsBounds(), corner_radius_, flags); - } - - private: - const int corner_radius_; - - DISALLOW_COPY_AND_ASSIGN(AppListOverlayView); -}; - SkColor GetBackgroundShieldColor(const std::vector<SkColor>& prominent_colors) { if (prominent_colors.empty()) return app_list::AppListView::kDefaultBackgroundColor; @@ -361,7 +334,6 @@ InitializeFullscreen(params.parent); InitChildWidgets(); - AddChildView(overlay_view_); SetState(app_list_state_); @@ -410,44 +382,6 @@ app_list_main_view_->contents_view()->Back(); } -void AppListView::SetAppListOverlayVisible(bool visible) { - DCHECK(overlay_view_); - - // Display the overlay immediately so we can begin the animation. - overlay_view_->SetVisible(true); - - ui::ScopedLayerAnimationSettings settings( - overlay_view_->layer()->GetAnimator()); - settings.SetTweenType(gfx::Tween::LINEAR); - - // If we're dismissing the overlay, hide the view at the end of the animation. - if (!visible) { - // Since only one animation is visible at a time, it's safe to re-use - // animation_observer_ here. - hide_view_animation_observer_->SetTarget(overlay_view_); - settings.AddObserver(hide_view_animation_observer_.get()); - } - - const float kOverlayFadeInMilliseconds = 125; - settings.SetTransitionDuration( - base::TimeDelta::FromMilliseconds(kOverlayFadeInMilliseconds)); - - const float kOverlayOpacity = 0.75f; - overlay_view_->layer()->SetOpacity(visible ? kOverlayOpacity : 0.0f); - // Create the illusion that the search box is hidden behind the app list - // overlay mask by setting its opacity to the same value, and disabling it. - { - ui::ScopedLayerAnimationSettings settings( - search_box_widget_->GetLayer()->GetAnimator()); - const float kSearchBoxWidgetOpacity = 0.5f; - search_box_widget_->GetLayer()->SetOpacity(visible ? kSearchBoxWidgetOpacity - : 1.0f); - search_box_view_->SetEnabled(!visible); - if (!visible) - search_box_view_->search_box()->RequestFocus(); - } -} - void AppListView::OnPaint(gfx::Canvas* canvas) { views::WidgetDelegateView::OnPaint(canvas); if (!next_paint_callback_.is_null()) { @@ -649,8 +583,6 @@ fullscreen_widget_->GetNativeView()->SetBounds( GetPreferredWidgetBoundsForState(AppListViewState::CLOSED)); - overlay_view_ = new AppListOverlayView(0 /* no corners */); - widget_observer_ = std::make_unique<FullscreenWidgetObserver>(this); }
diff --git a/ash/app_list/views/app_list_view.h b/ash/app_list/views/app_list_view.h index c1006df..d456966 100644 --- a/ash/app_list/views/app_list_view.h +++ b/ash/app_list/views/app_list_view.h
@@ -125,10 +125,6 @@ // Performs the 'back' action for the active page. void Back(); - // Enables/disables a semi-transparent overlay over the app list (good for - // hiding the app list when a modal dialog is being shown). - void SetAppListOverlayVisible(bool visible); - // views::View: void OnPaint(gfx::Canvas* canvas) override; const char* GetClassName() const override; @@ -397,10 +393,6 @@ // closed. std::unique_ptr<FullscreenWidgetObserver> widget_observer_; - // A semi-transparent white overlay that covers the app list while dialogs - // are open. - views::View* overlay_view_ = nullptr; - std::unique_ptr<HideViewAnimationObserver> hide_view_animation_observer_; std::unique_ptr<TransitionAnimationObserver> transition_animation_observer_;
diff --git a/ash/app_list/views/app_list_view_unittest.cc b/ash/app_list/views/app_list_view_unittest.cc index 5e354f9..59c5dfa3 100644 --- a/ash/app_list/views/app_list_view_unittest.cc +++ b/ash/app_list/views/app_list_view_unittest.cc
@@ -1996,27 +1996,6 @@ EXPECT_FALSE(search_box_view->back_button()->visible()); } -// Tests that the correct views are displayed for showing search results. -TEST_F(AppListViewTest, DISABLED_AppListOverlayTest) { - Initialize(0, false, false); - // TODO(newcomer): this test needs to be reevaluated for the fullscreen app - // list (http://crbug.com/759779). - Show(); - - AppListMainView* main_view = view_->app_list_main_view(); - SearchBoxView* search_box_view = main_view->search_box_view(); - - // The search box should not be enabled when the app list overlay is shown. - view_->SetAppListOverlayVisible(true); - EXPECT_FALSE(search_box_view->enabled()); - - // The search box should be refocused when the app list overlay is hidden. - view_->SetAppListOverlayVisible(false); - EXPECT_TRUE(search_box_view->enabled()); - EXPECT_EQ(search_box_view->search_box(), - view_->GetWidget()->GetFocusManager()->GetFocusedView()); -} - // Tests that even if initialize is called again with a different initial page, // that different initial page is respected. TEST_F(AppListViewTest, DISABLED_MultiplePagesReinitializeOnInputPage) {
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 73c05c5a..46d3e0f3 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -328,11 +328,10 @@ is_new_style_launcher_enabled_( app_list_features::IsNewStyleLauncherEnabled()) { DCHECK(contents_view_); - SetPaintToLayer(); + SetPaintToLayer(ui::LAYER_NOT_DRAWN); // Clip any icons that are outside the grid view's bounds. These icons would // otherwise be visible to the user when the grid view is off screen. layer()->SetMasksToBounds(true); - layer()->SetFillsBoundsOpaquely(false); // In new style launcher, suggestions container is replaced with suggestion // chips container, all apps indicator is removed and expand arrow is moved @@ -792,8 +791,6 @@ false /* is_in_folder */); AddChildView(view); drag_view_ = view; - drag_view_->SetPaintToLayer(); - drag_view_->layer()->SetFillsBoundsOpaquely(false); drag_view_->SetBoundsRect(drag_view_rect); drag_view_->SetDragUIState(); // Hide the title of the drag_view_. @@ -1162,8 +1159,6 @@ AppListItemView* view = new AppListItemView( this, item_list_->item_at(index), contents_view_->GetAppListMainView()->view_delegate()); - view->SetPaintToLayer(); - view->layer()->SetFillsBoundsOpaquely(false); return view; }
diff --git a/ash/app_list/views/search_result_tile_item_view.cc b/ash/app_list/views/search_result_tile_item_view.cc index eabf42b..b221106 100644 --- a/ash/app_list/views/search_result_tile_item_view.cc +++ b/ash/app_list/views/search_result_tile_item_view.cc
@@ -250,7 +250,12 @@ if (!item->icon().isNull()) OnMetadataChanged(); - base::string16 accessible_name = title_->text(); + base::string16 accessible_name; + if (!item_->accessible_name().empty()) + accessible_name = item_->accessible_name(); + else + accessible_name = title_->text(); + if (rating_ && rating_->visible()) { accessible_name += base::UTF8ToUTF16(", ") +
diff --git a/ash/media/media_notification_controller.cc b/ash/media/media_notification_controller.cc new file mode 100644 index 0000000..8407a36 --- /dev/null +++ b/ash/media/media_notification_controller.cc
@@ -0,0 +1,96 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/media/media_notification_controller.h" + +#include "base/strings/string16.h" +#include "services/media_session/public/mojom/constants.mojom.h" +#include "services/service_manager/public/cpp/connector.h" +#include "ui/gfx/image/image.h" +#include "ui/message_center/public/cpp/notification.h" +#include "ui/message_center/public/cpp/notification_delegate.h" +#include "ui/message_center/public/cpp/notifier_id.h" +#include "url/gurl.h" + +namespace ash { + +namespace { + +// The ID associated with the media session notification. +const char kMediaSessionNotificationId[] = "media-session"; + +// The notifier ID associated with the media session service. +const char kMediaSessionNotifierId[] = "media-session"; + +bool IsMediaSessionNotificationVisible() { + return message_center::MessageCenter::Get()->FindVisibleNotificationById( + kMediaSessionNotificationId) != nullptr; +} + +} // namespace + +MediaNotificationController::MediaNotificationController( + service_manager::Connector* connector) { + // |connector| can be null in tests. + if (!connector) + return; + + media_session::mojom::AudioFocusManagerPtr audio_focus_ptr; + connector->BindInterface(media_session::mojom::kServiceName, + mojo::MakeRequest(&audio_focus_ptr)); + + media_session::mojom::AudioFocusObserverPtr observer; + binding_.Bind(mojo::MakeRequest(&observer)); + audio_focus_ptr->AddObserver(std::move(observer)); +} + +MediaNotificationController::~MediaNotificationController() = default; + +void MediaNotificationController::OnFocusGained( + media_session::mojom::MediaSessionInfoPtr media_session, + media_session::mojom::AudioFocusType type) { + if (IsMediaSessionNotificationVisible()) + return; + + std::unique_ptr<message_center::Notification> notification = + message_center::Notification::CreateSystemNotification( + message_center::NotificationType::NOTIFICATION_TYPE_SIMPLE, + kMediaSessionNotificationId, base::string16(), base::string16(), + base::string16(), GURL(), + message_center::NotifierId( + message_center::NotifierId::SYSTEM_COMPONENT, + kMediaSessionNotifierId), + message_center::RichNotificationData(), + base::MakeRefCounted<message_center::HandleNotificationClickDelegate>( + base::BindRepeating( + &MediaNotificationController::OnNotificationClicked, + weak_ptr_factory_.GetWeakPtr())), + gfx::VectorIcon(), + message_center::SystemNotificationWarningLevel::NORMAL); + + notification->set_pinned(true); + + // Set the priority to low to prevent the notification showing as a popup and + // keep it at the bottom of the list. + notification->set_priority(message_center::LOW_PRIORITY); + + message_center::MessageCenter::Get()->AddNotification( + std::move(notification)); +} + +void MediaNotificationController::OnFocusLost( + media_session::mojom::MediaSessionInfoPtr media_session) { + if (!IsMediaSessionNotificationVisible()) + return; + + message_center::MessageCenter::Get()->RemoveNotification( + kMediaSessionNotificationId, false); +} + +void MediaNotificationController::OnNotificationClicked( + base::Optional<int> button_id) { + NOTIMPLEMENTED(); +} + +} // namespace ash
diff --git a/ash/media/media_notification_controller.h b/ash/media/media_notification_controller.h new file mode 100644 index 0000000..8b4cff41 --- /dev/null +++ b/ash/media/media_notification_controller.h
@@ -0,0 +1,49 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_MEDIA_MEDIA_NOTIFICATION_CONTROLLER_H_ +#define ASH_MEDIA_MEDIA_NOTIFICATION_CONTROLLER_H_ + +#include "ash/ash_export.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/optional.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/media_session/public/mojom/audio_focus.mojom.h" +#include "ui/message_center/message_center.h" + +namespace service_manager { +class Connector; +} // namespace service_manager + +namespace ash { + +// MediaNotificationController will show/hide a media notification when a media +// session is active. This notification will show metadata and playback +// controls. +class ASH_EXPORT MediaNotificationController + : public media_session::mojom::AudioFocusObserver { + public: + explicit MediaNotificationController(service_manager::Connector* connector); + ~MediaNotificationController() override; + + // AudioFocusObserver implementation. + void OnFocusGained(media_session::mojom::MediaSessionInfoPtr media_session, + media_session::mojom::AudioFocusType type) override; + void OnFocusLost( + media_session::mojom::MediaSessionInfoPtr media_session) override; + + private: + void OnNotificationClicked(base::Optional<int> button_id); + + mojo::Binding<media_session::mojom::AudioFocusObserver> binding_{this}; + + base::WeakPtrFactory<MediaNotificationController> weak_ptr_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(MediaNotificationController); +}; + +} // namespace ash + +#endif // ASH_MEDIA_MEDIA_NOTIFICATION_CONTROLLER_H_
diff --git a/ash/media/media_notification_controller_unittest.cc b/ash/media/media_notification_controller_unittest.cc new file mode 100644 index 0000000..4d5a9e3 --- /dev/null +++ b/ash/media/media_notification_controller_unittest.cc
@@ -0,0 +1,90 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/media/media_notification_controller.h" + +#include <memory> + +#include "ash/public/cpp/ash_features.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "base/macros.h" +#include "base/test/scoped_feature_list.h" +#include "services/media_session/public/mojom/audio_focus.mojom.h" +#include "ui/message_center/message_center.h" + +namespace ash { + +using media_session::mojom::AudioFocusType; +using media_session::mojom::MediaSessionInfo; + +namespace { + +bool IsMediaNotificationShown() { + return message_center::MessageCenter::Get()->FindVisibleNotificationById( + "media-session"); +} + +int GetVisibleNotificationCount() { + return message_center::MessageCenter::Get()->GetVisibleNotifications().size(); +} + +int GetPopupNotificationCount() { + return message_center::MessageCenter::Get()->GetPopupNotifications().size(); +} + +} // namespace + +class MediaNotificationControllerTest : public AshTestBase { + public: + MediaNotificationControllerTest() = default; + ~MediaNotificationControllerTest() override = default; + + // AshTestBase + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature( + features::kMediaSessionNotification); + + AshTestBase::SetUp(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + + DISALLOW_COPY_AND_ASSIGN(MediaNotificationControllerTest); +}; + +TEST_F(MediaNotificationControllerTest, OnFocusGainedLost) { + EXPECT_FALSE(IsMediaNotificationShown()); + EXPECT_EQ(0, GetVisibleNotificationCount()); + EXPECT_EQ(0, GetPopupNotificationCount()); + + Shell::Get()->media_notification_controller()->OnFocusGained( + MediaSessionInfo::New(), AudioFocusType::kGain); + EXPECT_TRUE(IsMediaNotificationShown()); + EXPECT_EQ(1, GetVisibleNotificationCount()); + EXPECT_EQ(0, GetPopupNotificationCount()); + + Shell::Get()->media_notification_controller()->OnFocusGained( + MediaSessionInfo::New(), AudioFocusType::kGain); + EXPECT_TRUE(IsMediaNotificationShown()); + EXPECT_EQ(1, GetVisibleNotificationCount()); + EXPECT_EQ(0, GetPopupNotificationCount()); + + Shell::Get()->media_notification_controller()->OnFocusLost( + MediaSessionInfo::New()); + EXPECT_FALSE(IsMediaNotificationShown()); + EXPECT_EQ(0, GetVisibleNotificationCount()); + EXPECT_EQ(0, GetPopupNotificationCount()); +} + +TEST_F(MediaNotificationControllerTest, OnFocusLost_Noop) { + EXPECT_FALSE(IsMediaNotificationShown()); + + Shell::Get()->media_notification_controller()->OnFocusLost( + MediaSessionInfo::New()); + EXPECT_FALSE(IsMediaNotificationShown()); +} + +} // namespace ash
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index 6d4a7b7e..e61fd16 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -38,6 +38,9 @@ const base::Feature kMediaSessionAccelerators{ "MediaSessionAccelerators", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kMediaSessionNotification{ + "MediaSessionNotification", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kNightLight{"NightLight", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kNotificationScrollBar{"NotificationScrollBar",
diff --git a/ash/public/cpp/ash_features.h b/ash/public/cpp/ash_features.h index 4534c54..4db82ae 100644 --- a/ash/public/cpp/ash_features.h +++ b/ash/public/cpp/ash_features.h
@@ -54,6 +54,11 @@ // TODO(beccahughes): Remove after launch. (https://crbug.com/894255) ASH_PUBLIC_EXPORT extern const base::Feature kMediaSessionAccelerators; +// Enables the media session notification. If this is enabled, we will show +// a notification that shows the currently playing media with controls. +// TODO(beccahughes): Remove after launch. (https://crbug.com/897836) +ASH_PUBLIC_EXPORT extern const base::Feature kMediaSessionNotification; + // Enables the Night Light feature. ASH_PUBLIC_EXPORT extern const base::Feature kNightLight;
diff --git a/ash/public/interfaces/app_list.mojom b/ash/public/interfaces/app_list.mojom index eafa883..55e70bf 100644 --- a/ash/public/interfaces/app_list.mojom +++ b/ash/public/interfaces/app_list.mojom
@@ -30,13 +30,14 @@ // A structure holding the common information which is sent from chrome to ash, // representing a search result. -// This structure should be kept as small as possible so that ash can get and -// render search results as early as possible. struct SearchResultMetadata { string id; // The id of the result. mojo_base.mojom.String16 title; // The title of the result, e.g. an app's // name, an autocomplete query, etc. mojo_base.mojom.String16 details; // A detail string of this result. + mojo_base.mojom.String16 accessible_name; + // An text to be announced by a screen + // reader app. array<SearchResultTag> title_tags; // How the title matches the query. See // the SearchResultTag section for // more details.
diff --git a/ash/shell.cc b/ash/shell.cc index d7a360a..4e5295366 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -62,6 +62,7 @@ #include "ash/magnifier/docked_magnifier_controller.h" #include "ash/magnifier/magnification_controller.h" #include "ash/magnifier/partial_magnification_controller.h" +#include "ash/media/media_notification_controller.h" #include "ash/media_controller.h" #include "ash/metrics/time_to_first_present_recorder.h" #include "ash/multi_device_setup/multi_device_notification_presenter.h" @@ -939,6 +940,10 @@ // before it. detachable_base_handler_.reset(); + // MediaNotificationController depends on MessageCenter and must be destructed + // before it. + media_notification_controller_.reset(); + // Destroys the MessageCenter singleton, so must happen late. message_center_controller_.reset(); @@ -1268,6 +1273,11 @@ focus_controller(), window_tree_host_manager_->input_method()); } + if (base::FeatureList::IsEnabled(features::kMediaSessionNotification)) { + media_notification_controller_ = + std::make_unique<MediaNotificationController>(connector_); + } + for (auto& observer : shell_observers_) observer.OnShellInitialized();
diff --git a/ash/shell.h b/ash/shell.h index d45ff2f..f301648b 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -137,6 +137,7 @@ class MagnificationController; class TabletModeController; class MediaController; +class MediaNotificationController; class MessageCenterController; class MouseCursorEventFilter; class MruWindowTracker; @@ -436,6 +437,9 @@ return magnification_controller_.get(); } MediaController* media_controller() { return media_controller_.get(); } + MediaNotificationController* media_notification_controller() { + return media_notification_controller_.get(); + } MessageCenterController* message_center_controller() { return message_center_controller_.get(); } @@ -739,6 +743,7 @@ std::unique_ptr<LogoutConfirmationController> logout_confirmation_controller_; std::unique_ptr<TabletModeController> tablet_mode_controller_; std::unique_ptr<MediaController> media_controller_; + std::unique_ptr<MediaNotificationController> media_notification_controller_; std::unique_ptr<MruWindowTracker> mru_window_tracker_; std::unique_ptr<MultiDeviceNotificationPresenter> multidevice_notification_presenter_;
diff --git a/base/BUILD.gn b/base/BUILD.gn index 21371e67..a536aecb 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -740,8 +740,6 @@ "task/sequence_manager/associated_thread_id.h", "task/sequence_manager/enqueue_order.cc", "task/sequence_manager/enqueue_order.h", - "task/sequence_manager/graceful_queue_shutdown_helper.cc", - "task/sequence_manager/graceful_queue_shutdown_helper.h", "task/sequence_manager/intrusive_heap.h", "task/sequence_manager/lazily_deallocated_deque.h", "task/sequence_manager/lazy_now.cc", @@ -2445,6 +2443,7 @@ "task/sequence_manager/lazily_deallocated_deque_unittest.cc", "task/sequence_manager/sequence_manager_impl_unittest.cc", "task/sequence_manager/task_queue_selector_unittest.cc", + "task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc", "task/sequence_manager/time_domain_unittest.cc", "task/sequence_manager/work_queue_sets_unittest.cc", "task/sequence_manager/work_queue_unittest.cc", @@ -3022,6 +3021,7 @@ ":base_java", ":base_java_test_support", "//third_party/android_support_test_runner:runner_java", + "//third_party/hamcrest:hamcrest_java", "//third_party/junit:junit", ] java_files = [ @@ -3148,6 +3148,8 @@ ":base_java", "//testing/android/junit:junit_test_support", "//third_party/android_support_test_runner:runner_java", + "//third_party/hamcrest:hamcrest_java", + "//third_party/junit:junit", "//third_party/robolectric:robolectric_all_java", ] }
diff --git a/base/android/java/src/org/chromium/base/PackageUtils.java b/base/android/java/src/org/chromium/base/PackageUtils.java index a8e487b..ab554cdc 100644 --- a/base/android/java/src/org/chromium/base/PackageUtils.java +++ b/base/android/java/src/org/chromium/base/PackageUtils.java
@@ -7,9 +7,6 @@ import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; /** * This class provides package checking related methods. @@ -34,22 +31,6 @@ return versionCode; } - /** - * Decodes into a Bitmap an Image resource stored in another package. - * @param otherPackage The package containing the resource. - * @param resourceId The id of the resource. - * @return A Bitmap containing the resource or null if the package could not be found. - */ - public static Bitmap decodeImageResource(String otherPackage, int resourceId) { - PackageManager packageManager = ContextUtils.getApplicationContext().getPackageManager(); - try { - Resources resources = packageManager.getResourcesForApplication(otherPackage); - return BitmapFactory.decodeResource(resources, resourceId); - } catch (PackageManager.NameNotFoundException e) { - return null; - } - } - private PackageUtils() { // Hide constructor }
diff --git a/base/task/sequence_manager/graceful_queue_shutdown_helper.cc b/base/task/sequence_manager/graceful_queue_shutdown_helper.cc deleted file mode 100644 index 9a8c893e..0000000 --- a/base/task/sequence_manager/graceful_queue_shutdown_helper.cc +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/task/sequence_manager/graceful_queue_shutdown_helper.h" - -#include "base/task/sequence_manager/task_queue_impl.h" - -namespace base { -namespace sequence_manager { -namespace internal { - -GracefulQueueShutdownHelper::GracefulQueueShutdownHelper() - : sequence_manager_deleted_(false) {} - -GracefulQueueShutdownHelper::~GracefulQueueShutdownHelper() = default; - -void GracefulQueueShutdownHelper::GracefullyShutdownTaskQueue( - std::unique_ptr<internal::TaskQueueImpl> task_queue) { - AutoLock lock(lock_); - if (sequence_manager_deleted_) - return; - queues_.push_back(std::move(task_queue)); -} - -void GracefulQueueShutdownHelper::OnSequenceManagerDeleted() { - AutoLock lock(lock_); - sequence_manager_deleted_ = true; - queues_.clear(); -} - -std::vector<std::unique_ptr<internal::TaskQueueImpl>> -GracefulQueueShutdownHelper::TakeQueues() { - AutoLock lock(lock_); - std::vector<std::unique_ptr<internal::TaskQueueImpl>> result; - result.swap(queues_); - return result; -} - -} // namespace internal -} // namespace sequence_manager -} // namespace base
diff --git a/base/task/sequence_manager/graceful_queue_shutdown_helper.h b/base/task/sequence_manager/graceful_queue_shutdown_helper.h deleted file mode 100644 index 108eb82..0000000 --- a/base/task/sequence_manager/graceful_queue_shutdown_helper.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_TASK_SEQUENCE_MANAGER_GRACEFUL_QUEUE_SHUTDOWN_HELPER_H_ -#define BASE_TASK_SEQUENCE_MANAGER_GRACEFUL_QUEUE_SHUTDOWN_HELPER_H_ - -#include <memory> -#include <vector> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/synchronization/lock.h" - -namespace base { -namespace sequence_manager { -namespace internal { - -class TaskQueueImpl; - -// Thread-safe helper to shutdown queues from any thread. -class GracefulQueueShutdownHelper - : public RefCountedThreadSafe<GracefulQueueShutdownHelper> { - public: - GracefulQueueShutdownHelper(); - - void GracefullyShutdownTaskQueue( - std::unique_ptr<internal::TaskQueueImpl> queue); - - void OnSequenceManagerDeleted(); - - std::vector<std::unique_ptr<internal::TaskQueueImpl>> TakeQueues(); - - private: - // This class is ref-counted so it controls its own lifetime. - ~GracefulQueueShutdownHelper(); - friend class RefCountedThreadSafe<GracefulQueueShutdownHelper>; - - Lock lock_; - bool sequence_manager_deleted_; - std::vector<std::unique_ptr<internal::TaskQueueImpl>> queues_; - - DISALLOW_COPY_AND_ASSIGN(GracefulQueueShutdownHelper); -}; - -} // namespace internal -} // namespace sequence_manager -} // namespace base - -#endif // BASE_TASK_SEQUENCE_MANAGER_GRACEFUL_QUEUE_SHUTDOWN_HELPER_H_
diff --git a/base/task/sequence_manager/intrusive_heap.h b/base/task/sequence_manager/intrusive_heap.h index eb2fc8a4..c49215b 100644 --- a/base/task/sequence_manager/intrusive_heap.h +++ b/base/task/sequence_manager/intrusive_heap.h
@@ -118,6 +118,11 @@ } } + const T& at(HeapHandle handle) const { + DCHECK(handle.IsValid()); + return nodes_[handle.index_]; + } + // Caution mutating the heap invalidates the iterators. const T* begin() const { return &nodes_[1u]; } const T* end() const { return begin() + size_; }
diff --git a/base/task/sequence_manager/intrusive_heap_unittest.cc b/base/task/sequence_manager/intrusive_heap_unittest.cc index 3c1323a..8ec5514 100644 --- a/base/task/sequence_manager/intrusive_heap_unittest.cc +++ b/base/task/sequence_manager/intrusive_heap_unittest.cc
@@ -91,7 +91,6 @@ TEST_F(IntrusiveHeapTest, InsertAscending) { IntrusiveHeap<TestElement> heap; - HeapHandle index1; for (int i = 0; i < 50; i++) heap.insert({i, nullptr}); @@ -373,6 +372,19 @@ EXPECT_TRUE(IntrusiveHeapTest::CompareNodes(six, five)); } +TEST_F(IntrusiveHeapTest, At) { + HeapHandle index[10]; + IntrusiveHeap<TestElement> heap; + + for (int i = 0; i < 10; i++) + heap.insert({static_cast<int>(i ^ (i + 1)), &index[i]}); + + for (int i = 0; i < 10; i++) { + EXPECT_EQ(heap.at(index[i]).key, i ^ (i + 1)); + EXPECT_EQ(heap.at(index[i]).handle, &index[i]); + } +} + } // namespace internal } // namespace sequence_manager } // namespace base
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc index 7b6309f5..b0ba253 100644 --- a/base/task/sequence_manager/sequence_manager_impl.cc +++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -72,7 +72,6 @@ SequenceManagerImpl::SequenceManagerImpl( std::unique_ptr<internal::ThreadController> controller) : associated_thread_(controller->GetAssociatedThread()), - graceful_shutdown_helper_(new internal::GracefulQueueShutdownHelper()), controller_(std::move(controller)), metric_recording_settings_(InitializeMetricRecordingSettings()), memory_corruption_sentinel_(kMemoryCorruptionSentinelValue), @@ -110,9 +109,6 @@ main_thread_only().active_queues.clear(); main_thread_only().queues_to_gracefully_shutdown.clear(); - - graceful_shutdown_helper_->OnSequenceManagerDeleted(); - main_thread_only().selector.SetTaskQueueSelectorObserver(nullptr); // In some tests a NestingObserver may not have been registered. @@ -231,6 +227,12 @@ task_queue->immediate_work_list_storage()->queue = nullptr; } +void SequenceManagerImpl::ShutdownTaskQueueGracefully( + std::unique_ptr<internal::TaskQueueImpl> task_queue) { + main_thread_only().queues_to_gracefully_shutdown[task_queue.get()] = + std::move(task_queue); +} + void SequenceManagerImpl::UnregisterTaskQueueImpl( std::unique_ptr<internal::TaskQueueImpl> task_queue) { TRACE_EVENT1("sequence_manager", "SequenceManagerImpl::UnregisterTaskQueue", @@ -458,6 +460,14 @@ return delay_till_next_task; } +bool SequenceManagerImpl::HasPendingHighResolutionTasks() { + for (TimeDomain* time_domain : main_thread_only().time_domains) { + if (time_domain->HasPendingHighResolutionTasks()) + return true; + } + return false; +} + void SequenceManagerImpl::WillQueueTask(Task* pending_task) { controller_->WillQueueTask(pending_task); } @@ -688,18 +698,7 @@ SweepCanceledDelayedTasksInQueue(pair.first, &time_domain_now); } -void SequenceManagerImpl::TakeQueuesToGracefullyShutdownFromHelper() { - std::vector<std::unique_ptr<internal::TaskQueueImpl>> queues = - graceful_shutdown_helper_->TakeQueues(); - for (std::unique_ptr<internal::TaskQueueImpl>& queue : queues) { - main_thread_only().queues_to_gracefully_shutdown[queue.get()] = - std::move(queue); - } -} - void SequenceManagerImpl::CleanUpQueues() { - TakeQueuesToGracefullyShutdownFromHelper(); - for (auto it = main_thread_only().queues_to_gracefully_shutdown.begin(); it != main_thread_only().queues_to_gracefully_shutdown.end();) { if (it->first->IsEmpty()) { @@ -713,11 +712,6 @@ main_thread_only().queues_to_delete.clear(); } -scoped_refptr<internal::GracefulQueueShutdownHelper> -SequenceManagerImpl::GetGracefulQueueShutdownHelper() const { - return graceful_shutdown_helper_; -} - WeakPtr<SequenceManagerImpl> SequenceManagerImpl::GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
diff --git a/base/task/sequence_manager/sequence_manager_impl.h b/base/task/sequence_manager/sequence_manager_impl.h index 76d06372..0bf46ae9 100644 --- a/base/task/sequence_manager/sequence_manager_impl.h +++ b/base/task/sequence_manager/sequence_manager_impl.h
@@ -28,7 +28,6 @@ #include "base/synchronization/lock.h" #include "base/task/sequence_manager/associated_thread_id.h" #include "base/task/sequence_manager/enqueue_order.h" -#include "base/task/sequence_manager/graceful_queue_shutdown_helper.h" #include "base/task/sequence_manager/moveable_auto_lock.h" #include "base/task/sequence_manager/sequence_manager.h" #include "base/task/sequence_manager/task_queue_impl.h" @@ -125,6 +124,7 @@ Optional<PendingTask> TakeTask() override; void DidRunTask() override; TimeDelta DelayTillNextTask(LazyNow* lazy_now) override; + bool HasPendingHighResolutionTasks() override; // Requests that a task to process work is posted on the main task runner. // These tasks are de-duplicated in two buckets: main-thread and all other @@ -150,8 +150,9 @@ void UnregisterTaskQueueImpl( std::unique_ptr<internal::TaskQueueImpl> task_queue); - scoped_refptr<internal::GracefulQueueShutdownHelper> - GetGracefulQueueShutdownHelper() const; + // Schedule a call to UnregisterTaskQueueImpl as soon as it's safe to do so. + void ShutdownTaskQueueGracefully( + std::unique_ptr<internal::TaskQueueImpl> task_queue); const scoped_refptr<AssociatedThreadId>& associated_thread() const { return associated_thread_; @@ -309,8 +310,6 @@ std::unique_ptr<internal::TaskQueueImpl> CreateTaskQueueImpl( const TaskQueue::Spec& spec) override; - void TakeQueuesToGracefullyShutdownFromHelper(); - // Deletes queues marked for deletion and empty queues marked for shutdown. void CleanUpQueues(); @@ -327,9 +326,6 @@ scoped_refptr<AssociatedThreadId> associated_thread_; - const scoped_refptr<internal::GracefulQueueShutdownHelper> - graceful_shutdown_helper_; - internal::EnqueueOrder::Generator enqueue_order_generator_; std::unique_ptr<internal::ThreadController> controller_;
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc index 7b6fd80..b0d7714 100644 --- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc +++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -34,6 +34,7 @@ #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/blame_context.h" +#include "build/build_config.h" #include "testing/gmock/include/gmock/gmock.h" using testing::AnyNumber; @@ -3168,9 +3169,11 @@ EXPECT_THAT(run_order, ElementsAre(1u, 2u)); } -TEST_P(SequenceManagerTest, TaskQueueDeletedOnAnotherThread) { +TEST_P(SequenceManagerTest, TaskRunnerDeletedOnAnotherThread) { std::vector<TimeTicks> run_times; scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue(); + scoped_refptr<TaskRunner> task_runner = + main_tq->CreateTaskRunner(kTaskTypeNone); int start_counter = 0; int complete_counter = 0; @@ -3181,7 +3184,7 @@ EXPECT_EQ(0u, manager_->QueuesToDeleteCount()); for (int i = 1; i <= 5; ++i) { - main_tq->PostDelayedTask( + task_runner->PostDelayedTask( FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock()), TimeDelta::FromMilliseconds(i * 100)); } @@ -3190,6 +3193,9 @@ // task handlers. UnsetOnTaskHandlers(main_tq); + // Make |task_runner| the only reference to |main_tq|. + main_tq = nullptr; + WaitableEvent task_queue_deleted(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::NOT_SIGNALED); std::unique_ptr<Thread> thread = std::make_unique<Thread>("test thread"); @@ -3197,12 +3203,12 @@ thread->task_runner()->PostTask( FROM_HERE, BindOnce( - [](scoped_refptr<TestTaskQueue> task_queue, + [](scoped_refptr<TaskRunner> task_runner, WaitableEvent* task_queue_deleted) { - task_queue = nullptr; + task_runner = nullptr; task_queue_deleted->Signal(); }, - std::move(main_tq), &task_queue_deleted)); + std::move(task_runner), &task_queue_deleted)); task_queue_deleted.Wait(); EXPECT_EQ(1u, manager_->ActiveQueuesCount()); @@ -3352,6 +3358,9 @@ // Run the posted task. Thread::Run(run_loop); EXPECT_TRUE(did_run_task_); + + // The |queue_| should be destructed on the creating thread. + queue_ = nullptr; } scoped_refptr<SingleThreadTaskRunner> original_task_runner_; @@ -3412,6 +3421,33 @@ CreateUnboundSequenceManager(nullptr); } +TEST_P(SequenceManagerTest, HasPendingHighResolutionTasks) { + CreateTaskQueues(1u); + bool supports_high_res = false; +#if defined(OS_WIN) + supports_high_res = true; +#endif + + // Only the third task needs high resolution timing. + EXPECT_FALSE(manager_->HasPendingHighResolutionTasks()); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); + EXPECT_FALSE(manager_->HasPendingHighResolutionTasks()); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromMilliseconds(100)); + EXPECT_FALSE(manager_->HasPendingHighResolutionTasks()); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromMilliseconds(10)); + EXPECT_EQ(manager_->HasPendingHighResolutionTasks(), supports_high_res); + + // Running immediate tasks doesn't affect pending high resolution tasks. + RunLoop().RunUntilIdle(); + EXPECT_EQ(manager_->HasPendingHighResolutionTasks(), supports_high_res); + + test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(100)); + RunLoop().RunUntilIdle(); + EXPECT_FALSE(manager_->HasPendingHighResolutionTasks()); +} + } // namespace sequence_manager_impl_unittest } // namespace internal } // namespace sequence_manager
diff --git a/base/task/sequence_manager/sequenced_task_source.h b/base/task/sequence_manager/sequenced_task_source.h index 285f853..612a2b4 100644 --- a/base/task/sequence_manager/sequenced_task_source.h +++ b/base/task/sequence_manager/sequenced_task_source.h
@@ -16,6 +16,8 @@ // Interface to pass tasks to ThreadController. class SequencedTaskSource { public: + virtual ~SequencedTaskSource() = default; + // Returns the next task to run from this source or nullopt if // there're no more tasks ready to run. If a task is returned, // DidRunTask() must be invoked before the next call to TakeTask(). @@ -28,6 +30,10 @@ // Returns the delay till the next task or TimeDelta::Max() // if there are no tasks left. virtual TimeDelta DelayTillNextTask(LazyNow* lazy_now) = 0; + + // Return true if there are any pending tasks in the task source which require + // high resolution timing. + virtual bool HasPendingHighResolutionTasks() = 0; }; } // namespace internal
diff --git a/base/task/sequence_manager/task_queue.cc b/base/task/sequence_manager/task_queue.cc index 85daf685..dd106ba 100644 --- a/base/task/sequence_manager/task_queue.cc +++ b/base/task/sequence_manager/task_queue.cc
@@ -34,8 +34,6 @@ const TaskQueue::Spec& spec) : impl_(std::move(impl)), sequence_manager_(impl_ ? impl_->GetSequenceManagerWeakPtr() : nullptr), - graceful_queue_shutdown_helper_( - impl_ ? impl_->GetGracefulQueueShutdownHelper() : nullptr), associated_thread_((impl_ && impl_->sequence_manager()) ? impl_->sequence_manager()->associated_thread() : MakeRefCounted<internal::AssociatedThreadId>()), @@ -48,8 +46,10 @@ return; if (impl_->IsUnregistered()) return; - graceful_queue_shutdown_helper_->GracefullyShutdownTaskQueue( - TakeTaskQueueImpl()); + + // If we've not been unregistered then this must occur on the main thread. + DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); + impl_->sequence_manager()->ShutdownTaskQueueGracefully(TakeTaskQueueImpl()); } TaskQueue::TaskTiming::TaskTiming(bool has_wall_time, bool has_thread_time)
diff --git a/base/task/sequence_manager/task_queue.h b/base/task/sequence_manager/task_queue.h index 07251608..d09a0e4 100644 --- a/base/task/sequence_manager/task_queue.h +++ b/base/task/sequence_manager/task_queue.h
@@ -29,7 +29,6 @@ namespace internal { struct AssociatedThreadId; -class GracefulQueueShutdownHelper; class SequenceManagerImpl; class TaskQueueImpl; } // namespace internal @@ -337,9 +336,6 @@ const WeakPtr<internal::SequenceManagerImpl> sequence_manager_; - const scoped_refptr<internal::GracefulQueueShutdownHelper> - graceful_queue_shutdown_helper_; - scoped_refptr<internal::AssociatedThreadId> associated_thread_; scoped_refptr<SingleThreadTaskRunner> default_task_runner_;
diff --git a/base/task/sequence_manager/task_queue_impl.cc b/base/task/sequence_manager/task_queue_impl.cc index b1164a7..dd396345 100644 --- a/base/task/sequence_manager/task_queue_impl.cc +++ b/base/task/sequence_manager/task_queue_impl.cc
@@ -15,6 +15,7 @@ #include "base/task/sequence_manager/work_queue.h" #include "base/time/time.h" #include "base/trace_event/blame_context.h" +#include "build/build_config.h" namespace base { namespace sequence_manager { @@ -145,8 +146,8 @@ // order inversion for tasks that are posted from within a lock, with a // destructor that acquires the same lock. - std::priority_queue<Task> delayed_incoming_queue; - delayed_incoming_queue.swap(main_thread_only().delayed_incoming_queue); + std::priority_queue<Task> delayed_incoming_queue = + main_thread_only().delayed_incoming_queue.TakeTasks(); std::unique_ptr<WorkQueue> immediate_work_queue = std::move(main_thread_only().immediate_work_queue); @@ -193,6 +194,17 @@ // for details. CHECK(task.callback); DCHECK_GT(task.delay, TimeDelta()); + + WakeUpResolution resolution = WakeUpResolution::kLow; +#if defined(OS_WIN) + // We consider the task needs a high resolution timer if the delay is more + // than 0 and less than 32ms. This caps the relative error to less than 50% : + // a 33ms wait can wake at 48ms since the default resolution on Windows is + // between 10 and 15ms. + if (task.delay.InMilliseconds() < (2 * Time::kMinLowResolutionThresholdMs)) + resolution = WakeUpResolution::kHigh; +#endif // defined(OS_WIN) + if (PlatformThread::CurrentId() == associated_thread_->thread_id) { // Lock-free fast path for delayed tasks posted from the main thread. DCHECK(main_thread_only().sequence_manager); @@ -203,7 +215,8 @@ TimeTicks time_domain_now = main_thread_only().time_domain->Now(); TimeTicks time_domain_delayed_run_time = time_domain_now + task.delay; PushOntoDelayedIncomingQueueFromMainThread( - Task(std::move(task), time_domain_delayed_run_time, sequence_number), + Task(std::move(task), time_domain_delayed_run_time, sequence_number, + EnqueueOrder(), resolution), time_domain_now, /* notify_task_annotator */ true); } else { // NOTE posting a delayed task from a different thread is not expected to @@ -219,7 +232,8 @@ TimeTicks time_domain_now = any_thread().time_domain->Now(); TimeTicks time_domain_delayed_run_time = time_domain_now + task.delay; PushOntoDelayedIncomingQueueLocked( - Task(std::move(task), time_domain_delayed_run_time, sequence_number)); + Task(std::move(task), time_domain_delayed_run_time, sequence_number, + EnqueueOrder(), resolution)); } } @@ -540,7 +554,7 @@ main_thread_only().immediate_work_queue->AsValueInto(now, state); state->EndArray(); state->BeginArray("delayed_incoming_queue"); - QueueAsValueInto(main_thread_only().delayed_incoming_queue, now, state); + main_thread_only().delayed_incoming_queue.AsValueInto(now, state); state->EndArray(); } state->SetString("priority", TaskQueue::PriorityToString(GetQueuePriority())); @@ -857,23 +871,10 @@ void TaskQueueImpl::SweepCanceledDelayedTasks(TimeTicks now) { if (main_thread_only().delayed_incoming_queue.empty()) return; - - // Remove canceled tasks. - std::priority_queue<Task> remaining_tasks; const SequenceManagerImpl* sequence_manager = main_thread_only().sequence_manager; - while (!main_thread_only().delayed_incoming_queue.empty()) { - // TODO(alexclarke): Use IsCancelled once we've understood the bug. - // See http://crbug.com/798554 - if (!sequence_manager->SetCrashKeysAndCheckIsTaskCancelled( - main_thread_only().delayed_incoming_queue.top())) { - remaining_tasks.push(std::move( - const_cast<Task&>(main_thread_only().delayed_incoming_queue.top()))); - } - main_thread_only().delayed_incoming_queue.pop(); - } - - main_thread_only().delayed_incoming_queue = std::move(remaining_tasks); + main_thread_only().delayed_incoming_queue.SweepCancelledTasks( + sequence_manager); // Also consider shrinking the work queue if it's wasting memory. main_thread_only().delayed_work_queue->MaybeShrinkQueue(); @@ -933,8 +934,11 @@ main_thread_only().on_next_wake_up_changed_callback.Run(wake_up->time); } + WakeUpResolution resolution = has_pending_high_resolution_tasks() + ? WakeUpResolution::kHigh + : WakeUpResolution::kLow; main_thread_only().time_domain->SetNextWakeUpForQueue(this, wake_up, - lazy_now); + resolution, lazy_now); } void TaskQueueImpl::SetDelayedWakeUpForTesting( @@ -991,10 +995,6 @@ return main_thread_only().sequence_manager->GetWeakPtr(); } -scoped_refptr<GracefulQueueShutdownHelper> -TaskQueueImpl::GetGracefulQueueShutdownHelper() { - return main_thread_only().sequence_manager->GetGracefulQueueShutdownHelper(); -} void TaskQueueImpl::SetQueueEnabledForTest(bool enabled) { main_thread_only().is_enabled_for_test = enabled; @@ -1016,6 +1016,46 @@ main_thread_only().sequence_manager = nullptr; } +TaskQueueImpl::DelayedIncomingQueue::DelayedIncomingQueue() = default; +TaskQueueImpl::DelayedIncomingQueue::~DelayedIncomingQueue() = default; + +void TaskQueueImpl::DelayedIncomingQueue::push(Task&& task) { + if (task.is_high_res) + pending_high_res_tasks_++; + queue_.push(std::move(task)); +} + +void TaskQueueImpl::DelayedIncomingQueue::pop() { + DCHECK(!empty()); + if (top().is_high_res) { + pending_high_res_tasks_--; + DCHECK_GE(pending_high_res_tasks_, 0); + } + queue_.pop(); +} + +void TaskQueueImpl::DelayedIncomingQueue::SweepCancelledTasks( + const SequenceManagerImpl* sequence_manager) { + std::priority_queue<Task> remaining_tasks; + while (!empty()) { + // TODO(alexclarke): Use IsCancelled once we've understood the bug. + // See http://crbug.com/798554 + if (!sequence_manager->SetCrashKeysAndCheckIsTaskCancelled(top())) { + if (top().is_high_res) + pending_high_res_tasks_++; + remaining_tasks.push(std::move(const_cast<Task&>(top()))); + } + pop(); + } + queue_ = std::move(remaining_tasks); +} + +void TaskQueueImpl::DelayedIncomingQueue::AsValueInto( + TimeTicks now, + trace_event::TracedValue* state) const { + QueueAsValueInto(queue_, now, state); +} + } // namespace internal } // namespace sequence_manager } // namespace base
diff --git a/base/task/sequence_manager/task_queue_impl.h b/base/task/sequence_manager/task_queue_impl.h index 8fcd036..62db3e3 100644 --- a/base/task/sequence_manager/task_queue_impl.h +++ b/base/task/sequence_manager/task_queue_impl.h
@@ -124,6 +124,7 @@ void RemoveFence(); bool HasActiveFence(); bool BlockedByFence() const; + // Implementation of TaskQueue::SetObserver. void SetOnNextWakeUpChangedCallback(OnNextWakeUpChangedCallback callback); @@ -149,6 +150,11 @@ // Used to check if we need to generate notifications about delayed work. bool HasPendingImmediateWork(); + bool has_pending_high_resolution_tasks() const { + return main_thread_only() + .delayed_incoming_queue.has_pending_high_resolution_tasks(); + } + WorkQueue* delayed_work_queue() { return main_thread_only().delayed_work_queue.get(); } @@ -225,8 +231,6 @@ return main_thread_only().sequence_manager; } - scoped_refptr<GracefulQueueShutdownHelper> GetGracefulQueueShutdownHelper(); - // Returns true if this queue is unregistered or task queue manager is deleted // and this queue can be safely deleted on any thread. bool IsUnregistered() const; @@ -259,6 +263,34 @@ OnNextWakeUpChangedCallback on_next_wake_up_changed_callback; }; + // A queue for holding delayed tasks before their delay has expired. + struct DelayedIncomingQueue { + public: + DelayedIncomingQueue(); + ~DelayedIncomingQueue(); + + void push(Task&& task); + void pop(); + bool empty() const { return queue_.empty(); } + size_t size() const { return queue_.size(); } + const Task& top() const { return queue_.top(); } + + bool has_pending_high_resolution_tasks() const { + return pending_high_res_tasks_; + } + + void SweepCancelledTasks(const SequenceManagerImpl*); + std::priority_queue<Task> TakeTasks() { return std::move(queue_); } + void AsValueInto(TimeTicks now, trace_event::TracedValue* state) const; + + private: + std::priority_queue<Task> queue_; + // Number of pending tasks in that need high resolution timing. + int pending_high_res_tasks_ = 0; + + DISALLOW_COPY_AND_ASSIGN(DelayedIncomingQueue); + }; + struct MainThreadOnly { MainThreadOnly(SequenceManagerImpl* sequence_manager, TaskQueueImpl* task_queue, @@ -275,7 +307,7 @@ std::unique_ptr<WorkQueue> delayed_work_queue; std::unique_ptr<WorkQueue> immediate_work_queue; - std::priority_queue<Task> delayed_incoming_queue; + DelayedIncomingQueue delayed_incoming_queue; ObserverList<MessageLoop::TaskObserver>::Unchecked task_observers; size_t set_index; HeapHandle heap_handle;
diff --git a/base/task/sequence_manager/tasks.cc b/base/task/sequence_manager/tasks.cc index 0172378..9fcbaa6 100644 --- a/base/task/sequence_manager/tasks.cc +++ b/base/task/sequence_manager/tasks.cc
@@ -10,7 +10,8 @@ Task::Task(internal::PostedTask posted_task, TimeTicks desired_run_time, internal::EnqueueOrder sequence_order, - internal::EnqueueOrder enqueue_order) + internal::EnqueueOrder enqueue_order, + internal::WakeUpResolution resolution) : PendingTask(posted_task.location, std::move(posted_task.callback), desired_run_time, @@ -23,6 +24,7 @@ // |PendingTask::sequence_num|'s type. static_assert(std::is_same<decltype(sequence_num), int>::value, ""); sequence_num = static_cast<int>(sequence_order); + this->is_high_res = resolution == internal::WakeUpResolution::kHigh; } namespace internal {
diff --git a/base/task/sequence_manager/tasks.h b/base/task/sequence_manager/tasks.h index 38b98a5..31e4920 100644 --- a/base/task/sequence_manager/tasks.h +++ b/base/task/sequence_manager/tasks.h
@@ -15,6 +15,8 @@ namespace internal { +enum class WakeUpResolution { kLow, kHigh }; + // Wrapper around PostTask method arguments and the assigned task type. // Eventually it becomes a PendingTask once accepted by a TaskQueueImpl. struct BASE_EXPORT PostedTask { @@ -68,7 +70,9 @@ Task(internal::PostedTask posted_task, TimeTicks desired_run_time, internal::EnqueueOrder sequence_order, - internal::EnqueueOrder enqueue_order = internal::EnqueueOrder()); + internal::EnqueueOrder enqueue_order = internal::EnqueueOrder(), + internal::WakeUpResolution wake_up_resolution = + internal::WakeUpResolution::kLow); internal::DelayedWakeUp delayed_wake_up() const { return internal::DelayedWakeUp{delayed_run_time, sequence_num};
diff --git a/base/task/sequence_manager/test/fake_task.cc b/base/task/sequence_manager/test/fake_task.cc index 779e12a..6fb40d7 100644 --- a/base/task/sequence_manager/test/fake_task.cc +++ b/base/task/sequence_manager/test/fake_task.cc
@@ -16,7 +16,9 @@ Nestable::kNestable, task_type), TimeTicks(), - internal::EnqueueOrder()) {} + internal::EnqueueOrder(), + internal::EnqueueOrder(), + internal::WakeUpResolution::kLow) {} FakeTaskTiming::FakeTaskTiming() : TaskTiming(false /* has_wall_time */, false /* has_thread_time */) {}
diff --git a/base/task/sequence_manager/test/sequence_manager_for_test.cc b/base/task/sequence_manager/test/sequence_manager_for_test.cc index 81b974b..7b22684f 100644 --- a/base/task/sequence_manager/test/sequence_manager_for_test.cc +++ b/base/task/sequence_manager/test/sequence_manager_for_test.cc
@@ -84,7 +84,6 @@ } size_t SequenceManagerForTest::QueuesToShutdownCount() { - TakeQueuesToGracefullyShutdownFromHelper(); return main_thread_only().queues_to_gracefully_shutdown.size(); }
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc index ed729663..bd2f236d 100644 --- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc +++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
@@ -7,6 +7,7 @@ #include "base/auto_reset.h" #include "base/time/tick_clock.h" #include "base/trace_event/trace_event.h" +#include "build/build_config.h" namespace base { namespace sequence_manager { @@ -120,6 +121,17 @@ } bool ThreadControllerWithMessagePumpImpl::DoWork() { + base::TimeTicks next_run_time; + return DoWorkImpl(&next_run_time); +} + +bool ThreadControllerWithMessagePumpImpl::DoDelayedWork( + TimeTicks* next_run_time) { + return DoWorkImpl(next_run_time); +} + +bool ThreadControllerWithMessagePumpImpl::DoWorkImpl( + base::TimeTicks* next_run_time) { DCHECK(main_thread_only().task_source); bool task_ran = false; @@ -152,28 +164,41 @@ main_thread_only().task_source->DelayTillNextTask(&lazy_now); DCHECK_GE(do_work_delay, TimeDelta()); // Schedule a continuation. + // TODO(altimin, gab): Make this more efficient by merging DoWork + // and DoDelayedWork and allowing returing base::TimeTicks() when we have + // immediate work. if (do_work_delay.is_zero()) { // Need to run new work immediately, but due to the contract of DoWork we // only need to return true to ensure that happens. + *next_run_time = lazy_now.Now(); return true; } else if (do_work_delay != TimeDelta::Max()) { + *next_run_time = lazy_now.Now() + do_work_delay; // Cancels any previously scheduled delayed wake-ups. - pump_->ScheduleDelayedWork(lazy_now.Now() + do_work_delay); + pump_->ScheduleDelayedWork(*next_run_time); + } else { + *next_run_time = base::TimeTicks::Max(); } return task_ran; } -bool ThreadControllerWithMessagePumpImpl::DoDelayedWork( - TimeTicks* next_run_time) { - // Delayed work is getting processed in DoWork(). - return false; -} - bool ThreadControllerWithMessagePumpImpl::DoIdleWork() { // RunLoop::Delegate knows whether we called Run() or RunUntilIdle(). if (ShouldQuitWhenIdle()) Quit(); +#if defined(OS_WIN) + bool need_high_res_mode = + main_thread_only().task_source->HasPendingHighResolutionTasks(); + if (main_thread_only().in_high_res_mode != need_high_res_mode) { + // On Windows we activate the high resolution timer so that the wait + // _if_ triggered by the timer happens with good resolution. If we don't + // do this the default resolution is 15ms which might not be acceptable + // for some tasks. + main_thread_only().in_high_res_mode = need_high_res_mode; + Time::ActivateHighResolutionTimer(need_high_res_mode); + } +#endif // defined(OS_WIN) return false; }
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.h b/base/task/sequence_manager/thread_controller_with_message_pump_impl.h index ea5fcfc..104d33d 100644 --- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.h +++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.h
@@ -49,20 +49,23 @@ void RemoveNestingObserver(RunLoop::NestingObserver* observer) override; const scoped_refptr<AssociatedThreadId>& GetAssociatedThread() const override; - private: - friend class DoWorkScope; - friend class RunScope; - + protected: // MessagePump::Delegate implementation. bool DoWork() override; bool DoDelayedWork(TimeTicks* next_run_time) override; bool DoIdleWork() override; + private: + friend class DoWorkScope; + friend class RunScope; + // RunLoop::Delegate implementation. void Run(bool application_tasks_allowed) override; void Quit() override; void EnsureWorkScheduled() override; + bool DoWorkImpl(base::TimeTicks* next_run_time); + struct MainThreadOnly { MainThreadOnly(); ~MainThreadOnly(); @@ -83,6 +86,9 @@ // Number of DoWork running, but only the inner-most one can take tasks. // Must be equal to |run_depth| or |run_depth - 1|. int do_work_depth = 0; + + // Whether high resolution timing is enabled or not. + bool in_high_res_mode = false; }; MainThreadOnly& main_thread_only() {
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc new file mode 100644 index 0000000..d9264b4 --- /dev/null +++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc
@@ -0,0 +1,148 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h" + +#include "base/test/mock_callback.h" +#include "base/test/simple_test_tick_clock.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +#include <queue> + +namespace base { +namespace sequence_manager { + +namespace { + +class ThreadControllerForTest + : public internal::ThreadControllerWithMessagePumpImpl { + public: + ThreadControllerForTest(std::unique_ptr<MessagePump> pump, + const TickClock* clock) + : ThreadControllerWithMessagePumpImpl(std::move(pump), clock) {} + + using ThreadControllerWithMessagePumpImpl::DoWork; + using ThreadControllerWithMessagePumpImpl::DoDelayedWork; + using ThreadControllerWithMessagePumpImpl::DoIdleWork; +}; + +class MockMessagePump : public MessagePump { + public: + MockMessagePump() {} + ~MockMessagePump() override {} + + MOCK_METHOD1(Run, void(MessagePump::Delegate*)); + MOCK_METHOD0(Quit, void()); + MOCK_METHOD0(ScheduleWork, void()); + MOCK_METHOD1(ScheduleDelayedWork, void(const TimeTicks&)); + MOCK_METHOD1(SetTimerSlack, void(TimerSlack)); +}; + +class FakeSequencedTaskSource : public internal::SequencedTaskSource { + public: + explicit FakeSequencedTaskSource(TickClock* clock) : clock_(clock) {} + ~FakeSequencedTaskSource() override = default; + + Optional<PendingTask> TakeTask() override { + if (tasks_.empty()) + return nullopt; + if (tasks_.front().delayed_run_time > clock_->NowTicks()) + return nullopt; + PendingTask task = std::move(tasks_.front()); + tasks_.pop(); + return task; + } + + void DidRunTask() override {} + + TimeDelta DelayTillNextTask(LazyNow* lazy_now) override { + if (tasks_.empty()) + return TimeDelta::Max(); + if (tasks_.front().delayed_run_time.is_null()) + return TimeDelta(); + if (lazy_now->Now() > tasks_.front().delayed_run_time) + return TimeDelta(); + return tasks_.front().delayed_run_time - lazy_now->Now(); + } + + void AddTask(PendingTask task) { + DCHECK(tasks_.empty() || task.delayed_run_time.is_null() || + tasks_.back().delayed_run_time < task.delayed_run_time); + tasks_.push(std::move(task)); + } + + bool HasPendingHighResolutionTasks() override { return false; } + + private: + TickClock* clock_; + std::queue<PendingTask> tasks_; +}; + +TimeTicks Seconds(int seconds) { + return TimeTicks() + TimeDelta::FromSeconds(seconds); +} + +} // namespace + +TEST(ThreadControllerWithMessagePumpTest, ScheduleDelayedWork) { + MockMessagePump* message_pump; + std::unique_ptr<MockMessagePump> pump = + std::make_unique<testing::StrictMock<MockMessagePump>>(); + message_pump = pump.get(); + + SimpleTestTickClock clock; + ThreadControllerForTest thread_controller(std::move(pump), &clock); + thread_controller.SetWorkBatchSize(1); + + FakeSequencedTaskSource task_source(&clock); + thread_controller.SetSequencedTaskSource(&task_source); + + base::TimeTicks next_run_time; + + MockCallback<OnceClosure> task1; + task_source.AddTask(PendingTask(FROM_HERE, task1.Get(), Seconds(10))); + MockCallback<OnceClosure> task2; + task_source.AddTask(PendingTask(FROM_HERE, task2.Get(), TimeTicks())); + MockCallback<OnceClosure> task3; + task_source.AddTask(PendingTask(FROM_HERE, task3.Get(), Seconds(20))); + + // Call a no-op DoWork. Expect that it doesn't do any work, but + // schedules a delayed wake-up appropriately. + clock.SetNowTicks(Seconds(5)); + EXPECT_CALL(*message_pump, ScheduleDelayedWork(Seconds(10))); + EXPECT_FALSE(thread_controller.DoWork()); + testing::Mock::VerifyAndClearExpectations(message_pump); + + // Call DoDelayedWork after the expiration of the delay. + // Expect that a task will run and the next delay will equal to |now| + // as we have immediate work to do. + clock.SetNowTicks(Seconds(11)); + EXPECT_CALL(task1, Run()).Times(1); + EXPECT_TRUE(thread_controller.DoDelayedWork(&next_run_time)); + EXPECT_EQ(next_run_time, Seconds(11)); + testing::Mock::VerifyAndClearExpectations(message_pump); + testing::Mock::VerifyAndClearExpectations(&task1); + + // Call DoWork immeidately after the previous call. Expect a new task + // to be run. + EXPECT_CALL(task2, Run()).Times(1); + EXPECT_CALL(*message_pump, ScheduleDelayedWork(Seconds(20))); + EXPECT_TRUE(thread_controller.DoWork()); + testing::Mock::VerifyAndClearExpectations(message_pump); + testing::Mock::VerifyAndClearExpectations(&task2); + + // Call DoDelayedWork for the last task and expect to be told + // about the lack of further delayed work + // (delay being base::TimeDelta::Max()). + clock.SetNowTicks(Seconds(21)); + EXPECT_CALL(task3, Run()).Times(1); + EXPECT_TRUE(thread_controller.DoDelayedWork(&next_run_time)); + EXPECT_EQ(next_run_time, TimeTicks::Max()); + testing::Mock::VerifyAndClearExpectations(message_pump); + testing::Mock::VerifyAndClearExpectations(&task3); +} + +} // namespace sequence_manager +} // namespace base
diff --git a/base/task/sequence_manager/time_domain.cc b/base/task/sequence_manager/time_domain.cc index 8ca32e756..72d0638 100644 --- a/base/task/sequence_manager/time_domain.cc +++ b/base/task/sequence_manager/time_domain.cc
@@ -50,30 +50,37 @@ DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); DCHECK_EQ(queue->GetTimeDomain(), this); LazyNow lazy_now(CreateLazyNow()); - SetNextWakeUpForQueue(queue, nullopt, &lazy_now); + SetNextWakeUpForQueue(queue, nullopt, internal::WakeUpResolution::kLow, + &lazy_now); } void TimeDomain::SetNextWakeUpForQueue( internal::TaskQueueImpl* queue, Optional<internal::DelayedWakeUp> wake_up, + internal::WakeUpResolution resolution, LazyNow* lazy_now) { DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); DCHECK_EQ(queue->GetTimeDomain(), this); DCHECK(queue->IsQueueEnabled() || !wake_up); Optional<TimeTicks> previous_wake_up; + Optional<internal::WakeUpResolution> previous_queue_resolution; if (!delayed_wake_up_queue_.empty()) previous_wake_up = delayed_wake_up_queue_.Min().wake_up.time; + if (queue->heap_handle().IsValid()) { + previous_queue_resolution = + delayed_wake_up_queue_.at(queue->heap_handle()).resolution; + } if (wake_up) { // Insert a new wake-up into the heap. if (queue->heap_handle().IsValid()) { // O(log n) delayed_wake_up_queue_.ChangeKey(queue->heap_handle(), - {wake_up.value(), queue}); + {wake_up.value(), resolution, queue}); } else { // O(log n) - delayed_wake_up_queue_.insert({wake_up.value(), queue}); + delayed_wake_up_queue_.insert({wake_up.value(), resolution, queue}); } } else { // Remove a wake-up from heap if present. @@ -85,6 +92,14 @@ if (!delayed_wake_up_queue_.empty()) new_wake_up = delayed_wake_up_queue_.Min().wake_up.time; + if (previous_queue_resolution && + *previous_queue_resolution == internal::WakeUpResolution::kHigh) { + pending_high_res_wake_up_count_--; + } + if (wake_up && resolution == internal::WakeUpResolution::kHigh) + pending_high_res_wake_up_count_++; + DCHECK_GE(pending_high_res_wake_up_count_, 0); + // TODO(kraynov): https://crbug.com/857101 Review the relationship with // SequenceManager's time. Right now it's not an issue since // VirtualTimeDomain doesn't invoke SequenceManager itself. @@ -137,5 +152,9 @@ // Can be overriden to trace some additional state. } +bool TimeDomain::HasPendingHighResolutionTasks() const { + return pending_high_res_wake_up_count_; +} + } // namespace sequence_manager } // namespace base
diff --git a/base/task/sequence_manager/time_domain.h b/base/task/sequence_manager/time_domain.h index e06f9cc..928abd0 100644 --- a/base/task/sequence_manager/time_domain.h +++ b/base/task/sequence_manager/time_domain.h
@@ -57,6 +57,7 @@ virtual Optional<TimeDelta> DelayTillNextTask(LazyNow* lazy_now) = 0; void AsValueInto(trace_event::TracedValue* state) const; + bool HasPendingHighResolutionTasks() const; protected: TimeDomain(); @@ -99,6 +100,7 @@ // NOTE: |lazy_now| is provided in TimeDomain's time. void SetNextWakeUpForQueue(internal::TaskQueueImpl* queue, Optional<internal::DelayedWakeUp> wake_up, + internal::WakeUpResolution resolution, LazyNow* lazy_now); // Remove the TaskQueue from any internal data sctructures. @@ -109,9 +111,14 @@ struct ScheduledDelayedWakeUp { internal::DelayedWakeUp wake_up; + internal::WakeUpResolution resolution; internal::TaskQueueImpl* queue; bool operator<=(const ScheduledDelayedWakeUp& other) const { + if (wake_up == other.wake_up) { + return static_cast<int>(resolution) <= + static_cast<int>(other.resolution); + } return wake_up <= other.wake_up; } @@ -128,6 +135,7 @@ internal::SequenceManagerImpl* sequence_manager_; // Not owned. internal::IntrusiveHeap<ScheduledDelayedWakeUp> delayed_wake_up_queue_; + int pending_high_res_wake_up_count_ = 0; scoped_refptr<internal::AssociatedThreadId> associated_thread_; DISALLOW_COPY_AND_ASSIGN(TimeDomain);
diff --git a/base/task/sequence_manager/time_domain_unittest.cc b/base/task/sequence_manager/time_domain_unittest.cc index 54efd761..0e343ea1 100644 --- a/base/task/sequence_manager/time_domain_unittest.cc +++ b/base/task/sequence_manager/time_domain_unittest.cc
@@ -318,5 +318,58 @@ task_queue2->UnregisterTaskQueue(); } +TEST_F(TimeDomainTest, HighResolutionWakeUps) { + TimeTicks now = time_domain_->Now(); + LazyNow lazy_now(now); + TimeTicks run_time1 = now + TimeDelta::FromMilliseconds(20); + TimeTicks run_time2 = now + TimeDelta::FromMilliseconds(40); + TaskQueueImplForTest q1(nullptr, time_domain_.get(), TaskQueue::Spec("test")); + TaskQueueImplForTest q2(nullptr, time_domain_.get(), TaskQueue::Spec("test")); + + // Add two high resolution wake-ups. + EXPECT_FALSE(time_domain_->HasPendingHighResolutionTasks()); + time_domain_->SetNextWakeUpForQueue( + &q1, internal::DelayedWakeUp{run_time1, 0}, + internal::WakeUpResolution::kHigh, &lazy_now); + EXPECT_TRUE(time_domain_->HasPendingHighResolutionTasks()); + time_domain_->SetNextWakeUpForQueue( + &q2, internal::DelayedWakeUp{run_time2, 0}, + internal::WakeUpResolution::kHigh, &lazy_now); + EXPECT_TRUE(time_domain_->HasPendingHighResolutionTasks()); + + // Remove one of the wake-ups. + time_domain_->SetNextWakeUpForQueue( + &q1, nullopt, internal::WakeUpResolution::kLow, &lazy_now); + EXPECT_TRUE(time_domain_->HasPendingHighResolutionTasks()); + + // Remove the second one too. + time_domain_->SetNextWakeUpForQueue( + &q2, nullopt, internal::WakeUpResolution::kLow, &lazy_now); + EXPECT_FALSE(time_domain_->HasPendingHighResolutionTasks()); + + // Change a low resolution wake-up to a high resolution one. + time_domain_->SetNextWakeUpForQueue( + &q1, internal::DelayedWakeUp{run_time1, 0}, + internal::WakeUpResolution::kLow, &lazy_now); + EXPECT_FALSE(time_domain_->HasPendingHighResolutionTasks()); + time_domain_->SetNextWakeUpForQueue( + &q1, internal::DelayedWakeUp{run_time1, 0}, + internal::WakeUpResolution::kHigh, &lazy_now); + EXPECT_TRUE(time_domain_->HasPendingHighResolutionTasks()); + + // Move a high resolution wake-up in time. + time_domain_->SetNextWakeUpForQueue( + &q1, internal::DelayedWakeUp{run_time2, 0}, + internal::WakeUpResolution::kHigh, &lazy_now); + EXPECT_TRUE(time_domain_->HasPendingHighResolutionTasks()); + + // Cancel the wake-up twice. + time_domain_->SetNextWakeUpForQueue( + &q1, nullopt, internal::WakeUpResolution::kLow, &lazy_now); + time_domain_->SetNextWakeUpForQueue( + &q1, nullopt, internal::WakeUpResolution::kLow, &lazy_now); + EXPECT_FALSE(time_domain_->HasPendingHighResolutionTasks()); +} + } // namespace sequence_manager } // namespace base
diff --git a/build/android/gyp/util/build_utils.py b/build/android/gyp/util/build_utils.py index 8f1ea090..32710e20 100644 --- a/build/android/gyp/util/build_utils.py +++ b/build/android/gyp/util/build_utils.py
@@ -338,7 +338,8 @@ zip_file.writestr(zipinfo, data, compress_type) -def DoZip(inputs, output, base_dir=None, compress_fn=None): +def DoZip(inputs, output, base_dir=None, compress_fn=None, + zip_prefix_path=None): """Creates a zip file from a list of files. Args: @@ -347,6 +348,7 @@ base_dir: Prefix to strip from inputs. compress_fn: Applied to each input to determine whether or not to compress. By default, items will be |zipfile.ZIP_STORED|. + zip_prefix_path: Path prepended to file path in zip file. """ input_tuples = [] for tup in inputs: @@ -358,11 +360,13 @@ input_tuples.sort(key=lambda tup: tup[0]) with zipfile.ZipFile(output, 'w') as outfile: for zip_path, fs_path in input_tuples: + if zip_prefix_path: + zip_path = os.path.join(zip_prefix_path, zip_path) compress = compress_fn(zip_path) if compress_fn else None AddToZipHermetic(outfile, zip_path, src_path=fs_path, compress=compress) -def ZipDir(output, base_dir, compress_fn=None): +def ZipDir(output, base_dir, compress_fn=None, zip_prefix_path=None): """Creates a zip file from a directory.""" inputs = [] for root, _, files in os.walk(base_dir): @@ -370,7 +374,8 @@ inputs.append(os.path.join(root, f)) with AtomicOutput(output) as f: - DoZip(inputs, f, base_dir, compress_fn=compress_fn) + DoZip(inputs, f, base_dir, compress_fn=compress_fn, + zip_prefix_path=zip_prefix_path) def MatchesGlob(path, filters):
diff --git a/build/android/pylib/results/json_results.py b/build/android/pylib/results/json_results.py index 3f87b46..c3bfa4c0 100644 --- a/build/android/pylib/results/json_results.py +++ b/build/android/pylib/results/json_results.py
@@ -106,7 +106,7 @@ 'status': status_as_string(r.GetType()), 'elapsed_time_ms': r.GetDuration(), 'output_snippet': unicode(r.GetLog(), errors='replace'), - 'losless_snippet': '', + 'losless_snippet': True, 'output_snippet_base64': '', 'links': r.GetLinks(), }
diff --git a/build/android/pylib/results/json_results_test.py b/build/android/pylib/results/json_results_test.py index e8b983b5..68e71f57 100755 --- a/build/android/pylib/results/json_results_test.py +++ b/build/android/pylib/results/json_results_test.py
@@ -175,6 +175,33 @@ [raw_results], global_tags=global_tags) self.assertEquals(['UNRELIABLE_RESULTS'], results_dict['global_tags']) + def testGenerateResultsDict_loslessSnippet(self): + result = base_test_result.BaseTestResult( + 'test.package.TestName', base_test_result.ResultType.FAIL) + log = 'blah-blah' + result.SetLog(log) + + all_results = base_test_result.TestRunResults() + all_results.AddResult(result) + + results_dict = json_results.GenerateResultsDict([all_results]) + self.assertEquals( + ['test.package.TestName'], + results_dict['all_tests']) + self.assertEquals(1, len(results_dict['per_iteration_data'])) + + iteration_result = results_dict['per_iteration_data'][0] + self.assertTrue('test.package.TestName' in iteration_result) + self.assertEquals(1, len(iteration_result['test.package.TestName'])) + + test_iteration_result = iteration_result['test.package.TestName'][0] + self.assertTrue('losless_snippet' in test_iteration_result) + self.assertTrue(test_iteration_result['losless_snippet']) + self.assertTrue('output_snippet' in test_iteration_result) + self.assertEquals(log, test_iteration_result['output_snippet']) + self.assertTrue('output_snippet_base64' in test_iteration_result) + self.assertEquals('', test_iteration_result['output_snippet_base64']) + if __name__ == '__main__': unittest.main(verbosity=2)
diff --git a/cc/paint/oop_pixeltest.cc b/cc/paint/oop_pixeltest.cc index 40a326e..56811dbed 100644 --- a/cc/paint/oop_pixeltest.cc +++ b/cc/paint/oop_pixeltest.cc
@@ -23,8 +23,10 @@ #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/client/raster_implementation.h" #include "gpu/command_buffer/client/raster_implementation_gles.h" +#include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/client/shared_memory_limits.h" #include "gpu/command_buffer/common/context_creation_attribs.h" +#include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/service/gr_shader_cache.h" #include "gpu/config/gpu_switches.h" #include "gpu/ipc/gl_in_process_context.h" @@ -163,24 +165,20 @@ int width = options.resource_size.width(); int height = options.resource_size.height(); - // Create and allocate a texture on the raster interface. - GLuint raster_texture_id; - + // Create and allocate a shared image on the raster interface. auto* raster_implementation = raster_context_provider_->RasterInterface(); - raster_texture_id = raster_implementation->CreateTexture( - false, gfx::BufferUsage::GPU_READ, viz::ResourceFormat::RGBA_8888); - raster_implementation->TexStorage2D(raster_texture_id, width, height); - raster_implementation->TexParameteri(raster_texture_id, - GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - EXPECT_EQ(raster_implementation->GetError(), - static_cast<unsigned>(GL_NO_ERROR)); + auto* sii = raster_context_provider_->SharedImageInterface(); + uint32_t flags = gpu::SHARED_IMAGE_USAGE_RASTER | + gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION; + gpu::Mailbox mailbox = sii->CreateSharedImage( + viz::ResourceFormat::RGBA_8888, gfx::Size(width, height), + options.color_space, flags); + EXPECT_TRUE(mailbox.Verify()); + raster_implementation->WaitSyncTokenCHROMIUM( + sii->GenUnverifiedSyncToken().GetConstData()); RasterColorSpace color_space(options.color_space, ++color_space_id_); - gpu::Mailbox mailbox; - raster_implementation->ProduceTextureDirect(raster_texture_id, - mailbox.name); if (options.preclear) { raster_implementation->BeginRasterCHROMIUM( options.preclear_color, options.msaa_sample_count, @@ -225,8 +223,9 @@ gl->DeleteTextures(1, &gl_texture_id); gl->DeleteFramebuffers(1, &fbo_id); - gl->OrderingBarrierCHROMIUM(); - raster_implementation->DeleteTextures(1, &raster_texture_id); + gpu::SyncToken sync_token; + gl->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); + sii->DestroySharedImage(sync_token, mailbox); // Swizzle rgba->bgra if needed. std::vector<SkPMColor> colors;
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 85dc63d2f..4d2e7de 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -856,7 +856,7 @@ } void LayerTreeHost::ApplyViewportChanges(const ScrollAndScaleSet& info) { - gfx::Vector2dF inner_viewport_scroll_delta; + gfx::ScrollOffset inner_viewport_scroll_delta; if (info.inner_viewport_scroll.element_id) inner_viewport_scroll_delta = info.inner_viewport_scroll.scroll_delta; @@ -871,9 +871,8 @@ // value, then the layer can early out without needing a full commit. if (viewport_layers_.inner_viewport_scroll) { viewport_layers_.inner_viewport_scroll->SetScrollOffsetFromImplSide( - gfx::ScrollOffsetWithDelta( - viewport_layers_.inner_viewport_scroll->CurrentScrollOffset(), - inner_viewport_scroll_delta)); + viewport_layers_.inner_viewport_scroll->CurrentScrollOffset() + + inner_viewport_scroll_delta); } ApplyPageScaleDeltaFromImplSide(info.page_scale_delta); @@ -914,8 +913,8 @@ Layer* layer = LayerByElementId(info->scrolls[i].element_id); if (!layer) continue; - layer->SetScrollOffsetFromImplSide(gfx::ScrollOffsetWithDelta( - layer->CurrentScrollOffset(), info->scrolls[i].scroll_delta)); + layer->SetScrollOffsetFromImplSide(layer->CurrentScrollOffset() + + info->scrolls[i].scroll_delta); SetNeedsUpdateLayers(); } for (size_t i = 0; i < info->scrollbars.size(); ++i) {
diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h index f7a0285a..e6e1c360 100644 --- a/cc/trees/layer_tree_host_client.h +++ b/cc/trees/layer_tree_host_client.h
@@ -10,11 +10,11 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "cc/input/browser_controls_state.h" +#include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/geometry/vector2d_f.h" namespace gfx { struct PresentationFeedback; -class Vector2dF; } namespace viz { @@ -25,7 +25,7 @@ struct ApplyViewportChangesArgs { // Scroll offset delta of the inner (visual) viewport. - gfx::Vector2dF inner_delta; + gfx::ScrollOffset inner_delta; // Elastic overscroll effect offset delta. This is used only on Mac. a.k.a // "rubber-banding" overscroll.
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h index a2ee2f0..14f797f 100644 --- a/cc/trees/layer_tree_host_common.h +++ b/cc/trees/layer_tree_host_common.h
@@ -135,9 +135,7 @@ struct CC_EXPORT ScrollUpdateInfo { ElementId element_id; - // TODO(miletus): Use ScrollOffset once LayerTreeHost/Blink fully supports - // fractional scroll offset. - gfx::Vector2d scroll_delta; + gfx::ScrollOffset scroll_delta; bool operator==(const ScrollUpdateInfo& other) const; };
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 73d5e8e..ca072ef 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -297,7 +297,7 @@ static ::testing::AssertionResult ScrollInfoContains( const ScrollAndScaleSet& scroll_info, ElementId id, - const gfx::Vector2d& scroll_delta) { + const gfx::ScrollOffset& scroll_delta) { int times_encountered = 0; for (size_t i = 0; i < scroll_info.scrolls.size(); ++i) { @@ -963,7 +963,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { gfx::ScrollOffset scroll_offset(20, 30); - gfx::Vector2d scroll_delta(11, -15); + gfx::ScrollOffset scroll_delta(11, -15); auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1); auto* root = root_owned.get(); @@ -980,14 +980,14 @@ std::unique_ptr<ScrollAndScaleSet> scroll_info; - root->ScrollBy(scroll_delta); + root->ScrollBy(gfx::ScrollOffsetToVector2dF(scroll_delta)); scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(scroll_info->scrolls.size(), 1u); EXPECT_TRUE( ScrollInfoContains(*scroll_info, root->element_id(), scroll_delta)); - gfx::Vector2d scroll_delta2(-5, 27); - root->ScrollBy(scroll_delta2); + gfx::ScrollOffset scroll_delta2(-5, 27); + root->ScrollBy(gfx::ScrollOffsetToVector2dF(scroll_delta2)); scroll_info = host_impl_->ProcessScrollDeltas(); ASSERT_EQ(scroll_info->scrolls.size(), 1u); EXPECT_TRUE(ScrollInfoContains(*scroll_info, root->element_id(), @@ -1131,8 +1131,10 @@ // We should still be scrolling, because the scrolled layer also exists in the // new tree. - gfx::Vector2d scroll_delta(0, 10); - host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); + gfx::ScrollOffset scroll_delta(0, 10); + host_impl_->ScrollBy( + UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(scroll_delta)) + .get()); host_impl_->ScrollEnd(EndState().get()); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); @@ -1667,7 +1669,7 @@ EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing()); BeginImplFrameAndAnimate(begin_frame_args, start_time + base::TimeDelta::FromMilliseconds(150)); - EXPECT_VECTOR_EQ(ScrollOffsetToVector2dF(current_offset), + EXPECT_VECTOR_EQ(gfx::ScrollOffsetToVector2dF(current_offset), overflow->CurrentScrollOffset()); } @@ -2259,7 +2261,7 @@ host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains( *scroll_info.get(), scroll_layer->element_id(), - gfx::Vector2d(0, scroll_delta.y() / page_scale_delta))); + gfx::ScrollOffset(0, scroll_delta.y() / page_scale_delta))); } } @@ -2879,7 +2881,7 @@ host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), - gfx::Vector2d(-10, -10))); + gfx::ScrollOffset(-10, -10))); } // Two-finger panning should work when starting fully zoomed out. @@ -2913,7 +2915,7 @@ host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, 2.f); EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), - gfx::Vector2d(10, 10))); + gfx::ScrollOffset(10, 10))); } } @@ -2954,7 +2956,7 @@ host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, page_scale_delta); EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), - gfx::Vector2d(0, -1))); + gfx::ScrollOffset(0, -1))); // Verify this scroll delta is consistent with the snapped position of the // scroll layer. @@ -3196,7 +3198,7 @@ host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, 2); EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), - gfx::Vector2d(-50, -50))); + gfx::ScrollOffset(-50, -50))); } start_time += base::TimeDelta::FromSeconds(10); @@ -3249,7 +3251,7 @@ EXPECT_EQ(scroll_info->page_scale_delta, min_page_scale); // Pushed to (0,0) via clamping against contents layer size. EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), - gfx::Vector2d(-50, -50))); + gfx::ScrollOffset(-50, -50))); } } @@ -3435,7 +3437,7 @@ host_impl_->ProcessScrollDeltas(); EXPECT_EQ(scroll_info->page_scale_delta, target_scale); EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(), - gfx::Vector2d(-50, -50))); + gfx::ScrollOffset(-50, -50))); } TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) { @@ -6553,7 +6555,7 @@ EXPECT_EQ(viewport_size, root_container->bounds()); gfx::Vector2d scroll_delta(0, 10); - gfx::Vector2d expected_scroll_delta = scroll_delta; + gfx::ScrollOffset expected_scroll_delta(scroll_delta); LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer(); gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); EXPECT_EQ( @@ -6600,7 +6602,7 @@ EXPECT_EQ(viewport_size, root_container->bounds()); gfx::Vector2d scroll_delta(0, 10); - gfx::Vector2d expected_scroll_delta = scroll_delta; + gfx::ScrollOffset expected_scroll_delta(scroll_delta); LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer(); gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); EXPECT_EQ( @@ -6705,7 +6707,7 @@ DrawFrame(); gfx::Vector2d scroll_delta(0, 10); - gfx::Vector2d expected_scroll_delta(scroll_delta); + gfx::ScrollOffset expected_scroll_delta(scroll_delta); gfx::ScrollOffset expected_max_scroll(outer_scroll->MaxScrollOffset()); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -6788,7 +6790,7 @@ ->children[0]; EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child_layer->element_id(), - gfx::Vector2d(0, -5))); + gfx::ScrollOffset(0, -5))); // The child should not have scrolled. ExpectNone(*scroll_info.get(), child->element_id()); @@ -6965,8 +6967,9 @@ ->test_properties() ->children[0]; LayerImpl* grand_child = child->test_properties()->children[0]; - EXPECT_TRUE(ScrollInfoContains( - *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, -2))); + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), + grand_child->element_id(), + gfx::ScrollOffset(0, -2))); // The child should not have scrolled. ExpectNone(*scroll_info.get(), child->element_id()); @@ -6989,11 +6992,12 @@ // The child should have scrolled up to its limit. EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(), - gfx::Vector2d(0, -3))); + gfx::ScrollOffset(0, -3))); // The grand child should not have scrolled. - EXPECT_TRUE(ScrollInfoContains( - *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, -2))); + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), + grand_child->element_id(), + gfx::ScrollOffset(0, -2))); // After scrolling the parent, another scroll on the opposite direction // should still scroll the child. @@ -7013,12 +7017,13 @@ scroll_info = host_impl_->ProcessScrollDeltas(); // The grand child should have scrolled. - EXPECT_TRUE(ScrollInfoContains( - *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, 5))); + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), + grand_child->element_id(), + gfx::ScrollOffset(0, 5))); // The child should not have scrolled. EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(), - gfx::Vector2d(0, -3))); + gfx::ScrollOffset(0, -3))); // Scrolling should be adjusted from viewport space. host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 2.f, 2.f); @@ -7038,8 +7043,9 @@ scroll_info = host_impl_->ProcessScrollDeltas(); // Should have scrolled by half the amount in layer space (5 - 2/2) - EXPECT_TRUE(ScrollInfoContains( - *scroll_info.get(), grand_child->element_id(), gfx::Vector2d(0, 4))); + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), + grand_child->element_id(), + gfx::ScrollOffset(0, 4))); } } TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { @@ -7082,13 +7088,15 @@ host_impl_->active_tree()->SetDeviceViewportSize(surface_size); DrawFrame(); { - gfx::Vector2d scroll_delta(0, 4); + gfx::ScrollOffset scroll_delta(0, 4); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL) .thread); - host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); + host_impl_->ScrollBy( + UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(scroll_delta)) + .get()); host_impl_->ScrollEnd(EndState().get()); std::unique_ptr<ScrollAndScaleSet> scroll_info = @@ -7218,18 +7226,21 @@ // The layer should have scrolled down in its local coordinates. std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(), - gfx::Vector2d(0, gesture_scroll_delta.x()))); + EXPECT_TRUE( + ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(), + gfx::ScrollOffset(0, gesture_scroll_delta.x()))); // Reset and scroll down with the wheel. SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF()); - gfx::Vector2d wheel_scroll_delta(0, 10); + gfx::ScrollOffset wheel_scroll_delta(0, 10); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL) .thread); - host_impl_->ScrollBy(UpdateState(gfx::Point(), wheel_scroll_delta).get()); + host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF( + wheel_scroll_delta)) + .get()); host_impl_->ScrollEnd(EndState().get()); // The layer should have scrolled down in its local coordinates. @@ -7289,9 +7300,9 @@ // The child layer should have scrolled down in its local coordinates an // amount proportional to the angle between it and the input scroll delta. - gfx::Vector2d expected_scroll_delta( - 0, - gesture_scroll_delta.y() * std::cos(gfx::DegToRad(child_layer_angle))); + gfx::ScrollOffset expected_scroll_delta( + 0, std::floor(gesture_scroll_delta.y() * + std::cos(gfx::DegToRad(child_layer_angle)))); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id, @@ -7315,9 +7326,9 @@ // The child layer should have scrolled down in its local coordinates an // amount proportional to the angle between it and the input scroll delta. - gfx::Vector2d expected_scroll_delta( - 0, - -gesture_scroll_delta.x() * std::sin(gfx::DegToRad(child_layer_angle))); + gfx::ScrollOffset expected_scroll_delta( + 0, std::floor(-gesture_scroll_delta.x() * + std::sin(gfx::DegToRad(child_layer_angle)))); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id, @@ -7364,21 +7375,21 @@ std::unique_ptr<ScrollAndScaleSet> scroll_info; - gfx::Vector2d gesture_scroll_deltas[4]; - gesture_scroll_deltas[0] = gfx::Vector2d(4, 10); - gesture_scroll_deltas[1] = gfx::Vector2d(4, 10); - gesture_scroll_deltas[2] = gfx::Vector2d(10, 0); - gesture_scroll_deltas[3] = gfx::Vector2d(10, 0); + gfx::ScrollOffset gesture_scroll_deltas[4]; + gesture_scroll_deltas[0] = gfx::ScrollOffset(4, 10); + gesture_scroll_deltas[1] = gfx::ScrollOffset(4, 10); + gesture_scroll_deltas[2] = gfx::ScrollOffset(10, 0); + gesture_scroll_deltas[3] = gfx::ScrollOffset(10, 0); - gfx::Vector2d expected_scroll_deltas[4]; + gfx::ScrollOffset expected_scroll_deltas[4]; // Perspective affects the vertical delta by a different // amount depending on the vertical position of the |viewport_point|. - expected_scroll_deltas[0] = gfx::Vector2d(2, 9); - expected_scroll_deltas[1] = gfx::Vector2d(1, 4); + expected_scroll_deltas[0] = gfx::ScrollOffset(2, 9); + expected_scroll_deltas[1] = gfx::ScrollOffset(1, 4); // Deltas which start with the same vertical position of the // |viewport_point| are subject to identical perspective effects. - expected_scroll_deltas[2] = gfx::Vector2d(5, 0); - expected_scroll_deltas[3] = gfx::Vector2d(5, 0); + expected_scroll_deltas[2] = gfx::ScrollOffset(5, 0); + expected_scroll_deltas[3] = gfx::ScrollOffset(5, 0); gfx::Point viewport_point(1, 1); @@ -7394,8 +7405,11 @@ InputHandler::TOUCHSCREEN) .thread); host_impl_->ScrollBy( - UpdateState(viewport_point, gesture_scroll_deltas[i]).get()); - viewport_point += gesture_scroll_deltas[i]; + UpdateState(viewport_point, + gfx::ScrollOffsetToVector2dF(gesture_scroll_deltas[i])) + .get()); + viewport_point += + gfx::ScrollOffsetToFlooredVector2d(gesture_scroll_deltas[i]); host_impl_->ScrollEnd(EndState().get()); scroll_info = host_impl_->ProcessScrollDeltas(); @@ -7438,18 +7452,21 @@ // amount. std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(), - gfx::Vector2d(0, scroll_delta.y() / scale))); + EXPECT_TRUE( + ScrollInfoContains(*scroll_info.get(), scroll_layer->element_id(), + gfx::ScrollOffset(0, scroll_delta.y() / scale))); // Reset and scroll down with the wheel. SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF()); - gfx::Vector2d wheel_scroll_delta(0, 10); + gfx::ScrollOffset wheel_scroll_delta(0, 10); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL) .thread); - host_impl_->ScrollBy(UpdateState(gfx::Point(), wheel_scroll_delta).get()); + host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF( + wheel_scroll_delta)) + .get()); host_impl_->ScrollEnd(EndState().get()); // It should apply the scale factor to the scroll delta for the wheel event. @@ -7618,7 +7635,8 @@ host_impl_->DrawLayers(&frame); host_impl_->DidDrawAllLayers(frame); EXPECT_FALSE(frame.has_no_damage); - CheckLayerScrollDelta(scroll_layer, ScrollOffsetToVector2dF(scroll_offset)); + CheckLayerScrollDelta(scroll_layer, + gfx::ScrollOffsetToVector2dF(scroll_offset)); } TEST_F(LayerTreeHostImplTest, @@ -7656,7 +7674,7 @@ host_impl_->DidDrawAllLayers(frame); EXPECT_TRUE(frame.has_no_damage); CheckLayerScrollDelta(scroll_layer, - ScrollOffsetToVector2dF(gfx::ScrollOffset())); + gfx::ScrollOffsetToVector2dF(gfx::ScrollOffset())); } TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 112d802..223c0dd 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -3239,8 +3239,7 @@ void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override { gfx::ScrollOffset offset = scroll_layer_->CurrentScrollOffset(); - scroll_layer_->SetScrollOffset( - ScrollOffsetWithDelta(offset, args.inner_delta)); + scroll_layer_->SetScrollOffset(offset + args.inner_delta); layer_tree_host()->SetPageScaleFactorAndLimits(args.page_scale_delta, 0.5f, 2.f); } @@ -3326,7 +3325,7 @@ void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override { EXPECT_TRUE(sent_gesture_); - EXPECT_EQ(gfx::Vector2dF(50, 50), args.inner_delta); + EXPECT_EQ(gfx::ScrollOffset(50, 50), args.inner_delta); EXPECT_EQ(2, args.page_scale_delta); auto* scroll_layer = layer_tree_host()->inner_viewport_scroll_layer();
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc index c4fa5bc..13e7b3e0 100644 --- a/cc/trees/property_tree.cc +++ b/cc/trees/property_tree.cc
@@ -1503,18 +1503,17 @@ gfx::ScrollOffset scroll_delta = PullDeltaForMainThread(map_entry.second.get()); - gfx::Vector2d scroll_delta_vector(scroll_delta.x(), scroll_delta.y()); ElementId id = map_entry.first; if (!scroll_delta.IsZero()) { if (id == inner_viewport_scroll_element_id) { // Inner (visual) viewport is stored separately. scroll_info->inner_viewport_scroll.element_id = id; - scroll_info->inner_viewport_scroll.scroll_delta = scroll_delta_vector; + scroll_info->inner_viewport_scroll.scroll_delta = scroll_delta; } else { LayerTreeHostCommon::ScrollUpdateInfo scroll; scroll.element_id = id; - scroll.scroll_delta = scroll_delta_vector; + scroll.scroll_delta = scroll_delta; scroll_info->scrolls.push_back(scroll); } }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 791adb7..0b561c8 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -255,6 +255,7 @@ "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java", "//components/autofill/android:autofill_java", "//components/background_task_scheduler:background_task_scheduler_java", + "//components/background_task_scheduler:background_task_scheduler_task_ids_java", "//components/bookmarks/common/android:bookmarks_java", "//components/contextual_search/content:mojo_bindings_java", "//components/crash/android:java", @@ -298,6 +299,7 @@ "//net/android:net_java", "//printing:printing_java", "//services/data_decoder/public/cpp/android:safe_json_java", + "//services/network/public/mojom:mojom_java", "//services/service_manager/public/java:service_manager_java", "//services/service_manager/public/mojom:mojom_java", "//services/shape_detection:shape_detection_java", @@ -322,10 +324,12 @@ "//third_party/blink/public:android_mojo_bindings_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", + "//third_party/blink/public/mojom:mojom_platform_java", "//third_party/cacheinvalidation:cacheinvalidation_javalib", "//third_party/cacheinvalidation:cacheinvalidation_proto_java", "//third_party/cct_dynamic_module:cct_dynamic_module_java", "//third_party/custom_tabs_client:custom_tabs_support_java", + "//third_party/feed:feed_lib_proto_java", "//third_party/gif_player:gif_player_java", "//third_party/jsr-305:jsr_305_javalib", "//third_party/protobuf:protobuf_lite_javalib", @@ -602,8 +606,13 @@ "//chrome/android:chrome_java", "//chrome/test/android:chrome_java_test_support", "//content/public/android:content_java", + "//content/public/test/android:content_java_test_support", + "//net/android:net_java_test_support", + "//third_party/android_deps:android_support_v4_java", + "//third_party/android_support_test_runner:runner_java", "//third_party/custom_tabs_client:custom_tabs_support_java", "//third_party/espresso:espresso_all_java", + "//third_party/junit:junit", ] } @@ -638,10 +647,13 @@ "//components/autofill/android:autofill_java", "//components/background_task_scheduler:background_task_scheduler_java", "//components/background_task_scheduler:background_task_scheduler_javatests", + "//components/background_task_scheduler:background_task_scheduler_task_ids_java", "//components/bookmarks/common/android:bookmarks_java", "//components/crash/android:javatests", "//components/dom_distiller/core/android:dom_distiller_core_java", "//components/download/internal/background_service:internal_java", + "//components/download/public/common:public_java", + "//components/embedder_support/android:content_view_java", "//components/embedder_support/android:web_contents_delegate_java", "//components/feature_engagement:feature_engagement_java", "//components/gcm_driver/android:gcm_driver_java", @@ -679,7 +691,9 @@ "//services:service_javatests", "//services/device/public/java:geolocation_java", "//services/device/public/java:geolocation_java_test_support", + "//services/network/public/mojom:mojom_java", "//services/service_manager/public/java:service_manager_java", + "//third_party/android_data_chart:android_data_chart_java", "//third_party/android_deps:android_arch_lifecycle_common_java", "//third_party/android_deps:android_support_annotations_java", "//third_party/android_deps:android_support_design_java", @@ -693,7 +707,9 @@ "//third_party/blink/public:android_mojo_bindings_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", + "//third_party/blink/public/mojom:mojom_platform_java", "//third_party/cacheinvalidation:cacheinvalidation_javalib", + "//third_party/cct_dynamic_module:cct_dynamic_module_java", "//third_party/custom_tabs_client:custom_tabs_support_java", "//third_party/espresso:espresso_all_java", "//third_party/hamcrest:hamcrest_java", @@ -1300,6 +1316,8 @@ java_files = [ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java" ] deps = [ ":chrome_public_base_module_java", + "//base:base_java", + "//third_party/protobuf:protobuf_lite_javalib", # This exists here because com.google.protobuf.nano is needed in tests, # but that code is stripped out via proguard. Adding this deps adds
diff --git a/chrome/android/java/res/values/values.xml b/chrome/android/java/res/values/values.xml index 34e6fc6..9cda9a8 100644 --- a/chrome/android/java/res/values/values.xml +++ b/chrome/android/java/res/values/values.xml
@@ -57,6 +57,7 @@ <string name="help_context_sad_tab">mobile_awsnap</string> <string name="help_context_clear_browsing_data">clear_browsing_data</string> <string name="help_context_change_sync_passphrase">change_sync_passphrase</string> + <string name="help_context_sync_and_services">sync_and_services</string> <!-- TODO(peconn): Add help section. --> <!-- <string name="help_context_suggestions">mobile_content_suggestions</string> -->
diff --git a/chrome/android/java/res/xml/developer_preferences.xml b/chrome/android/java/res/xml/developer_preferences.xml new file mode 100644 index 0000000..e619047 --- /dev/null +++ b/chrome/android/java/res/xml/developer_preferences.xml
@@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2018 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- TODO(eseckler): Add tracing preferences. --> +</PreferenceScreen>
diff --git a/chrome/android/java/res/xml/main_preferences.xml b/chrome/android/java/res/xml/main_preferences.xml index 1d038396..8e6a4b28 100644 --- a/chrome/android/java/res/xml/main_preferences.xml +++ b/chrome/android/java/res/xml/main_preferences.xml
@@ -95,9 +95,14 @@ android:order="17" android:title="@string/menu_downloads"/> <Preference + android:fragment="org.chromium.chrome.browser.preferences.developer.DeveloperPreferences" + android:key="developer" + android:order="18" + android:title="@string/prefs_developer"/> + <Preference android:fragment="org.chromium.chrome.browser.preferences.AboutChromePreferences" android:key="about_chrome" - android:order="18" + android:order="19" android:title="@string/prefs_about_chrome"/> </PreferenceScreen>
diff --git a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml index 04fff5b..10fba98 100644 --- a/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml +++ b/chrome/android/java/res_autofill_assistant/layout/autofill_assistant_sheet.xml
@@ -8,6 +8,7 @@ android:id="@+id/autofill_assistant" android:layout_width="match_parent" android:layout_height="match_parent" + android:paddingTop="@dimen/control_container_height" android:visibility="invisible" android:gravity="bottom">
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java index 91185f2b..f693fe85 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
@@ -19,7 +19,6 @@ import org.chromium.base.ContextUtils; import org.chromium.base.DiscardableReferencePool; import org.chromium.base.Log; -import org.chromium.base.Supplier; import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; import org.chromium.base.annotations.MainDex; @@ -30,6 +29,7 @@ import org.chromium.build.BuildHooks; import org.chromium.build.BuildHooksAndroid; import org.chromium.build.BuildHooksConfig; +import org.chromium.chrome.browser.crash.ApplicationStatusTracker; import org.chromium.chrome.browser.crash.PureJavaExceptionHandler; import org.chromium.chrome.browser.crash.PureJavaExceptionReporter; import org.chromium.chrome.browser.customtabs.CustomTabsConnection; @@ -71,17 +71,10 @@ } checkAppBeingReplaced(); - // Renderers and GPU process have command line passed to them via IPC + // Renderer and GPU processes have command line passed to them via IPC // (see ChildProcessService.java). - Supplier<Boolean> shouldUseDebugFlags = new Supplier<Boolean>() { - @Override - public Boolean get() { - ChromePreferenceManager manager = ChromePreferenceManager.getInstance(); - return manager.readBoolean( - ChromePreferenceManager.COMMAND_LINE_ON_NON_ROOTED_ENABLED_KEY, false); - } - }; - CommandLineInitUtil.initCommandLine(COMMAND_LINE_FILE, shouldUseDebugFlags); + CommandLineInitUtil.initCommandLine( + COMMAND_LINE_FILE, ChromeApplication::shouldUseDebugFlags); // Requires command-line flags. TraceEvent.maybeEnableEarlyTracing(); @@ -92,17 +85,16 @@ // Chrome is just the browser process). ApplicationStatus.initialize(this); + // Register application status listener for crashes, this needs to be done as early as + // possible so that this value is set before any crashes are reported. + ApplicationStatusTracker.getInstance().registerListener(); + // Only browser process requires custom resources. BuildHooksAndroid.initCustomResources(this); // Disable MemoryPressureMonitor polling when Chrome goes to the background. - ApplicationStatus.registerApplicationStateListener(newState -> { - if (newState == ApplicationState.HAS_RUNNING_ACTIVITIES) { - MemoryPressureMonitor.INSTANCE.enablePolling(); - } else if (newState == ApplicationState.HAS_STOPPED_ACTIVITIES) { - MemoryPressureMonitor.INSTANCE.disablePolling(); - } - }); + ApplicationStatus.registerApplicationStateListener( + ChromeApplication::updateMemoryPressurePolling); // Not losing much to not cover the below conditional since it just has simple setters. TraceEvent.end("ChromeApplication.attachBaseContext"); @@ -122,6 +114,19 @@ AsyncTask.takeOverAndroidThreadPool(); } + private static Boolean shouldUseDebugFlags() { + return ChromePreferenceManager.getInstance().readBoolean( + ChromePreferenceManager.COMMAND_LINE_ON_NON_ROOTED_ENABLED_KEY, false); + } + + private static void updateMemoryPressurePolling(@ApplicationState int newState) { + if (newState == ApplicationState.HAS_RUNNING_ACTIVITIES) { + MemoryPressureMonitor.INSTANCE.enablePolling(); + } else if (newState == ApplicationState.HAS_STOPPED_ACTIVITIES) { + MemoryPressureMonitor.INSTANCE.disablePolling(); + } + } + /** Ensure this application object is not out-of-date. */ private void checkAppBeingReplaced() { // During app update the old apk can still be triggered by broadcasts and spin up an
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index 6e3b3e1..9f3afae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -202,6 +202,7 @@ "ContextualSuggestionsIPHReverseScroll"; public static final String CUSTOM_CONTEXT_MENU = "CustomContextMenu"; public static final String CUSTOM_FEEDBACK_UI = "CustomFeedbackUi"; + public static final String DEVELOPER_PREFERENCES = "DeveloperPreferences"; // Enables the Data Reduction Proxy menu item in the main menu rather than under Settings on // Android. public static final String DATA_REDUCTION_MAIN_MENU = "DataReductionProxyMainMenu";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java index 6f21dc2..f93e485 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java
@@ -10,9 +10,11 @@ import android.content.Intent; import android.content.pm.ResolveInfo; import android.content.res.Resources; +import android.graphics.Bitmap; import android.net.Uri; import android.os.RemoteException; import android.support.annotation.Nullable; +import android.support.customtabs.trusted.TrustedWebActivityService; import android.support.customtabs.trusted.TrustedWebActivityServiceConnectionManager; import android.support.customtabs.trusted.TrustedWebActivityServiceWrapper; @@ -36,9 +38,8 @@ /** * Creates a TrustedWebActivityService. */ - public TrustedWebActivityClient() { - mConnection = new TrustedWebActivityServiceConnectionManager( - ContextUtils.getApplicationContext()); + public TrustedWebActivityClient(TrustedWebActivityServiceConnectionManager connection) { + mConnection = connection; } /** @@ -85,18 +86,17 @@ return; } - int smallIconId = service.getSmallIconId(); - if (smallIconId == -1) { + int id = service.getSmallIconId(); + if (id == TrustedWebActivityService.NO_ID) { return; } - String packageName = service.getComponentName().getPackageName(); - + Bitmap bitmap = service.getSmallIconBitmap(); if (!builder.hasStatusBarIconBitmap()) { - builder.setStatusBarIconForRemoteApp(smallIconId, packageName); + builder.setStatusBarIconForUntrustedRemoteApp(id, bitmap); } if (!builder.hasSmallIconForContent()) { - builder.setContentSmallIconForRemoteApp(smallIconId, packageName); + builder.setContentSmallIconForUntrustedRemoteApp(bitmap); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/ApplicationStatusTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/ApplicationStatusTracker.java new file mode 100644 index 0000000..2094c50d --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/ApplicationStatusTracker.java
@@ -0,0 +1,57 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.crash; + +import org.chromium.base.ApplicationState; +import org.chromium.base.ApplicationStatus; +import org.chromium.base.ThreadUtils; + +/** + * This class updates crash keys when the application state changes. + */ +public class ApplicationStatusTracker { + private static final String APP_FOREGROUND = "app_foreground"; + private static final String APP_BACKGROUND = "app_background"; + + private static class Holder { + static final ApplicationStatusTracker INSTANCE = new ApplicationStatusTracker(); + } + + private String mCurrentState; + + private ApplicationStatusTracker() {} + + public void registerListener() { + setApplicationStatus(ApplicationStatus.getStateForApplication()); + ApplicationStatus.registerApplicationStateListener(this::setApplicationStatus); + } + + private void setApplicationStatus(@ApplicationState int state) { + ThreadUtils.assertOnUiThread(); + String appStatus; + // TODO(wnwen): Add foreground service as another state. + if (isApplicationInForeground(state)) { + appStatus = APP_FOREGROUND; + } else { + appStatus = APP_BACKGROUND; + } + if (!appStatus.equals(mCurrentState)) { + mCurrentState = appStatus; + CrashKeys.getInstance().set(CrashKeyIndex.APPLICATION_STATUS, appStatus); + } + } + + private static boolean isApplicationInForeground(@ApplicationState int state) { + return state == ApplicationState.HAS_RUNNING_ACTIVITIES + || state == ApplicationState.HAS_PAUSED_ACTIVITIES; + } + + /** + * @return The shared instance of this class. + */ + public static ApplicationStatusTracker getInstance() { + return Holder.INSTANCE; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/CrashKeys.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/CrashKeys.java index bf8dcc3c..79eae23 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/CrashKeys.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/CrashKeys.java
@@ -21,9 +21,8 @@ * </ol> */ public class CrashKeys { - private static final String[] KEYS = new String[] { - "loaded_dynamic_module", "active_dynamic_module", - }; + private static final String[] KEYS = + new String[] {"loaded_dynamic_module", "active_dynamic_module", "application_status"}; private final AtomicReferenceArray<String> mValues = new AtomicReferenceArray<>(KEYS.length);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java index 0e32d41..dd4eb7f9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java
@@ -10,8 +10,10 @@ import android.app.PendingIntent; import android.app.RemoteInput; import android.content.Context; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; @@ -21,7 +23,7 @@ import android.os.Build; import android.support.annotation.IntDef; -import org.chromium.base.PackageUtils; +import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.widget.RoundedIconGenerator; @@ -238,32 +240,60 @@ } /** - * Sets the status bar icon for a notification that will be displayed by a different - * Android app (e.g. a WebAPK or Trusted Web Activity). + * Sets the status bar icon for a notification that will be displayed by a different app. + * The icon must come from a trusted app because this involves decoding a Bitmap from its + * resources. * @param iconId An iconId for a resource in the package that will display the notification. * @param packageName The package name of the package that will display the notification. - * @return This NotificationBuilderBase. */ - public NotificationBuilderBase setStatusBarIconForRemoteApp(int iconId, String packageName) { + public NotificationBuilderBase setStatusBarIconForTrustedRemoteApp( + int iconId, String packageName) { + setStatusBarIconForRemoteApp(iconId, decodeImageResource(packageName, iconId)); + return this; + } + + /** + * Sets the status bar icon for a notification that will be displayed by a different app. + * Unlike {@link #setStatusBarIconForTrustedRemoteApp} this is safe to use for any app. + * @param iconId An iconId for a resource in the package that will display the notification. + * @param iconBitmap The decoded bitmap. Depending on the device we need either id or bitmap. + */ + public NotificationBuilderBase setStatusBarIconForUntrustedRemoteApp( + int iconId, @Nullable Bitmap iconBitmap) { + setStatusBarIconForRemoteApp(iconId, iconBitmap); + return this; + } + + private void setStatusBarIconForRemoteApp(int iconId, @Nullable Bitmap iconBitmap) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // On Android M+, the small icon has to be from the resources of the app whose context // is passed to the Notification.Builder constructor. Thus we can't use iconId directly, // and instead decode the image and set the icon as a Bitmap. - setStatusBarIcon(PackageUtils.decodeImageResource(packageName, iconId)); + setStatusBarIcon(iconBitmap); } else { // Pre Android M, the small icon has to be from the resources of the app whose // NotificationManager is used in NotificationManager#notify. setSmallIconId(iconId); } + } + + /** + * Sets the small icon to be shown inside a notification that will be displayed by a different + * app. The icon must come from a trusted app. + */ + public NotificationBuilderBase setContentSmallIconForTrustedRemoteApp( + int iconId, String packageName) { + setSmallIconForContent(decodeImageResource(packageName, iconId)); return this; } /** * Sets the small icon to be shown inside a notification that will be displayed by a different - * Android app (e.g. a WebAPK or Trusted Web Activity). + * app. Unlike {@link #setContentSmallIconForTrustedRemoteApp} this is safe to use for any app. */ - public NotificationBuilderBase setContentSmallIconForRemoteApp(int iconId, String packageName) { - setSmallIconForContent(PackageUtils.decodeImageResource(packageName, iconId)); + public NotificationBuilderBase setContentSmallIconForUntrustedRemoteApp( + @Nullable Bitmap bitmap) { + setSmallIconForContent(bitmap); return this; } @@ -594,4 +624,16 @@ return new RoundedIconGenerator(largeIconWidthPx, largeIconHeightPx, cornerRadiusPx, NOTIFICATION_ICON_BG_COLOR, NOTIFICATION_ICON_TEXT_SIZE_DP * density); } + + /** Decodes into a Bitmap an Image resource stored in another package. */ + @Nullable + private static Bitmap decodeImageResource(String otherPackage, int resourceId) { + PackageManager packageManager = ContextUtils.getApplicationContext().getPackageManager(); + try { + Resources resources = packageManager.getResourcesForApplication(otherPackage); + return BitmapFactory.decodeResource(resources, resourceId); + } catch (PackageManager.NameNotFoundException e) { + return null; + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java index 3a10904e..d03ef9d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java
@@ -15,6 +15,7 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.support.customtabs.trusted.TrustedWebActivityServiceConnectionManager; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.TextUtils; @@ -132,7 +133,8 @@ mNotificationManager = new NotificationManagerProxyImpl( (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)); } - mTwaClient = new TrustedWebActivityClient(); + mTwaClient = new TrustedWebActivityClient( + new TrustedWebActivityServiceConnectionManager(context)); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAssistantPaymentRequest.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAssistantPaymentRequest.java index 91d55548..15a5ce12 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAssistantPaymentRequest.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillAssistantPaymentRequest.java
@@ -127,7 +127,8 @@ mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.DataType.PAYMENT_METHODS, SectionInformation.NO_SELECTION, - (new AutofillPaymentApp(mWebContents)).getInstruments(mMethodData)); + (new AutofillPaymentApp(mWebContents)) + .getInstruments(mMethodData, /*forceReturnServerCards=*/true)); if (!mPaymentMethodsSection.isEmpty() && mPaymentMethodsSection.getItem(0).isComplete()) { mPaymentMethodsSection.setSelectedItemIndex(0); } @@ -161,6 +162,9 @@ UrlFormatter.formatUrlForSecurityDisplay(mWebContents.getLastCommittedUrl()), SecurityStateModel.getSecurityLevelForWebContents(mWebContents), new ShippingStrings(mPaymentOptions.shippingType)); + // This payment request is embedded in another flow, so update the 'Pay' button text to + // 'Confirm'. + mUI.updatePayButtonText(R.string.autofill_assistant_payment_info_confirm); final FaviconHelper faviconHelper = new FaviconHelper(); faviconHelper.getLocalFaviconImageForURL(Profile.getLastUsedProfile(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentApp.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentApp.java index b8ae7880..ceaa5cd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentApp.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AutofillPaymentApp.java
@@ -48,17 +48,20 @@ String unusedIFRameOrigin, byte[][] unusedCertificateChain, Map<String, PaymentDetailsModifier> unusedModifiers, final InstrumentsCallback callback) { - new Handler().post(() - -> callback.onInstrumentsReady( - AutofillPaymentApp.this, getInstruments(methodDataMap))); + new Handler().post( + () + -> callback.onInstrumentsReady(AutofillPaymentApp.this, + getInstruments(methodDataMap, /*forceReturnServerCards=*/false))); } /** Method to get instruments synchronously. */ - public List<PaymentInstrument> getInstruments(Map<String, PaymentMethodData> methodDataMap) { + public List<PaymentInstrument> getInstruments( + Map<String, PaymentMethodData> methodDataMap, boolean forceReturnServerCards) { PersonalDataManager pdm = PersonalDataManager.getInstance(); - List<CreditCard> cards = - pdm.getCreditCardsToSuggest(/*includeServerCards=*/ChromeFeatureList.isEnabled( - ChromeFeatureList.WEB_PAYMENTS_RETURN_GOOGLE_PAY_IN_BASIC_CARD)); + List<CreditCard> cards = pdm.getCreditCardsToSuggest( + /*includeServerCards=*/forceReturnServerCards + || ChromeFeatureList.isEnabled( + ChromeFeatureList.WEB_PAYMENTS_RETURN_GOOGLE_PAY_IN_BASIC_CARD)); List<PaymentInstrument> instruments = new ArrayList<>(cards.size()); if (methodDataMap.containsKey(BasicCardUtils.BASIC_CARD_METHOD_NAME)) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java index d9477992..1549c28 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
@@ -620,6 +620,15 @@ } /** + * Update default text on the pay button to the given text. + * + * @param textResId The resource id of the text to be shown on the button. + */ + public void updatePayButtonText(int textResId) { + mPayButton.setText(textResId); + } + + /** * Updates the line items in response to a changed shipping address or option. * * @param cart The shopping cart, including the line items and the total.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java index 07ff3d3a..db02385 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java
@@ -44,6 +44,7 @@ public static final String PREF_NOTIFICATIONS = "notifications"; public static final String PREF_LANGUAGES = "languages"; public static final String PREF_DOWNLOADS = "downloads"; + public static final String PREF_DEVELOPER = "developer"; public static final String AUTOFILL_GUID = "guid"; // Needs to be in sync with kSettingsOrigin[] in @@ -152,6 +153,11 @@ if (!ChromeFeatureList.isEnabled(ChromeFeatureList.DOWNLOADS_LOCATION_CHANGE)) { getPreferenceScreen().removePreference(findPreference(PREF_DOWNLOADS)); } + + // Developer preferences are only shown when the feature is enabled. + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.DEVELOPER_PREFERENCES)) { + getPreferenceScreen().removePreference(findPreference(PREF_DEVELOPER)); + } } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java index e3671e5..14856f0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncAndServicesPreferences.java
@@ -319,7 +319,7 @@ public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.menu_id_targeted_help) { HelpAndFeedback.getInstance(getActivity()) - .show(getActivity(), getString(R.string.help_context_privacy), + .show(getActivity(), getString(R.string.help_context_sync_and_services), Profile.getLastUsedProfile(), null); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/DeveloperPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/DeveloperPreferences.java new file mode 100644 index 0000000..c1b1bd3 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/developer/DeveloperPreferences.java
@@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.preferences.developer; + +import android.os.Bundle; +import android.preference.PreferenceFragment; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.preferences.PreferenceUtils; + +/** + * Settings fragment containing preferences aimed at Chrome and web developers. + */ +public class DeveloperPreferences extends PreferenceFragment { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActivity().setTitle(R.string.prefs_developer); + PreferenceUtils.addPreferencesFromResource(this, R.xml.developer_preferences); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkServiceClient.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkServiceClient.java index a7fdd33..78aa2376 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkServiceClient.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkServiceClient.java
@@ -105,10 +105,10 @@ private void fallbackToWebApkIconIfNecessary(NotificationBuilderBase builder, String webApkPackage, int iconId) { if (!builder.hasSmallIconForContent()) { - builder.setContentSmallIconForRemoteApp(iconId, webApkPackage); + builder.setContentSmallIconForTrustedRemoteApp(iconId, webApkPackage); } if (!builder.hasStatusBarIconBitmap()) { - builder.setStatusBarIconForRemoteApp(iconId, webApkPackage); + builder.setStatusBarIconForTrustedRemoteApp(iconId, webApkPackage); } }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 5943c82..f649c4d 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -89,10 +89,12 @@ <file lang="en-GB" path="translations/android_chrome_strings_en-GB.xtb" /> <file lang="es" path="translations/android_chrome_strings_es.xtb" /> <file lang="es-419" path="translations/android_chrome_strings_es-419.xtb" /> + <file lang="et" path="translations/android_chrome_strings_et.xtb" /> <file lang="fa" path="translations/android_chrome_strings_fa.xtb" /> <file lang="fi" path="translations/android_chrome_strings_fi.xtb" /> <file lang="fil" path="translations/android_chrome_strings_fil.xtb" /> <file lang="fr" path="translations/android_chrome_strings_fr.xtb" /> + <file lang="gu" path="translations/android_chrome_strings_gu.xtb" /> <file lang="hi" path="translations/android_chrome_strings_hi.xtb" /> <file lang="hr" path="translations/android_chrome_strings_hr.xtb" /> <file lang="hu" path="translations/android_chrome_strings_hu.xtb" /> @@ -101,8 +103,12 @@ <file lang="iw" path="translations/android_chrome_strings_iw.xtb" /> <file lang="ja" path="translations/android_chrome_strings_ja.xtb" /> <file lang="ko" path="translations/android_chrome_strings_ko.xtb" /> + <file lang="kn" path="translations/android_chrome_strings_kn.xtb" /> <file lang="lt" path="translations/android_chrome_strings_lt.xtb" /> <file lang="lv" path="translations/android_chrome_strings_lv.xtb" /> + <file lang="ml" path="translations/android_chrome_strings_ml.xtb" /> + <file lang="mr" path="translations/android_chrome_strings_mr.xtb" /> + <file lang="ms" path="translations/android_chrome_strings_ms.xtb" /> <file lang="nl" path="translations/android_chrome_strings_nl.xtb" /> <file lang="no" path="translations/android_chrome_strings_no.xtb" /> <file lang="pl" path="translations/android_chrome_strings_pl.xtb" /> @@ -115,6 +121,8 @@ <file lang="sr" path="translations/android_chrome_strings_sr.xtb" /> <file lang="sv" path="translations/android_chrome_strings_sv.xtb" /> <file lang="sw" path="translations/android_chrome_strings_sw.xtb" /> + <file lang="ta" path="translations/android_chrome_strings_ta.xtb" /> + <file lang="te" path="translations/android_chrome_strings_te.xtb" /> <file lang="th" path="translations/android_chrome_strings_th.xtb" /> <file lang="tr" path="translations/android_chrome_strings_tr.xtb" /> <file lang="uk" path="translations/android_chrome_strings_uk.xtb" /> @@ -1399,6 +1407,11 @@ Download occurs only on Wi-Fi </message> + <!-- Developer preferences --> + <message name="IDS_PREFS_DEVELOPER" desc="Title for the Developer preferences page in Chrome settings, which is hidden for regular uses and shows settings and tools aimed at Chrome and web developers. [CHAR-LIMIT=32]"> + Developer options + </message> + <!-- About Chrome preferences --> <message name="IDS_PREFS_ABOUT_CHROME" desc="Title for the About Chrome page. [CHAR-LIMIT=32]"> About Chrome
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_bn.xtb b/chrome/android/java/strings/translations/android_chrome_strings_bn.xtb new file mode 100644 index 0000000..a42ac37f --- /dev/null +++ b/chrome/android/java/strings/translations/android_chrome_strings_bn.xtb
@@ -0,0 +1,1056 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="bn"> +<translation id="1006017844123154345">Open Online</translation> +<translation id="1036727731225946849">Adding <ph name="WEBAPK_NAME" />...</translation> +<translation id="1041308826830691739">From websites</translation> +<translation id="1049743911850919806">Incognito</translation> +<translation id="1054301162707478098">You’ve gone private.</translation> +<translation id="10614374240317010">Never saved</translation> +<translation id="1067922213147265141">Other Google services</translation> +<translation id="1068672505746868501">Never translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="10713315585330490"><ph name="FILE_SIZE" /> – <ph name="DESCRIPTION" /></translation> +<translation id="1080790410959514870">You are signing out of an account managed by <ph name="DOMAIN_NAME" />. This will delete the Chrome data stored on this device, but the data will remain in your Google Account.</translation> +<translation id="1105960400813249514">Screen Capture</translation> +<translation id="1111673857033749125">Bookmarks saved on your other devices will appear here.</translation> +<translation id="1113597929977215864">Show simplified view</translation> +<translation id="1121094540300013208">Usage and crash reports</translation> +<translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download pending.}other{# downloads pending.}}</translation> +<translation id="1145536944570833626">Delete existing data.</translation> +<translation id="1146678959555564648">Enter VR</translation> +<translation id="114721135501989771">Get Google smarts in Chrome</translation> +<translation id="1157102636231978136">Your browsing data and activity, synced to your Google account</translation> +<translation id="116280672541001035">Used</translation> +<translation id="1172593791219290334">Startup Page</translation> +<translation id="1175310183703641346">Your bookmarks, history, passwords and more will no longer be synced to your Google account</translation> +<translation id="1178581264944972037">Pause</translation> +<translation id="1181037720776840403">Remove</translation> +<translation id="1197267115302279827">Move bookmarks</translation> +<translation id="119944043368869598">Clear all</translation> +<translation id="1201402288615127009">Next</translation> +<translation id="1204037785786432551">Download link</translation> +<translation id="1206892813135768548">Copy link text</translation> +<translation id="1208340532756947324">To sync and personalise across devices, turn on sync</translation> +<translation id="1209206284964581585">Hide for now</translation> +<translation id="123724288017357924">Reload the current page, ignoring cached content</translation> +<translation id="124116460088058876">More languages</translation> +<translation id="124678866338384709">Close current tab</translation> +<translation id="1258753120186372309">Google doodle: <ph name="DOODLE_DESCRIPTION" /></translation> +<translation id="1259100630977430756">Pages that you view in private tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your private tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going private doesn’t hide your browsing from your employer, your Internet service provider or the websites that you visit.</translation> +<translation id="127138278192656016">Use sync and all services</translation> +<translation id="1272079795634619415">Stop</translation> +<translation id="1283039547216852943">Tap to expand</translation> +<translation id="1285320974508926690">Never translate this site</translation> +<translation id="1291207594882862231">Clear history, cookies, site data, cache…</translation> +<translation id="129553762522093515">Recently closed</translation> +<translation id="1326317727527857210">To get your tabs from your other devices, sign in to Chrome.</translation> +<translation id="1332501820983677155">Google Chrome feature shortcuts</translation> +<translation id="1360432990279830238">Sign out and turn off sync?</translation> +<translation id="136248372334525878">Preload pages for faster loading and offline reading</translation> +<translation id="1369915414381695676">Site <ph name="SITE_NAME" /> added</translation> +<translation id="1373696734384179344">Insufficient memory to download the selected content.</translation> +<translation id="1376578503827013741">Computing…</translation> +<translation id="138361230106469022">Hi, <ph name="FULL_NAME" /></translation> +<translation id="1383876407941801731">Search</translation> +<translation id="1384959399684842514">Download paused</translation> +<translation id="1389974829397082527">No bookmarks here</translation> +<translation id="1397811292916898096">Search with <ph name="PRODUCT_NAME" /></translation> +<translation id="1397854323885047133">Sync and personalisation</translation> +<translation id="1404122904123200417">Embedded in <ph name="WEBSITE_URL" /></translation> +<translation id="1406000523432664303">“Do Not Track”</translation> +<translation id="1407135791313364759">Open all</translation> +<translation id="1409426117486808224">Simplified view for open tabs</translation> +<translation id="1409879593029778104"><ph name="FILE_NAME" /> download prevented because file already exists.</translation> +<translation id="1414981605391750300">Contacting Google. This may take a minute…</translation> +<translation id="1416550906796893042">Application version</translation> +<translation id="1430915738399379752">Print</translation> +<translation id="1445680696957526815">Chrome’s components are incompatible with one another. Chrome may be upgrading, please try again in a few minutes. If the problem continues, try uninstalling and re-installing Chrome.</translation> +<translation id="1446450296470737166">Allow full control of MIDI devices</translation> +<translation id="145097072038377568">Turned off in Android Settings</translation> +<translation id="1477626028522505441"><ph name="FILE_NAME" /> download failed due to server issues.</translation> +<translation id="1506061864768559482">Search engine</translation> +<translation id="1513352483775369820">Bookmarks and web history</translation> +<translation id="1513858653616922153">Delete password</translation> +<translation id="1516229014686355813">Tap to Search sends the selected word and the current page as context to Google Search. You can turn it off in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="1539064842193522527">Link opened in Chrome</translation> +<translation id="1549000191223877751">Move to other window</translation> +<translation id="1553358976309200471">Update Chrome</translation> +<translation id="1566400915470565838">To use <ph name="APP_NAME" />, please connect to the Internet.</translation> +<translation id="1569387923882100876">Connected device</translation> +<translation id="1571304935088121812">Copy username</translation> +<translation id="1576370611341449972">Download occurs only on Wi-Fi</translation> +<translation id="1612196535745283361">Chrome needs location access to scan for devices. Location access is <ph name="BEGIN_LINK" />turned off for this device<ph name="END_LINK" />.</translation> +<translation id="162035744160882748">Turn on sync, personalisation and other Google services</translation> +<translation id="1620510694547887537">Camera</translation> +<translation id="1623104350909869708">Prevent this page from creating additional dialogues</translation> +<translation id="1628019612362412531">{NUM_SELECTED,plural, =1{Remove 1 selected item}other{Remove # selected items}}</translation> +<translation id="1641113438599504367">Safe Browsing</translation> +<translation id="164269334534774161">You are viewing an offline copy of this page from <ph name="CREATION_TIME" /></translation> +<translation id="1644574205037202324">History</translation> +<translation id="1647391597548383849">Access your camera</translation> +<translation id="1660204651932907780">Allow sites to play sound (recommended)</translation> +<translation id="1670399744444387456">Basic</translation> +<translation id="1671236975893690980">Download pending...</translation> +<translation id="1672586136351118594">Don‘t show again</translation> +<translation id="1709438864123551175">Data Saver</translation> +<translation id="1718835860248848330">Last hour</translation> +<translation id="1729516292547892356">To view virtual reality content, update Google VR Services</translation> +<translation id="1733116627827457509"><ph name="FILE_SIZE" /> – Updated <ph name="TIME_SINCE_UPDATE" /></translation> +<translation id="1736419249208073774">Explore</translation> +<translation id="1743802530341753419">Ask before allowing sites to connect to a device (recommended)</translation> +<translation id="1749561566933687563">Sync your bookmarks</translation> +<translation id="17513872634828108">Open tabs</translation> +<translation id="1756600373018374892">Tap this button for quick access to your tabs.</translation> +<translation id="1779089405699405702">Image decoder</translation> +<translation id="1782483593938241562">End date <ph name="DATE" /></translation> +<translation id="1792959175193046959">Change the default download location at any time</translation> +<translation id="1807246157184219062">Light</translation> +<translation id="1821253160463689938">Uses cookies to remember your preferences, even if you don't visit those pages</translation> +<translation id="1829244130665387512">Find in page</translation> +<translation id="1832521218263067499">Security incidents</translation> +<translation id="1853692000353488670">New incognito tab</translation> +<translation id="1868024384445905608">Chrome now downloads files faster</translation> +<translation id="1878302395768190018">You can customise this at any time in Chrome Settings</translation> +<translation id="1880072593381090678">Popular pages from Chrome</translation> +<translation id="1883903952484604915">My files</translation> +<translation id="1887786770086287077">Location access is off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1891331835972267886"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="189172778771606813">Close navigation drawer</translation> +<translation id="1919345977826869612">Ads</translation> +<translation id="1919950603503897840">Select contacts</translation> +<translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/<ph name="FILE_SIZE_WITH_UNITS" /></translation> +<translation id="1933845786846280168">Selected Tab</translation> +<translation id="1938981467853765413">Provide feedback</translation> +<translation id="194341124344773587">Turn on permission for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1943432128510653496">Save passwords</translation> +<translation id="1944384637046898011">Encrypt all with Google password as of <ph name="TIME" /></translation> +<translation id="1946005195648379376">Control how Google uses your browsing history to personalise Search and other Google services.</translation> +<translation id="1952172573699511566">Websites will show text in your preferred language, when possible.</translation> +<translation id="195283394249132567">Personalised Google services</translation> +<translation id="1966710179511230534">Please update your sign-in details.</translation> +<translation id="1974060860693918893">Advanced</translation> +<translation id="1984937141057606926">Allowed, except third-party</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> button</translation> +<translation id="1989112275319619282">Browse</translation> +<translation id="1993768208584545658"><ph name="SITE" /> wants to pair</translation> +<translation id="1994173015038366702">Site URL</translation> +<translation id="2000419248597011803">Sends some cookies and searches from the address bar and search box to your default search engine</translation> +<translation id="2002537628803770967">Credit cards and addresses using Google Pay</translation> +<translation id="200815880754187296"><ph name="KILOBYTES" /> KB other apps</translation> +<translation id="2017836877785168846">Clears history and autocompletions in the address bar.</translation> +<translation id="2021896219286479412">Full screen site controls</translation> +<translation id="2038563949887743358">Turn on Request desktop site</translation> +<translation id="2045104531052923016"><ph name="GIGABYTES" /> GB other apps</translation> +<translation id="2063713494490388661">Tap to Search</translation> +<translation id="2079545284768500474">Undo</translation> +<translation id="2082238445998314030">Result <ph name="RESULT_NUMBER" /> of <ph name="TOTAL_RESULTS" /></translation> +<translation id="2086652334978798447">To get personalised content suggested by Google, sign in to Chrome.</translation> +<translation id="2091887806945687916">Sound</translation> +<translation id="2095887075102408547">When this feature is turned on, Chrome will use Google servers to compress pages that you visit before downloading them. Pages accessed using private connections (HTTPS) or in Incognito tabs will not be optimised or seen by Google.</translation> +<translation id="2096012225669085171">Sync and personalise across devices</translation> +<translation id="2100273922101894616">Auto Sign-in</translation> +<translation id="2111511281910874386">Go to page</translation> +<translation id="2120297377148151361">Activity and interactions</translation> +<translation id="2122601567107267586">Could not open app</translation> +<translation id="2126426811489709554">Powered by Chrome</translation> +<translation id="2131665479022868825"><ph name="DATA" /> saved</translation> +<translation id="213279576345780926">Closed <ph name="TAB_TITLE" /></translation> +<translation id="2139186145475833000">Add to Home screen</translation> +<translation id="2142289305367051020">Your favourite pages are here</translation> +<translation id="2146738493024040262">Open Instant App</translation> +<translation id="2148716181193084225">Today</translation> +<translation id="2154484045852737596">Edit card</translation> +<translation id="2154710561487035718">Copy URL</translation> +<translation id="2156074688469523661">Remaining sites (<ph name="NUMBER_OF_SITES" />)</translation> +<translation id="2206488550163399966"><ph name="APP_NAME" />, web app. <ph name="APP_URL" /></translation> +<translation id="2227444325776770048">Continue as <ph name="USER_FULL_NAME" /></translation> +<translation id="2232379019872353004">Sends some system information and page content to Google</translation> +<translation id="2234876718134438132">Sync and Google services</translation> +<translation id="2259659629660284697">Export passwords…</translation> +<translation id="2268044343513325586">Refine</translation> +<translation id="2280910239864711607">Open a new tab in private mode</translation> +<translation id="2286841657746966508">Billing address</translation> +<translation id="230115972905494466">No compatible devices found</translation> +<translation id="2315043854645842844">Client side certificate selection is not supported by the operating system.</translation> +<translation id="2321086116217818302">Preparing passwords…</translation> +<translation id="2321958826496381788">Drag the slider until you can read this comfortably. Text should look at least this big after double-tapping on a paragraph.</translation> +<translation id="2323763861024343754">Site storage</translation> +<translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised by you or your parents at any time. Google may use content on sites that you visit, as well as browsing activity and interactions, to personalise Chrome and Google services such as Translate, Search and ads.</translation> +<translation id="2328985652426384049">Can’t sign in</translation> +<translation id="2342981853652716282">Sign in to Chrome to get your bookmarks, passwords and more on all your devices.</translation> +<translation id="2343328333327081434">Installing…</translation> +<translation id="2346253980530904022">Google servers will optimise the pages that you visit, except for HTTPS and Incognito.</translation> +<translation id="2349710944427398404">Total data used by Chrome, including accounts, bookmarks and saved settings</translation> +<translation id="2351097562818989364">Your translate settings have been reset.</translation> +<translation id="2359808026110333948">Continue</translation> +<translation id="2369533728426058518">open tabs</translation> +<translation id="2387895666653383613">Text scaling</translation> +<translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> +<translation id="2410754283952462441">Choose an account</translation> +<translation id="2414672073755873541">No content here</translation> +<translation id="2414886740292270097">Dark</translation> +<translation id="2416359993254398973">Chrome needs permission to access your camera for this site.</translation> +<translation id="2426805022920575512">Choose another account</translation> +<translation id="2433507940547922241">Appearance</translation> +<translation id="2434158240863470628">Download complete <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2436117022029368436">Communicates with Google to improve browsing and Chrome</translation> +<translation id="2440823041667407902">Location access</translation> +<translation id="2450083983707403292">Do you want to start downloading <ph name="FILE_NAME" /> again?</translation> +<translation id="2476578072172137802">Site Settings</translation> +<translation id="2482878487686419369">Notifications</translation> +<translation id="2496180316473517155">Browsing history</translation> +<translation id="2498359688066513246">Help & feedback</translation> +<translation id="2501278716633472235">Go back</translation> +<translation id="2513403576141822879">For more settings that relate to privacy, security and data collection, see <ph name="BEGIN_LINK" />Sync and Google services<ph name="END_LINK" /></translation> +<translation id="2523184218357549926">Sends URLs of pages that you visit to Google</translation> +<translation id="2526148617758225454">Data Saver is on. Manage it in Settings.</translation> +<translation id="2532336938189706096">Web View</translation> +<translation id="2536728043171574184">Viewing an offline copy of this page</translation> +<translation id="2546283357679194313">Cookies and site data</translation> +<translation id="2567385386134582609">IMAGE</translation> +<translation id="2570922361219980984">Location access is also off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="257931822824936280">Expanded – click to collapse.</translation> +<translation id="2581165646603367611">This will clear cookies, cache and other data of sites Chrome doesn't think is important.</translation> +<translation id="2586657967955657006">Clipboard</translation> +<translation id="2587052924345400782">Newer version is available</translation> +<translation id="2593272815202181319">Monospace</translation> +<translation id="2612676031748830579">Card number</translation> +<translation id="2621115761605608342">Allow JavaScript for a specific site.</translation> +<translation id="2625189173221582860">Password copied</translation> +<translation id="2631006050119455616">Saved</translation> +<translation id="2633278372998075009">Private tabs</translation> +<translation id="2647434099613338025">Add language</translation> +<translation id="2650751991977523696">Download file again?</translation> +<translation id="2653659639078652383">Submit</translation> +<translation id="2677748264148917807">Leave</translation> +<translation id="2704606927547763573">Copied</translation> +<translation id="2707726405694321444">Refresh page</translation> +<translation id="2709516037105925701">Auto-fill</translation> +<translation id="271033894570825754">New</translation> +<translation id="2728754400939377704">Sort by site</translation> +<translation id="2744248271121720757">Tap a word to search instantly or see related actions</translation> +<translation id="2762000892062317888">just now</translation> +<translation id="2777555524387840389"><ph name="SECONDS" /> secs left</translation> +<translation id="2781151931089541271">1 sec left</translation> +<translation id="2803478378562657435">Showing saved passwords and password options</translation> +<translation id="2810645512293415242">Simplified page to save data and load faster.</translation> +<translation id="281504910091592009">View and manage saved passwords in your <ph name="BEGIN_LINK" />Google account<ph name="END_LINK" /></translation> +<translation id="2818669890320396765">To get your bookmarks on all your devices, sign in and turn on sync</translation> +<translation id="2836148919159985482">Touch the back button to exit full screen.</translation> +<translation id="2842985007712546952">Parent folder</translation> +<translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Previous track</translation> +<translation id="2876764156902388290">Chrome is using less data to show you this page</translation> +<translation id="2888126860611144412">About Chrome</translation> +<translation id="2891154217021530873">Stop page loading</translation> +<translation id="2900528713135656174">Create event</translation> +<translation id="2902702728133930130">Chrome failed during start-up with an unexpected error.</translation> +<translation id="290376772003165898">Page is not in <ph name="LANGUAGE" />?</translation> +<translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> +<translation id="2913331724188855103">Allow sites to save and read cookie data (recommended)</translation> +<translation id="2932150158123903946">Google <ph name="APP_NAME" /> storage</translation> +<translation id="2943166482989655199">Improve Chrome and its security by sending system and usage data to Google</translation> +<translation id="2956410042958133412">This account is managed by <ph name="PARENT_NAME_1" /> and <ph name="PARENT_NAME_2" />.</translation> +<translation id="2960796085439532066">Copyright <ph name="YEAR" /> Google Inc. All rights reserved.</translation> +<translation id="2962095958535813455">Switched to incognito tabs</translation> +<translation id="2968755619301702150">Certificate viewer</translation> +<translation id="2979025552038692506">Selected Incognito Tab</translation> +<translation id="2989523299700148168">Recently Visited</translation> +<translation id="2996291259634659425">Create passphrase</translation> +<translation id="2996809686854298943">URL required</translation> +<translation id="300526633675317032">This will clear all <ph name="SIZE_IN_KB" /> of website storage.</translation> +<translation id="3029613699374795922">Downloaded <ph name="KBS" /> KB</translation> +<translation id="3029704984691124060">Passphrases do not match</translation> +<translation id="3036750288708366620"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /></translation> +<translation id="3045654778214005718">See more like this from Google</translation> +<translation id="305593374596241526">Location is off; turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="307908932405420782">More articles will appear soon. Enjoy your morning!</translation> +<translation id="3089395242580810162">Open in incognito tab</translation> +<translation id="311456632243022227">Multiple links opened in Chrome</translation> +<translation id="3115898365077584848">Show info</translation> +<translation id="3137521801621304719">Leave incognito mode</translation> +<translation id="3148434565183091099">To get your bookmarks on all your devices, sign in to Chrome.</translation> +<translation id="3157842584138209013">See how much data you've saved from the More Options button</translation> +<translation id="3166827708714933426">Tab and window shortcuts</translation> +<translation id="3190152372525844641">Turn on permissions for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> stored data</translation> +<translation id="3207960819495026254">Bookmarked</translation> +<translation id="321773570071367578">If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="3227137524299004712">Microphone</translation> +<translation id="3232754137068452469">Web App</translation> +<translation id="3234355010754616171">New private tab</translation> +<translation id="3236059992281584593">1 min left</translation> +<translation id="3244271242291266297">MM</translation> +<translation id="3254409185687681395">Bookmark this page</translation> +<translation id="3259831549858767975">Make everything on the page smaller</translation> +<translation id="3269093882174072735">Load image</translation> +<translation id="3269956123044984603">To get your tabs from your other devices, turn on “Auto-sync data” in Android account settings.</translation> +<translation id="3282568296779691940">Sign in to Chrome</translation> +<translation id="32895400574683172">Notifications are allowed</translation> +<translation id="3295602654194328831">Hide info</translation> +<translation id="3298243779924642547">Lite</translation> +<translation id="3303414029551471755">Proceed to download the content?</translation> +<translation id="3328801116991980348">Site information</translation> +<translation id="3341058695485821946">See how much data you've saved</translation> +<translation id="3350687908700087792">Close all incognito tabs</translation> +<translation id="3365671512111106261">Unavailable when Data Saver is turned on</translation> +<translation id="3367813778245106622">Sign in again to start sync</translation> +<translation id="3377025655491224618">Private tab</translation> +<translation id="3384347053049321195">Share image</translation> +<translation id="3386292677130313581">Ask before allowing sites to know your location (recommended)</translation> +<translation id="3387650086002190359"><ph name="FILE_NAME" /> download failed due to file system errors.</translation> +<translation id="339329030417445648">This site tends to show intrusive ads</translation> +<translation id="3398320232533725830">Open the bookmarks manager</translation> +<translation id="3414952576877147120">Size:</translation> +<translation id="3443221991560634068">Reload the current page</translation> +<translation id="3452612588551937789">Sign in with your Google Account to get your bookmarks, history, passwords and other settings on all your devices.</translation> +<translation id="3485359633434254965">{FILES,plural, =1{%1$d file downloaded}other{%1$d files downloaded}}</translation> +<translation id="3492207499832628349">New incognito tab</translation> +<translation id="3493531032208478708"><ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /> about suggested content</translation> +<translation id="3518985090088779359">Accept & continue</translation> +<translation id="3522247891732774234">Update available. More options</translation> +<translation id="3527085408025491307">Folder</translation> +<translation id="3542235761944717775"><ph name="KILOBYTES" /> KB available</translation> +<translation id="3549644494707163724">Encrypt all synced data with your own sync passphrase</translation> +<translation id="3549657413697417275">Search your history</translation> +<translation id="3552151358455404883">Manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="3557336313807607643">Add to contacts</translation> +<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="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="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="3600792891314830896">Mute sites that play sound</translation> +<translation id="360207483134687714">Help improve the VR experience in Chrome</translation> +<translation id="3616113530831147358">Audio</translation> +<translation id="3620176948598597475">Resetting erases Data Saver history, including the list of visited sites.</translation> +<translation id="3630011985153972676">Allow Chrome to download articles for you when on Wi-Fi under settings.</translation> +<translation id="3632295766818638029">Unmask password</translation> +<translation id="363596933471559332">Automatically sign in to websites using stored credentials. When the feature is off, you’ll be asked for verification every time before signing in to a website.</translation> +<translation id="3661699943263275414">Third-party websites can save and read cookie data</translation> +<translation id="3662546969139119822">No history here</translation> +<translation id="3672452749423051839">Navigation error suggestions</translation> +<translation id="3692944402865947621"><ph name="FILE_NAME" /> download failed because storage location is not reachable.</translation> +<translation id="3712575778697986964">Reset Data Saver?</translation> +<translation id="3714981814255182093">Open the Find Bar</translation> +<translation id="3716182511346448902">This page uses too much memory, so Chrome paused it.</translation> +<translation id="3739899004075612870">Bookmarked in <ph name="PRODUCT_NAME" /></translation> +<translation id="3744111309925758534"><ph name="MEGABYTES" /> MB other apps</translation> +<translation id="3744111561329211289">Background sync</translation> +<translation id="3773755127849930740"><ph name="BEGIN_LINK" />Turn on Bluetooth<ph name="END_LINK" /> to allow pairing</translation> +<translation id="3778956594442850293">Added to Home screen</translation> +<translation id="3781011235031427080">More like this opened at half height</translation> +<translation id="3789841737615482174">Install</translation> +<translation id="3810838688059735925">Video</translation> +<translation id="3810973564298564668">Manage</translation> +<translation id="3819178904835489326"><ph name="NUMBER_OF_DOWNLOADS" /> downloads deleted</translation> +<translation id="3819562311292413223">Download articles for you</translation> +<translation id="3822502789641063741">Clear site storage?</translation> +<translation id="385051799172605136">Back</translation> +<translation id="3859306556332390985">Seek forward</translation> +<translation id="3868004864571585162">Cookies, media licences and site data</translation> +<translation id="3894427358181296146">Add folder</translation> +<translation id="3895926599014793903">Force enable zoom</translation> +<translation id="3927692899758076493">Sans Serif</translation> +<translation id="3928666092801078803">Combine my data</translation> +<translation id="393697183122708255">No enabled voice search available</translation> +<translation id="3950820424414687140">Sign in</translation> +<translation id="395206256282351086">Search and site suggestions disabled</translation> +<translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> +<translation id="3967822245660637423">Download complete</translation> +<translation id="397583555483684758">Sync has stopped working</translation> +<translation id="3976396876660209797">Remove and recreate this shortcut</translation> +<translation id="3985215325736559418">Do you want to download <ph name="FILE_NAME" /> again?</translation> +<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="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> +<translation id="3997476611815694295">Unimportant storage</translation> +<translation id="4002066346123236978">Title</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# hr}other{# hrs}}</translation> +<translation id="4042870126885713738">Show suggestions when a web address does not resolve or a connection cannot be made</translation> +<translation id="4046123991198612571">Next track</translation> +<translation id="4048707525896921369">Learn about topics on websites without leaving the page. Tap to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results and other details. + +To adjust your search term, long press to select. To refine your search, slide the panel all the way up and tap the search box.</translation> +<translation id="4056223980640387499">Sepia</translation> +<translation id="4060598801229743805">Options available near the top of the screen</translation> +<translation id="4062305924942672200">Legal information</translation> +<translation id="4084682180776658562">Bookmark</translation> +<translation id="4084712963632273211">From <ph name="PUBLISHER_ORIGIN" /> – <ph name="BEGIN_DEEMPHASIZED" />delivered by Google<ph name="END_DEEMPHASIZED" /></translation> +<translation id="4084836577264234537"><ph name="MEGABYTES" /> MB downloaded</translation> +<translation id="4089831646916293264">This feature may interfere with access to premium data services provided by your operator.</translation> +<translation id="4095146165863963773">Delete app data?</translation> +<translation id="4097739989936358050">This app is running in Chrome.</translation> +<translation id="4099578267706723511">Help make Chrome better by sending usage statistics and crash reports to Google.</translation> +<translation id="410351446219883937">Autoplay</translation> +<translation id="4113030288477039509">Managed by your administrator</translation> +<translation id="4116038641877404294">Download pages to use them offline</translation> +<translation id="4127069705158143605">{BOOKMARKS_COUNT,plural, =1{%1$d bookmark}other{%1$d bookmarks}}</translation> +<translation id="4149994727733219643">Simplified view for web pages</translation> +<translation id="4159800535322890630">Block sites from accessing your sensors</translation> +<translation id="4165986682804962316">Site settings</translation> +<translation id="4170011742729630528">The service is not available; try again later.</translation> +<translation id="4179980317383591987"><ph name="AMOUNT" /> used</translation> +<translation id="4181841719683918333">Languages</translation> +<translation id="4192273449750167573">Review your settings on the next screen</translation> +<translation id="4195643157523330669">Open in new tab</translation> +<translation id="4198423547019359126">No available download locations</translation> +<translation id="4209895695669353772">To get personalised content suggested by Google, turn on sync</translation> +<translation id="4226663524361240545">Notifications may vibrate the device</translation> +<translation id="4242533952199664413">Open settings</translation> +<translation id="4243710787042215766">Open in private tab</translation> +<translation id="424864128008805179">Sign out of Chrome?</translation> +<translation id="4256782883801055595">Open-source licences</translation> +<translation id="4259722352634471385">Navigation is blocked: <ph name="URL" /></translation> +<translation id="4262028915562328938">Sync error occurred, tap to get details.</translation> +<translation id="4269820728363426813">Copy link address</translation> +<translation id="4275663329226226506">Media</translation> +<translation id="4278390842282768270">Allowed</translation> +<translation id="4307992518367153382">Basics</translation> +<translation id="4351244548802238354">Close dialogue</translation> +<translation id="4378154925671717803">Phone</translation> +<translation id="4384468725000734951">Using Sogou for search</translation> +<translation id="4398088515904522762">To use this feature, turn on <ph name="BEGIN_LINK" />Activity and interactions<ph name="END_LINK" />.</translation> +<translation id="4404568932422911380">No bookmarks</translation> +<translation id="4409723563706114196">Use page predictions</translation> +<translation id="4412992751769744546">Allow third-party cookies</translation> +<translation id="4419556793104466535">Control sync, personalisation and more</translation> +<translation id="4432792777822557199">Pages in <ph name="SOURCE_LANGUAGE" /> will be translated to <ph name="TARGET_LANGUAGE" /> from now on</translation> +<translation id="4434045419905280838">Pop-ups and redirects</translation> +<translation id="4452411734226507615">Close <ph name="TAB_TITLE" /> tab</translation> +<translation id="4452548195519783679">Bookmarked to <ph name="FOLDER_NAME" /></translation> +<translation id="4453340223357552416"><ph name="FILE_NAME" /> downloaded in <ph name="PRODUCT_NAME" /></translation> +<translation id="4468959413250150279">Mute sound for a specific site.</translation> +<translation id="4472118726404937099">To sync and personalise across devices, sign in and turn on sync</translation> +<translation id="447252321002412580">Help improve Chrome's features and performance</translation> +<translation id="4479647676395637221">Ask first before allowing sites to use your camera (recommended)</translation> +<translation id="4487967297491345095">All Chrome’s app data will be deleted permanently. This includes all files, settings, accounts, databases, etc.</translation> +<translation id="4508440807153586353">Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting you'll need to reset sync. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation> +<translation id="4513387527876475750">{DAYS,plural, =1{# day ago}other{# days ago}}</translation> +<translation id="451872707440238414">Search your bookmarks</translation> +<translation id="4521489764227272523">The selected data has been removed from Chrome and your synced devices. + +Your Google Account may have other forms of browsing history such as searches and activity from other Google services at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="4532845899244822526">Choose folder</translation> +<translation id="4550003330909367850">To view or copy your password here, set screen lock on this device.</translation> +<translation id="4558311620361989323">Web page shortcuts</translation> +<translation id="4561979708150884304">No connection</translation> +<translation id="4565377596337484307">Hide password</translation> +<translation id="4570913071927164677">Details</translation> +<translation id="4572422548854449519">Sign in to managed account</translation> +<translation id="4581964774250883625">You’ve gone incognito.</translation> +<translation id="4583164079174244168">{MINUTES,plural, =1{# minute ago}other{# minutes ago}}</translation> +<translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">This offline page is from <ph name="CREATION_TIME" /> and may differ from the online version.</translation> +<translation id="4605958867780575332">Item removed: <ph name="ITEM_TITLE" /></translation> +<translation id="4616150815774728855">Open <ph name="WEBAPK_NAME" /></translation> +<translation id="4634124774493850572">Use password</translation> +<translation id="4645575059429386691">Managed by your parent</translation> +<translation id="4660011489602794167">Show keyboard</translation> +<translation id="4663756553811254707"><ph name="NUMBER_OF_BOOKMARKS" /> bookmarks deleted</translation> +<translation id="4665282149850138822"><ph name="NAME" /> was added to your Home screen</translation> +<translation id="4684427112815847243">Sync everything</translation> +<translation id="4695891336199304370">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}other{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}}</translation> +<translation id="4698034686595694889">View offline in <ph name="APP_NAME" /></translation> +<translation id="4698413471314543145">Critical functionality required to run Chrome is missing; either your Chrome installation is incomplete or not compatible with this version of Android.</translation> +<translation id="4699172675775169585">Cached images and files</translation> +<translation id="4714588616299687897">Save up to 60% of your data</translation> +<translation id="4719927025381752090">Offer to translate</translation> +<translation id="4720023427747327413">Open in <ph name="PRODUCT_NAME" /></translation> +<translation id="4720982865791209136">Help improve Chrome. <ph name="BEGIN_LINK" />Take survey<ph name="END_LINK" /></translation> +<translation id="4730876730346568982">You are switching sync accounts from <ph name="ACCOUNT_EMAIL_OLD" /> to <ph name="ACCOUNT_EMAIL_NEW" />. Your existing Chrome data is managed by <ph name="MANAGED_DOMAIN" />. This will delete your data from this device, but your data will remain in <ph name="ACCOUNT_EMAIL_OLD" />.</translation> +<translation id="473775607612524610">Update</translation> +<translation id="4738836084190194332">Last synced: <ph name="WHEN" /></translation> +<translation id="4749960740855309258">Open a new tab</translation> +<translation id="4751476147751820511">Motion or light sensors</translation> +<translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download complete.}other{# downloads complete.}}</translation> +<translation id="4766369052440583386">Data Saver is on</translation> +<translation id="4797039098279997504">Touch to return to <ph name="URL_OF_THE_CURRENT_TAB" /></translation> +<translation id="4807098396393229769">Name on card</translation> +<translation id="4807963036345170158">Data Saver is off</translation> +<translation id="4816465935029283692">Data types</translation> +<translation id="4837753911714442426">Open options to print page</translation> +<translation id="4842092870884894799">Showing password generation pop-up</translation> +<translation id="4850886885716139402">View</translation> +<translation id="4860895144060829044">Call</translation> +<translation id="4874967477260347223">Media Licenses</translation> +<translation id="4875775213178255010">Content Suggestions</translation> +<translation id="4878404682131129617">Establishing a tunnel via proxy server failed</translation> +<translation id="4881695831933465202">Open</translation> +<translation id="488187801263602086">Rename file</translation> +<translation id="4882831918239250449">Control how your browsing history is used to personalise Search, ads and more</translation> +<translation id="4883379392681899581">Leave private mode</translation> +<translation id="4885273946141277891">Unsupported number of Chrome instances.</translation> +<translation id="4910889077668685004">Payment apps</translation> +<translation id="4913161338056004800">Reset statistics</translation> +<translation id="4913169188695071480">Stop refreshing</translation> +<translation id="4915549754973153784"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /> while scanning for devices…</translation> +<translation id="4943872375798546930">No results</translation> +<translation id="4956460920135325549">Lite page delivered by Google.</translation> +<translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> is sharing your screen</translation> +<translation id="4961334780091921942">Your passwords, history & more on all devices</translation> +<translation id="4961700429721424617">You are signing out of an account managed by <ph name="MANAGED_DOMAIN" />. This will delete your Chrome data from this device, but your data will remain in your Google account.</translation> +<translation id="497421865427891073">go forward</translation> +<translation id="4988210275050210843">Downloading file (<ph name="MEGABYTES" />).</translation> +<translation id="4988526792673242964">Pages</translation> +<translation id="4996978546172906250">Share via</translation> +<translation id="5004339818306944878">Use up to 60% less data and speed up the web. Google servers will optimise the pages you visit.</translation> +<translation id="5004416275253351869">Google activity controls</translation> +<translation id="5005498671520578047">Copy password</translation> +<translation id="5011311129201317034"><ph name="SITE" /> wants to connect</translation> +<translation id="5013696553129441713">No new suggestions</translation> +<translation id="5016205925109358554">Serif</translation> +<translation id="5039804452771397117">Allow</translation> +<translation id="5040262127954254034">Privacy</translation> +<translation id="5063480226653192405">Usage</translation> +<translation id="5087580092889165836">Add card</translation> +<translation id="5100237604440890931">Collapsed – click to expand.</translation> +<translation id="510275257476243843">1 hour left</translation> +<translation id="5123685120097942451">Incognito tab</translation> +<translation id="5127805178023152808">Sync is off</translation> +<translation id="5129038482087801250">Install web app</translation> +<translation id="5139940364318403933">Learn how to use Google Drive</translation> +<translation id="515227803646670480">Clear stored data</translation> +<translation id="5152843274749979095">No supported apps installed</translation> +<translation id="5161254044473106830">Title required</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download failed.}other{# downloads failed.}}</translation> +<translation id="5168917394043976756">Open navigation drawer</translation> +<translation id="5171365962177408781">Tap to load the new tab page and view suggested articles</translation> +<translation id="5184329579814168207">Open in Chrome</translation> +<translation id="5199929503336119739">Work profile</translation> +<translation id="5210286577605176222">Jump to the previous tab</translation> +<translation id="5210365745912300556">Close tab</translation> +<translation id="5222676887888702881">Sign out</translation> +<translation id="5224771365102442243">With video</translation> +<translation id="5233638681132016545">New tab</translation> +<translation id="5240817131241497236">The settings that control sync, personalisation and other Google services in Chrome have changed. This may affect your current settings.</translation> +<translation id="5264003212305142034"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised at any time. Google may use content on sites that you visit, plus browser activity and interactions, to personalise Chrome and other Google services such as Translate, Search and ads.</translation> +<translation id="5271967389191913893">Device cannot open the content to be downloaded.</translation> +<translation id="528192093759286357">Drag from top and touch the back button to exit full screen.</translation> +<translation id="5284584623296338184">Changes to your bookmarks, history, passwords and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google account.</translation> +<translation id="5300589172476337783">Show</translation> +<translation id="5301954838959518834">OK, got it</translation> +<translation id="5304593522240415983">This field cannot be blank</translation> +<translation id="5308380583665731573">Connect</translation> +<translation id="5308603654685598744">When this feature is turned on, Chrome will offer to translate pages written in other languages using Google Translate.</translation> +<translation id="5313967007315987356">Add site</translation> +<translation id="5317780077021120954">Save</translation> +<translation id="5324858694974489420">Parental Settings</translation> +<translation id="5327248766486351172">Name</translation> +<translation id="5335288049665977812">Allow sites to run JavaScript (recommended)</translation> +<translation id="5345040418939504969">Deleted <ph name="BOOKMARK_TITLE" /></translation> +<translation id="5372829067651257087">URL copied.</translation> +<translation id="5391532827096253100">Your connection to this site is not secure. Site information</translation> +<translation id="5400569084694353794">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="5403644198645076998">Only allow certain sites</translation> +<translation id="5414836363063783498">Verifying…</translation> +<translation id="5423934151118863508">Your most visited pages will appear here</translation> +<translation id="5424588387303617268"><ph name="GIGABYTES" /> GB available</translation> +<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="5447765697759493033">This site will not be translated</translation> +<translation id="545042621069398927">Speeding up your download.</translation> +<translation id="5456381639095306749">Download page</translation> +<translation id="5466407412363861127">This feature uses <ph name="BEGIN_LINK" />sync<ph name="END_LINK" />.</translation> +<translation id="548278423535722844">Open in maps app</translation> +<translation id="5487521232677179737">Clear data</translation> +<translation id="5487729733663684359">Chrome updates are no longer supported for this version of Android.</translation> +<translation id="5494920125229734069">Select all</translation> +<translation id="550684401320795253">Updating Chrome...</translation> +<translation id="5512137114520586844">This account is managed by <ph name="PARENT_NAME" />.</translation> +<translation id="5514904542973294328">Disabled by the administrator of this device</translation> +<translation id="5515439363601853141">Unlock to view your password</translation> +<translation id="5515716148775388141">Your icons have moved to the bottom of the screen</translation> +<translation id="5517095782334947753">You have bookmarks, history, passwords and other settings from <ph name="FROM_ACCOUNT" />.</translation> +<translation id="5524843473235508879">Redirect blocked.</translation> +<translation id="5527082711130173040">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK1" />Update permissions<ph name="END_LINK1" />. Location access is also <ph name="BEGIN_LINK2" />turned off for this device<ph name="END_LINK2" />.</translation> +<translation id="5527111080432883924">Ask before allowing sites to read text and images from the clipboard (recommended)</translation> +<translation id="5530766185686772672">Close incognito tabs</translation> +<translation id="5534640966246046842">Site copied</translation> +<translation id="5537099431952529648">You and your parents can manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="5556459405103347317">Reload</translation> +<translation id="5561549206367097665">Waiting for network…</translation> +<translation id="557283862590186398">Chrome needs permission to access your microphone for this site.</translation> +<translation id="55737423895878184">Location and notifications are allowed</translation> +<translation id="5578795271662203820">Search <ph name="SEARCH_ENGINE" /> for this image</translation> +<translation id="5595485650161345191">Edit address</translation> +<translation id="5596627076506792578">More options</translation> +<translation id="5620299005957670886">Allow sites to access your sensors (recommended)</translation> +<translation id="5620928963363755975">Find your files and pages in Downloads from the More Options button</translation> +<translation id="5626134646977739690">Name:</translation> +<translation id="5639724618331995626">Allow all sites</translation> +<translation id="5648166631817621825">Last 7 days</translation> +<translation id="5655963694829536461">Search your downloads</translation> +<translation id="5659593005791499971">Email</translation> +<translation id="5665379678064389456">Create event in <ph name="APP_NAME" /></translation> +<translation id="5668404140385795438">Override a website’s request to prevent zooming in</translation> +<translation id="5676636989614905379">Cannot play video on <ph name="SCREEN_NAME" />.</translation> +<translation id="5677928146339483299">Blocked</translation> +<translation id="5684874026226664614">Oops. This page could not be translated.</translation> +<translation id="5686790454216892815">File name too long</translation> +<translation id="5689516760719285838">Location</translation> +<translation id="5719837394786370183">Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your incognito tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your Internet service provider or the websites you visit.</translation> +<translation id="572328651809341494">Recent tabs</translation> +<translation id="5726692708398506830">Make everything on the page bigger</translation> +<translation id="5738816946784116349">Chrome Downloads</translation> +<translation id="5748802427693696783">Switched to standard tabs</translation> +<translation id="5749068826913805084">Chrome needs storage access to download files.</translation> +<translation id="5763382633136178763">Incognito tabs</translation> +<translation id="5763514718066511291">Tap to copy the URL for this app</translation> +<translation id="5765780083710877561">Description:</translation> +<translation id="5777170031995031090">Control how Google uses your browsing history to personalise Search, ads and other Google services.</translation> +<translation id="5793665092639000975">Using <ph name="SPACE_USED" /> of <ph name="SPACE_AVAILABLE" /></translation> +<translation id="5804241973901381774">Permissions</translation> +<translation id="5809361687334836369">{HOURS,plural, =1{# hour ago}other{# hours ago}}</translation> +<translation id="5817918615728894473">Pair</translation> +<translation id="583281660410589416">Unknown</translation> +<translation id="5833397272224757657">Uses content on sites that you visit, plus browser activity and interactions, for personalisation</translation> +<translation id="5833984609253377421">Share link</translation> +<translation id="584427517463557805">Selected private tab</translation> +<translation id="5854790677617711513">Older than 30 days</translation> +<translation id="5858741533101922242">Chrome is unable to turn on Bluetooth adaptor</translation> +<translation id="5860033963881614850">Off</translation> +<translation id="5862731021271217234">To get your tabs from your other devices, turn on sync</translation> +<translation id="5864174910718532887">Details: Sorted by site name</translation> +<translation id="5864419784173784555">Waiting for another download…</translation> +<translation id="5865733239029070421">Automatically sends usage statistics and crash reports to Google</translation> +<translation id="5869522115854928033">Saved passwords</translation> +<translation id="5878455346526065919">Block ads from sites that tend to show intrusive ads</translation> +<translation id="5902828464777634901">All local data stored by this website, including cookies, will be deleted.</translation> +<translation id="5911030830365207728">Google Translate</translation> +<translation id="5916664084637901428">On</translation> +<translation id="5919204609460789179">Update <ph name="PRODUCT_NAME" /> to start sync</translation> +<translation id="5937580074298050696"><ph name="AMOUNT" /> saved</translation> +<translation id="5939518447894949180">Reset</translation> +<translation id="5942872142862698679">Using Google for search</translation> +<translation id="5952764234151283551">Sends the URL of a page that you're trying to reach to Google</translation> +<translation id="5956665950594638604">Open the Chrome Help Centre in a new tab</translation> +<translation id="5958275228015807058">Find your files and pages in Downloads</translation> +<translation id="5962718611393537961">Tap to collapse</translation> +<translation id="5990142338020175451">More personal Google services, such as better page suggestions</translation> +<translation id="6000066717592683814">Keep Google</translation> +<translation id="6005538289190791541">Suggested password</translation> +<translation id="6039379616847168523">Jump to the next tab</translation> +<translation id="6040143037577758943">Close</translation> +<translation id="6042308850641462728">More</translation> +<translation id="604996488070107836"><ph name="FILE_NAME" /> download failed due to an unknown error.</translation> +<translation id="605721222689873409">YY</translation> +<translation id="6075798973483050474">Edit home page</translation> +<translation id="60923314841986378"><ph name="HOURS" /> hours left</translation> +<translation id="60924377787140961">More articles will appear soon. Enjoy your afternoon!</translation> +<translation id="6099151465289169210">Switched to private tabs</translation> +<translation id="6108923351542677676">Setup in progress…</translation> +<translation id="6111020039983847643">data used</translation> +<translation id="6112702117600201073">Refreshing page</translation> +<translation id="6127379762771434464">Item removed</translation> +<translation id="6140912465461743537">Country/Region</translation> +<translation id="6154478581116148741">Turn on screen lock in Settings to export your passwords from this device</translation> +<translation id="6159335304067198720"><ph name="PERCENT" /> data savings</translation> +<translation id="6165508094623778733">Learn more</translation> +<translation id="6177111841848151710">Blocked for current search engine</translation> +<translation id="6177390657002841081">Turn on Data Saver</translation> +<translation id="6181444274883918285">Add site exception</translation> +<translation id="618993374665929060">More like this opened at full height</translation> +<translation id="6192333916571137726">Download File</translation> +<translation id="6192792657125177640">Exceptions</translation> +<translation id="6206551242102657620">Connection is secure. Site information</translation> +<translation id="6210748933810148297">Not <ph name="EMAIL" />?</translation> +<translation id="6216432067784365534"><ph name="NAME_OF_LIST_ITEM" /> Options</translation> +<translation id="6221633008163990886">Unlock to export your passwords</translation> +<translation id="6232535412751077445">Enabling “Do Not Track” means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request and how the request is interpreted. + +For example, some websites may respond to this request by showing you ads that aren’t based on other websites that you’ve visited. Many websites will still collect and use your browsing data – for example to improve security, to provide content, ads and recommendations and to generate reporting statistics.</translation> +<translation id="6255999984061454636">Content suggestions</translation> +<translation id="6277522088822131679">There was a problem printing the page. Please try again.</translation> +<translation id="6295158916970320988">All sites</translation> +<translation id="629730747756840877">Account</translation> +<translation id="6303969859164067831">Sign out and turn off sync</translation> +<translation id="6320088164292336938">Vibrate</translation> +<translation id="6324034347079777476">Android system sync disabled</translation> +<translation id="6333140779060797560">Share via <ph name="APPLICATION" /></translation> +<translation id="6336451774241870485">New private tab</translation> +<translation id="6337234675334993532">Encryption</translation> +<translation id="6341580099087024258">Ask where to save files</translation> +<translation id="6343192674172527289">No downloads found</translation> +<translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}}</translation> +<translation id="6364438453358674297">Remove suggestion from history?</translation> +<translation id="6378173571450987352">Details: Sorted by amount of data used</translation> +<translation id="6383961787135158834">Clear Site Storage…</translation> +<translation id="6388207532828177975">Clear & reset</translation> +<translation id="6393863479814692971">Chrome needs permission to access your camera and microphone for this site.</translation> +<translation id="6395288395575013217">LINK</translation> +<translation id="6404511346730675251">Edit bookmark</translation> +<translation id="6406506848690869874">Sync</translation> +<translation id="641643625718530986">Print…</translation> +<translation id="6416782512398055893">Downloaded <ph name="MBS" /> MB</translation> +<translation id="6433501201775827830">Choose your search engine</translation> +<translation id="6437478888915024427">Page info</translation> +<translation id="6447842834002726250">Cookies</translation> +<translation id="6448273550210938826">Search and URL suggestions</translation> +<translation id="6461962085415701688">Can’t open file</translation> +<translation id="6475951671322991020">Download video</translation> +<translation id="6482749332252372425"><ph name="FILE_NAME" /> download failed due to lack of storage space.</translation> +<translation id="6496823230996795692">To use <ph name="APP_NAME" /> for the first time, please connect to the Internet.</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6534565668554028783">Google took too long to respond</translation> +<translation id="6538442820324228105">Downloaded <ph name="GBS" /> GB</translation> +<translation id="654446541061731451">Select a tab to beam</translation> +<translation id="6545017243486555795">Clear All Data</translation> +<translation id="6556716549745717622">Block if site tends to show intrusive ads (recommended)</translation> +<translation id="6560414384669816528">Search with Sogou</translation> +<translation id="6566259936974865419">Chrome has saved you <ph name="GIGABYTES" /> GB</translation> +<translation id="6573096386450695060">Always allow</translation> +<translation id="6573431926118603307">Tabs that you've opened in Chrome on your other devices will appear here.</translation> +<translation id="6575643671698722332">Reset failed. Ensure that your device is online and try again.</translation> +<translation id="6583199322650523874">Bookmark the current page</translation> +<translation id="6584721918629302382">AR</translation> +<translation id="6593061639179217415">Desktop site</translation> +<translation id="6600954340915313787">Copied to Chrome</translation> +<translation id="6608650720463149374"><ph name="GIGABYTES" /> GB</translation> +<translation id="6610147964972079463">Close private tabs</translation> +<translation id="6612358246767739896">Protected content</translation> +<translation id="6627583120233659107">Edit folder</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6643649862576733715">Sort by amount of data saved</translation> +<translation id="6648977384226967773">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}other{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}}</translation> +<translation id="6656545060687952787">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK" />Update permissions<ph name="END_LINK" /></translation> +<translation id="6657585470893396449">Password</translation> +<translation id="6659594942844771486">Tab</translation> +<translation id="666268767214822976">Use a prediction service to show related queries and popular websites as you type in the address bar</translation> +<translation id="666731172850799929">Open in <ph name="APP_NAME" /></translation> +<translation id="666981079809192359">Chrome Privacy Notice</translation> +<translation id="6697492270171225480">Show suggestions for similar pages when a page can't be found</translation> +<translation id="6697947395630195233">Chrome needs access to your location to share your location with this site.</translation> +<translation id="6698801883190606802">Manage synced data</translation> +<translation id="6710213216561001401">Previous</translation> +<translation id="6712388303105732168">See more like this from Google using the More Like This button</translation> +<translation id="6738867403308150051">Downloading…</translation> +<translation id="6746124502594467657">Move down</translation> +<translation id="6762156594045689028">To change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="6766622839693428701">Swipe down to close.</translation> +<translation id="6770414673596662518">Chrome’s Safe Browsing system will also be used to detect malicious pages and protect you from phishing, malware and harmful downloads.</translation> +<translation id="6776813977906306442">Download videos to watch later using the Download button</translation> +<translation id="6790428901817661496">Play</translation> +<translation id="679325081238418596">Get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="6820607729870073286">You have no saved website settings.</translation> +<translation id="6820686453637990663">CVC</translation> +<translation id="6831043979455480757">Translate</translation> +<translation id="6846298663435243399">Loading…</translation> +<translation id="685040365210406336">Make no changes</translation> +<translation id="6850409657436465440">Your download is still in progress</translation> +<translation id="6850830437481525139"><ph name="TAB_COUNT" /> tabs closed</translation> +<translation id="6864459304226931083">Download image</translation> +<translation id="6865313869410766144">Autofill form data</translation> +<translation id="6868088497967843822">Sign in to get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="688738109438487280">Add existing data to <ph name="TO_ACCOUNT" />.</translation> +<translation id="6891726759199484455">Unlock to copy your password</translation> +<translation id="6891858906296486776">{OPEN_TABS,plural, =1{%1$d open tab}other{%1$d open tabs}}</translation> +<translation id="6896758677409633944">Copy</translation> +<translation id="6910211073230771657">Deleted</translation> +<translation id="6912998170423641340">Block sites from reading text and images from the clipboard</translation> +<translation id="6914783257214138813">Your passwords will be visible to anyone who can see the exported file.</translation> +<translation id="6942665639005891494">Change the default download location at any time using the Settings menu option</translation> +<translation id="6945221475159498467">Select</translation> +<translation id="6963642900430330478">This page is dangerous. Site information</translation> +<translation id="6963766334940102469">Delete bookmarks</translation> +<translation id="6965382102122355670">OK</translation> +<translation id="6978479750597523876">Reset translate settings</translation> +<translation id="6979737339423435258">All time</translation> +<translation id="6981982820502123353">Accessibility</translation> +<translation id="6985347914332179298">No downloads here</translation> +<translation id="6990079615885386641">Get the app from the Google Play Store: <ph name="APP_ACTION" /></translation> +<translation id="699220179437400583">Automatically report details of possible security incidents to Google</translation> +<translation id="6992289844737586249">Ask first before allowing sites to use your microphone (recommended)</translation> +<translation id="7016516562562142042">Allowed for current search engine</translation> +<translation id="7021515813996758557"><ph name="FILE_NAME" /> downloaded</translation> +<translation id="7022756207310403729">Open in browser</translation> +<translation id="702463548815491781">Recommended when TalkBack or Switch Access are on</translation> +<translation id="7029809446516969842">Passwords</translation> +<translation id="7031882061095297553">Sync to</translation> +<translation id="7032663816368481562">When you tap More like this <ph name="ICON" /> in the address bar, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="7034608350006174882">Cards and addresses using Google Pay</translation> +<translation id="7053983685419859001">Block</translation> +<translation id="7055152154916055070">Redirect blocked:</translation> +<translation id="7062545763355031412">Accept and switch accounts</translation> +<translation id="7063006564040364415">Could not connect to the sync server.</translation> +<translation id="7066151586745993502">{NUM_SELECTED,plural, =1{1 selected}other{# selected}}</translation> +<translation id="7077143737582773186">SD Card</translation> +<translation id="7087918508125750058"><ph name="ITEM_COUNT" /> selected. Options available near top of the screen</translation> +<translation id="7108338896283013870">Hide</translation> +<translation id="7121362699166175603">Clears history and autocompletions in the address bar. 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="7128222689758636196">Allow for current search engine</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7139148793369023665">More like this closed</translation> +<translation id="7141896414559753902">Block sites from showing pop-ups and redirects (recommended)</translation> +<translation id="7149158118503947153"><ph name="BEGIN_LINK" />Load original page<ph name="END_LINK" /> from <ph name="DOMAIN_NAME" /></translation> +<translation id="7149893636342594995">Last 24 Hours</translation> +<translation id="7176368934862295254"><ph name="KILOBYTES" /> KB</translation> +<translation id="7177466738963138057">You can change this later in Settings</translation> +<translation id="7180611975245234373">Refresh</translation> +<translation id="7189372733857464326">Waiting for Google Play Services to finish updating</translation> +<translation id="7189598951263744875">Share...</translation> +<translation id="7191430249889272776">Tab opened in background.</translation> +<translation id="723171743924126238">Select images</translation> +<translation id="7243308994586599757">Options available near bottom of the screen</translation> +<translation id="7250468141469952378"><ph name="ITEM_COUNT" /> selected</translation> +<translation id="7251326866581677552">Blocked from some sites</translation> +<translation id="7253272406652746122">Add a Google account from the Accounts page in your device’s Settings app.</translation> +<translation id="7274013316676448362">Blocked site</translation> +<translation id="729975465115245577">Your device doesn’t have an app to store the passwords file.</translation> +<translation id="7302081693174882195">Details: Sorted by amount of data saved</translation> +<translation id="7333031090786104871">Still adding previous site</translation> +<translation id="7352939065658542140">VIDEO</translation> +<translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Share 1 selected item}other{Share # selected items}}</translation> +<translation id="7359002509206457351">Access payment methods</translation> +<translation id="7366340029385295517">Casting to <ph name="SCREEN_NAME" /></translation> +<translation id="7375125077091615385">Type:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> +<translation id="7400418766976504921">URL</translation> +<translation id="7403691278183511381">Chrome First Run Experience</translation> +<translation id="741204030948306876">Yes, I'm in</translation> +<translation id="7413229368719586778">Start date <ph name="DATE" /></translation> +<translation id="7423098979219808738">Ask first</translation> +<translation id="7423538860840206698">Blocked from reading clipboard</translation> +<translation id="7431991332293347422">Control how your browsing history is used to personalise Search and more</translation> +<translation id="7437998757836447326">Sign out of Chrome</translation> +<translation id="7444811645081526538">More categories</translation> +<translation id="7445411102860286510">Allow sites to automatically play muted videos (recommended)</translation> +<translation id="7454641608352164238">Not enough space</translation> +<translation id="7455923816558154057">Tap to view</translation> +<translation id="7465104139234185284">Close all private tabs</translation> +<translation id="7473891865547856676">No Thanks</translation> +<translation id="7475192538862203634">If you’re seeing this frequently, try these <ph name="BEGIN_LINK" />suggestions<ph name="END_LINK" />.</translation> +<translation id="7475688122056506577">SD card not found. Some of your files may be missing.</translation> +<translation id="748127970106343339">Confirm device credential deletion</translation> +<translation id="7481312909269577407">Forward</translation> +<translation id="7493994139787901920"><ph name="VERSION" /> (Updated <ph name="TIME_SINCE_UPDATE" />)</translation> +<translation id="7494879913343971937">Show passwords</translation> +<translation id="7494974237137038751">data saved</translation> +<translation id="7498271377022651285">Please wait…</translation> +<translation id="7514365320538308">Download</translation> +<translation id="751961395872307827">Can't connect to the site</translation> +<translation id="7521387064766892559">JavaScript</translation> +<translation id="7542481630195938534">Can’t get suggestions</translation> +<translation id="7562080006725997899">Clear browsing data</translation> +<translation id="756809126120519699">Cleared Chrome data</translation> +<translation id="757524316907819857">Block sites from playing protected content</translation> +<translation id="7589445247086920869">Block for current search engine</translation> +<translation id="7593557518625677601">Open Android settings and re-enable Android system sync to start Chrome sync</translation> +<translation id="7596558890252710462">Operating system</translation> +<translation id="7605594153474022051">Sync isn't working</translation> +<translation id="7612619742409846846">Signed in to Google as</translation> +<translation id="7619072057915878432"><ph name="FILE_NAME" /> download failed due to network failures.</translation> +<translation id="7624880197989616768"><ph name="BEGIN_LINK1" />Get help<ph name="END_LINK1" /> or <ph name="BEGIN_LINK2" />re-scan<ph name="END_LINK2" /></translation> +<translation id="7626032353295482388">Welcome to Chrome</translation> +<translation id="7638584964844754484">Incorrect passphrase</translation> +<translation id="7641339528570811325">Clear browsing data…</translation> +<translation id="7648422057306047504">Encrypt passwords with Google credentials</translation> +<translation id="7649070708921625228">Help</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7665369617277396874">Add account</translation> +<translation id="7682724950699840886">Try the following tips: make sure that there is enough space on your device; try to export again.</translation> +<translation id="7698359219371678927">Create email in <ph name="APP_NAME" /></translation> +<translation id="7704317875155739195">Auto-complete searches and URLs</translation> +<translation id="773466115871691567">Always translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> +<translation id="773905249182896430">Protects you and your device from dangerous sites</translation> +<translation id="7762668264895820836">SD Card <ph name="SD_CARD_NUMBER" /></translation> +<translation id="7764225426217299476">Add address</translation> +<translation id="7765158879357617694">Move</translation> +<translation id="7769602470925380267">Accept and sign out</translation> +<translation id="7772032839648071052">Confirm passphrase</translation> +<translation id="7774809984919390718">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}other{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}}</translation> +<translation id="7781829728241885113">Yesterday</translation> +<translation id="7791543448312431591">Add</translation> +<translation id="780301667611848630">No, thank you</translation> +<translation id="7810647596859435254">Open with…</translation> +<translation id="7821588508402923572">Your data savings will appear here</translation> +<translation id="7832327313660264358">The data that you sync to Google and the features that you use will not change</translation> +<translation id="7837721118676387834">Allow auto-play of muted videos for a specific site.</translation> +<translation id="7846076177841592234">Cancel selection</translation> +<translation id="784934925303690534">Time range</translation> +<translation id="7851858861565204677">Other Devices</translation> +<translation id="7854964836418414587">Close more like this</translation> +<translation id="7875915731392087153">Create email</translation> +<translation id="7876243839304621966">Remove all</translation> +<translation id="7882131421121961860">No history found</translation> +<translation id="7882806643839505685">Allow sound for a specific site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Downloading file.}other{Downloading # files.}}</translation> +<translation id="7929962904089429003">Opening the menu</translation> +<translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> is out of date.</translation> +<translation id="7947953824732555851">Accept and sign in</translation> +<translation id="7963646190083259054">Vendor:</translation> +<translation id="7981313251711023384">Preload pages for faster browsing and searching</translation> +<translation id="79859296434321399">To view augmented reality content, install ARCore</translation> +<translation id="7986741934819883144">Select a contact</translation> +<translation id="7987073022710626672">Chrome Terms of Service</translation> +<translation id="7987764905897278458">Get more Google smarts</translation> +<translation id="7998918019931843664">Re-open closed tab</translation> +<translation id="7999064672810608036">Are you sure that you want to clear all local data, including cookies, and reset all permissions for this website?</translation> +<translation id="8004582292198964060">Browser</translation> +<translation id="8007176423574883786">Turned off for this device</translation> +<translation id="8015452622527143194">Return everything on the page to default size</translation> +<translation id="802154636333426148">Download failed</translation> +<translation id="8026334261755873520">Clear browsing data</translation> +<translation id="8035133914807600019">New folder…</translation> +<translation id="8037411810184515274">VR</translation> +<translation id="8037686209485537503">More like this</translation> +<translation id="8037750541064988519"><ph name="DAYS" /> days left</translation> +<translation id="804335162455518893">SD card not found</translation> +<translation id="805047784848435650">Based on your browsing history</translation> +<translation id="8051695050440594747"><ph name="MEGABYTES" /> MB available</translation> +<translation id="8058746566562539958">Open in new Chrome tab</translation> +<translation id="8063895661287329888">Failed to add bookmark.</translation> +<translation id="806745655614357130">Keep my data separate</translation> +<translation id="8068648041423924542">Unable to select certificate.</translation> +<translation id="8073388330009372546">Open image in new tab</translation> +<translation id="8084114998886531721">Saved password</translation> +<translation id="8087000398470557479">This content is from <ph name="DOMAIN_NAME" />, delivered by Google.</translation> +<translation id="8103578431304235997">Incognito Tab</translation> +<translation id="8105951947646329362">Suggest related pages</translation> +<translation id="8109613176066109935">To get your bookmarks on all your devices, turn on sync</translation> +<translation id="8116925261070264013">Muted</translation> +<translation id="813082847718468539">View site information</translation> +<translation id="8156139159503939589">What languages do you read?</translation> +<translation id="8168435359814927499">Content</translation> +<translation id="8186512483418048923"><ph name="FILES" /> files left</translation> +<translation id="8190358571722158785">1 day left</translation> +<translation id="8200772114523450471">Resume</translation> +<translation id="8209050860603202033">Open image</translation> +<translation id="8220488350232498290"><ph name="GIGABYTES" /> GB downloaded</translation> +<translation id="8249310407154411074">Move to top</translation> +<translation id="8250920743982581267">Documents</translation> +<translation id="825412236959742607">This page uses too much memory, so Chrome removed some content.</translation> +<translation id="8260126382462817229">Try signing in again</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8266862848225348053">Download location</translation> +<translation id="8274165955039650276">See downloads</translation> +<translation id="8283853025636624853">Syncing to <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8310344678080805313">Standard tabs</translation> +<translation id="8313455859591948645">Edit startup page</translation> +<translation id="8316092324682955408"><ph name="DOMAIN_NAME" /> and more sites</translation> +<translation id="8339163506404995330">Pages in <ph name="LANGUAGE" /> will not be translated</translation> +<translation id="8349013245300336738">Sort by amount of data used</translation> +<translation id="8372893542064058268">Allow Background Sync for a specific site.</translation> +<translation id="8374821112118309944">You need to update TalkBack to a newer version.</translation> +<translation id="8393700583063109961">Send message</translation> +<translation id="8413126021676339697">Show full history</translation> +<translation id="8428213095426709021">Settings</translation> +<translation id="8438566539970814960">Make searches and browsing better</translation> +<translation id="8441146129660941386">Seek backward</translation> +<translation id="8445448999790540984">Can’t export passwords</translation> +<translation id="8447861592752582886">Revoke device permission</translation> +<translation id="8477071352266846533">Sync off for <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8487700953926739672">Available offline</translation> +<translation id="8489271220582375723">Open the history page</translation> +<translation id="8493948351860045254">Free up space</translation> +<translation id="8497726226069778601">Nothing to see here… yet</translation> +<translation id="8503559462189395349">Chrome Passwords</translation> +<translation id="8503813439785031346">Username</translation> +<translation id="8504988642345501642">When you scroll up, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="8507520749471379845">Passwords available</translation> +<translation id="8514477925623180633">Export passwords stored with Chrome</translation> +<translation id="8514577642972634246">Enter incognito mode</translation> +<translation id="851751545965956758">Block sites from connecting to devices</translation> +<translation id="8523928698583292556">Delete stored password</translation> +<translation id="854522910157234410">Open this page:</translation> +<translation id="8558485628462305855">To view augmented reality content, update ARCore</translation> +<translation id="8559990750235505898">Offer to translate pages in other languages</translation> +<translation id="8562452229998620586">Your saved passwords will appear here.</translation> +<translation id="8569404424186215731">since <ph name="DATE" /></translation> +<translation id="8571213806525832805">Last 4 weeks</translation> +<translation id="857509777403223202">More articles will appear soon. Enjoy your evening!</translation> +<translation id="857943718398505171">Allowed (recommended)</translation> +<translation id="8583805026567836021">Clearing account data</translation> +<translation id="8609465669617005112">Move up</translation> +<translation id="8616006591992756292">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="8617240290563765734">Open the suggested URL specified in the downloaded content?</translation> +<translation id="862875433388403934">Content (films, music, etc.) downloaded in other applications may no longer be playable until those applications re-acquire licences based on a new device credential. To obtain new licences, connect to the Internet and play your downloaded content.</translation> +<translation id="8636825310635137004">To get your tabs from your other devices, turn on sync.</translation> +<translation id="8641930654639604085">Try to block mature sites</translation> +<translation id="8662811608048051533">Signs you out of most sites.</translation> +<translation id="8664979001105139458">File name already exists</translation> +<translation id="8676374126336081632">Clear input</translation> +<translation id="8687353297350450808">{N_BARS,plural, =1{Signal Strength Level: # bar}other{Signal Strength Level: # bars}}</translation> +<translation id="868929229000858085">Search your contacts</translation> +<translation id="869891660844655955">Expiry date</translation> +<translation id="8719023831149562936">Can’t beam current tab</translation> +<translation id="8725066075913043281">Try again</translation> +<translation id="8728487861892616501">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8730621377337864115">Done</translation> +<translation id="8748850008226585750">Contents hidden</translation> +<translation id="8751914237388039244">Select an image</translation> +<translation id="8788968922598763114">Reopen the last closed tab</translation> +<translation id="8812260976093120287">On some websites, you can pay with above supported payment apps on your device.</translation> +<translation id="8816439037877937734"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome's <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8820817407110198400">Bookmarks</translation> +<translation id="8823704566850948458">Suggest password...</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> +<translation id="883806473910249246">An error occurred while downloading the content.</translation> +<translation id="8840953339110955557">This page may differ from the online version.</translation> +<translation id="8847988622838149491">USB</translation> +<translation id="8853345339104747198"><ph name="TAB_TITLE" />, tab</translation> +<translation id="885701979325669005">Storage</translation> +<translation id="8901170036886848654">No bookmarks found</translation> +<translation id="8909135823018751308">Share…</translation> +<translation id="8912362522468806198">Google Account</translation> +<translation id="8920114477895755567">Waiting for details of parents.</translation> +<translation id="8922289737868596582">Download pages from the More Options button to use them offline</translation> +<translation id="8941729603749328384">www.example.com</translation> +<translation id="8942627711005830162">Open in other window</translation> +<translation id="8951232171465285730">Chrome has saved you <ph name="MEGABYTES" /> MB</translation> +<translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> +<translation id="8972098258593396643">Download to default folder?</translation> +<translation id="8979405271719829084">Download videos to watch later</translation> +<translation id="8981454092730389528">Google Activity Controls</translation> +<translation id="8983677657449185470">Help improve Safe Browsing</translation> +<translation id="8986494364107987395">Automatically send usage statistics and crash reports to Google</translation> +<translation id="8993760627012879038">Open a new tab in Incognito mode</translation> +<translation id="8998729206196772491">You are signing in with an account managed by <ph name="MANAGED_DOMAIN" /> and giving its administrator control over your Chrome data. Your data will become permanently tied to this account. Signing out of Chrome will delete your data from this device, but it will remain stored in your Google account.</translation> +<translation id="9019902583201351841">Managed by your parents</translation> +<translation id="9040142327097499898">Notifications are allowed. Location is off for this device.</translation> +<translation id="9050666287014529139">Passphrase</translation> +<translation id="9060538597317784206">View app <ph name="APP_NAME" /> on the Play Store. Rating: <ph name="APP_RATING" />.</translation> +<translation id="9063523880881406963">Turn off Request desktop site</translation> +<translation id="9065203028668620118">Edit</translation> +<translation id="9070377983101773829">Start voice search</translation> +<translation id="9071742570345586758">To view virtual reality content, install Google VR Services</translation> +<translation id="9074336505530349563">To get personalised content suggested by Google, sign in and turn on sync</translation> +<translation id="9080642952018487277">Enter private mode</translation> +<translation id="9086455579313502267">Unable to access the network</translation> +<translation id="9099018167121903954"><ph name="KILOBYTES" /> KB downloaded</translation> +<translation id="9100505651305367705">Offer to show articles in simplified view, when supported</translation> +<translation id="9100610230175265781">Passphrase required</translation> +<translation id="9100939710791843300">Tap the home button to load the new tab page and view suggested articles</translation> +<translation id="9133515669113036225">Reset device credentials</translation> +<translation id="9133703968756164531"><ph name="ITEM_NAME" /> (<ph name="ITEM_ID" />)</translation> +<translation id="9137013805542155359">Show original</translation> +<translation id="9139068048179869749">Ask before allowing sites to send notifications (recommended)</translation> +<translation id="9155898266292537608">You can also search with a quick tap on a word</translation> +<translation id="9188680907066685419">Sign out of managed account</translation> +<translation id="9204836675896933765">1 file left</translation> +<translation id="9206873250291191720">A</translation> +<translation id="9218033835049520260">Suggest strong password...</translation> +<translation id="9219103736887031265">Images</translation> +<translation id="932327136139879170">Home</translation> +<translation id="932599481871055447">Save data and browse faster</translation> +<translation id="938850635132480979">Error: <ph name="ERROR_CODE" /></translation> +<translation id="945522503751344254">Send feedback</translation> +<translation id="945632385593298557">Access your microphone</translation> +<translation id="951339005376969845">Delete existing data. You can retrieve it by switching back to <ph name="FROM_ACCOUNT" />.</translation> +<translation id="95817756606698420">Chrome can use <ph name="BEGIN_BOLD" />Sogou<ph name="END_BOLD" /> for search in China. You can change this in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="970715775301869095"><ph name="MINUTES" /> mins left</translation> +<translation id="974555521953189084">Enter your passphrase to start sync</translation> +<translation id="981121421437150478">Offline</translation> +<translation id="982182592107339124">This will clear data for all sites, including:</translation> +<translation id="983192555821071799">Close all tabs</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_et.xtb b/chrome/android/java/strings/translations/android_chrome_strings_et.xtb new file mode 100644 index 0000000..d9f43da9 --- /dev/null +++ b/chrome/android/java/strings/translations/android_chrome_strings_et.xtb
@@ -0,0 +1,1056 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="et"> +<translation id="1006017844123154345">Open Online</translation> +<translation id="1036727731225946849">Adding <ph name="WEBAPK_NAME" />...</translation> +<translation id="1041308826830691739">From websites</translation> +<translation id="1049743911850919806">Incognito</translation> +<translation id="1054301162707478098">You’ve gone private.</translation> +<translation id="10614374240317010">Never saved</translation> +<translation id="1067922213147265141">Other Google services</translation> +<translation id="1068672505746868501">Never translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="10713315585330490"><ph name="FILE_SIZE" /> – <ph name="DESCRIPTION" /></translation> +<translation id="1080790410959514870">You are signing out of an account managed by <ph name="DOMAIN_NAME" />. This will delete the Chrome data stored on this device, but the data will remain in your Google Account.</translation> +<translation id="1105960400813249514">Screen Capture</translation> +<translation id="1111673857033749125">Bookmarks saved on your other devices will appear here.</translation> +<translation id="1113597929977215864">Show simplified view</translation> +<translation id="1121094540300013208">Usage and crash reports</translation> +<translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download pending.}other{# downloads pending.}}</translation> +<translation id="1145536944570833626">Delete existing data.</translation> +<translation id="1146678959555564648">Enter VR</translation> +<translation id="114721135501989771">Get Google smarts in Chrome</translation> +<translation id="1157102636231978136">Your browsing data and activity, synced to your Google account</translation> +<translation id="116280672541001035">Used</translation> +<translation id="1172593791219290334">Startup Page</translation> +<translation id="1175310183703641346">Your bookmarks, history, passwords and more will no longer be synced to your Google account</translation> +<translation id="1178581264944972037">Pause</translation> +<translation id="1181037720776840403">Remove</translation> +<translation id="1197267115302279827">Move bookmarks</translation> +<translation id="119944043368869598">Clear all</translation> +<translation id="1201402288615127009">Next</translation> +<translation id="1204037785786432551">Download link</translation> +<translation id="1206892813135768548">Copy link text</translation> +<translation id="1208340532756947324">To sync and personalise across devices, turn on sync</translation> +<translation id="1209206284964581585">Hide for now</translation> +<translation id="123724288017357924">Reload the current page, ignoring cached content</translation> +<translation id="124116460088058876">More languages</translation> +<translation id="124678866338384709">Close current tab</translation> +<translation id="1258753120186372309">Google doodle: <ph name="DOODLE_DESCRIPTION" /></translation> +<translation id="1259100630977430756">Pages that you view in private tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your private tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going private doesn’t hide your browsing from your employer, your Internet service provider or the websites that you visit.</translation> +<translation id="127138278192656016">Use sync and all services</translation> +<translation id="1272079795634619415">Stop</translation> +<translation id="1283039547216852943">Tap to expand</translation> +<translation id="1285320974508926690">Never translate this site</translation> +<translation id="1291207594882862231">Clear history, cookies, site data, cache…</translation> +<translation id="129553762522093515">Recently closed</translation> +<translation id="1326317727527857210">To get your tabs from your other devices, sign in to Chrome.</translation> +<translation id="1332501820983677155">Google Chrome feature shortcuts</translation> +<translation id="1360432990279830238">Sign out and turn off sync?</translation> +<translation id="136248372334525878">Preload pages for faster loading and offline reading</translation> +<translation id="1369915414381695676">Site <ph name="SITE_NAME" /> added</translation> +<translation id="1373696734384179344">Insufficient memory to download the selected content.</translation> +<translation id="1376578503827013741">Computing…</translation> +<translation id="138361230106469022">Hi, <ph name="FULL_NAME" /></translation> +<translation id="1383876407941801731">Search</translation> +<translation id="1384959399684842514">Download paused</translation> +<translation id="1389974829397082527">No bookmarks here</translation> +<translation id="1397811292916898096">Search with <ph name="PRODUCT_NAME" /></translation> +<translation id="1397854323885047133">Sync and personalisation</translation> +<translation id="1404122904123200417">Embedded in <ph name="WEBSITE_URL" /></translation> +<translation id="1406000523432664303">“Do Not Track”</translation> +<translation id="1407135791313364759">Open all</translation> +<translation id="1409426117486808224">Simplified view for open tabs</translation> +<translation id="1409879593029778104"><ph name="FILE_NAME" /> download prevented because file already exists.</translation> +<translation id="1414981605391750300">Contacting Google. This may take a minute…</translation> +<translation id="1416550906796893042">Application version</translation> +<translation id="1430915738399379752">Print</translation> +<translation id="1445680696957526815">Chrome’s components are incompatible with one another. Chrome may be upgrading, please try again in a few minutes. If the problem continues, try uninstalling and re-installing Chrome.</translation> +<translation id="1446450296470737166">Allow full control of MIDI devices</translation> +<translation id="145097072038377568">Turned off in Android Settings</translation> +<translation id="1477626028522505441"><ph name="FILE_NAME" /> download failed due to server issues.</translation> +<translation id="1506061864768559482">Search engine</translation> +<translation id="1513352483775369820">Bookmarks and web history</translation> +<translation id="1513858653616922153">Delete password</translation> +<translation id="1516229014686355813">Tap to Search sends the selected word and the current page as context to Google Search. You can turn it off in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="1539064842193522527">Link opened in Chrome</translation> +<translation id="1549000191223877751">Move to other window</translation> +<translation id="1553358976309200471">Update Chrome</translation> +<translation id="1566400915470565838">To use <ph name="APP_NAME" />, please connect to the Internet.</translation> +<translation id="1569387923882100876">Connected device</translation> +<translation id="1571304935088121812">Copy username</translation> +<translation id="1576370611341449972">Download occurs only on Wi-Fi</translation> +<translation id="1612196535745283361">Chrome needs location access to scan for devices. Location access is <ph name="BEGIN_LINK" />turned off for this device<ph name="END_LINK" />.</translation> +<translation id="162035744160882748">Turn on sync, personalisation and other Google services</translation> +<translation id="1620510694547887537">Camera</translation> +<translation id="1623104350909869708">Prevent this page from creating additional dialogues</translation> +<translation id="1628019612362412531">{NUM_SELECTED,plural, =1{Remove 1 selected item}other{Remove # selected items}}</translation> +<translation id="1641113438599504367">Safe Browsing</translation> +<translation id="164269334534774161">You are viewing an offline copy of this page from <ph name="CREATION_TIME" /></translation> +<translation id="1644574205037202324">History</translation> +<translation id="1647391597548383849">Access your camera</translation> +<translation id="1660204651932907780">Allow sites to play sound (recommended)</translation> +<translation id="1670399744444387456">Basic</translation> +<translation id="1671236975893690980">Download pending...</translation> +<translation id="1672586136351118594">Don‘t show again</translation> +<translation id="1709438864123551175">Data Saver</translation> +<translation id="1718835860248848330">Last hour</translation> +<translation id="1729516292547892356">To view virtual reality content, update Google VR Services</translation> +<translation id="1733116627827457509"><ph name="FILE_SIZE" /> – Updated <ph name="TIME_SINCE_UPDATE" /></translation> +<translation id="1736419249208073774">Explore</translation> +<translation id="1743802530341753419">Ask before allowing sites to connect to a device (recommended)</translation> +<translation id="1749561566933687563">Sync your bookmarks</translation> +<translation id="17513872634828108">Open tabs</translation> +<translation id="1756600373018374892">Tap this button for quick access to your tabs.</translation> +<translation id="1779089405699405702">Image decoder</translation> +<translation id="1782483593938241562">End date <ph name="DATE" /></translation> +<translation id="1792959175193046959">Change the default download location at any time</translation> +<translation id="1807246157184219062">Light</translation> +<translation id="1821253160463689938">Uses cookies to remember your preferences, even if you don't visit those pages</translation> +<translation id="1829244130665387512">Find in page</translation> +<translation id="1832521218263067499">Security incidents</translation> +<translation id="1853692000353488670">New incognito tab</translation> +<translation id="1868024384445905608">Chrome now downloads files faster</translation> +<translation id="1878302395768190018">You can customise this at any time in Chrome Settings</translation> +<translation id="1880072593381090678">Popular pages from Chrome</translation> +<translation id="1883903952484604915">My files</translation> +<translation id="1887786770086287077">Location access is off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1891331835972267886"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="189172778771606813">Close navigation drawer</translation> +<translation id="1919345977826869612">Ads</translation> +<translation id="1919950603503897840">Select contacts</translation> +<translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/<ph name="FILE_SIZE_WITH_UNITS" /></translation> +<translation id="1933845786846280168">Selected Tab</translation> +<translation id="1938981467853765413">Provide feedback</translation> +<translation id="194341124344773587">Turn on permission for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1943432128510653496">Save passwords</translation> +<translation id="1944384637046898011">Encrypt all with Google password as of <ph name="TIME" /></translation> +<translation id="1946005195648379376">Control how Google uses your browsing history to personalise Search and other Google services.</translation> +<translation id="1952172573699511566">Websites will show text in your preferred language, when possible.</translation> +<translation id="195283394249132567">Personalised Google services</translation> +<translation id="1966710179511230534">Please update your sign-in details.</translation> +<translation id="1974060860693918893">Advanced</translation> +<translation id="1984937141057606926">Allowed, except third-party</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> button</translation> +<translation id="1989112275319619282">Browse</translation> +<translation id="1993768208584545658"><ph name="SITE" /> wants to pair</translation> +<translation id="1994173015038366702">Site URL</translation> +<translation id="2000419248597011803">Sends some cookies and searches from the address bar and search box to your default search engine</translation> +<translation id="2002537628803770967">Credit cards and addresses using Google Pay</translation> +<translation id="200815880754187296"><ph name="KILOBYTES" /> KB other apps</translation> +<translation id="2017836877785168846">Clears history and autocompletions in the address bar.</translation> +<translation id="2021896219286479412">Full screen site controls</translation> +<translation id="2038563949887743358">Turn on Request desktop site</translation> +<translation id="2045104531052923016"><ph name="GIGABYTES" /> GB other apps</translation> +<translation id="2063713494490388661">Tap to Search</translation> +<translation id="2079545284768500474">Undo</translation> +<translation id="2082238445998314030">Result <ph name="RESULT_NUMBER" /> of <ph name="TOTAL_RESULTS" /></translation> +<translation id="2086652334978798447">To get personalised content suggested by Google, sign in to Chrome.</translation> +<translation id="2091887806945687916">Sound</translation> +<translation id="2095887075102408547">When this feature is turned on, Chrome will use Google servers to compress pages that you visit before downloading them. Pages accessed using private connections (HTTPS) or in Incognito tabs will not be optimised or seen by Google.</translation> +<translation id="2096012225669085171">Sync and personalise across devices</translation> +<translation id="2100273922101894616">Auto Sign-in</translation> +<translation id="2111511281910874386">Go to page</translation> +<translation id="2120297377148151361">Activity and interactions</translation> +<translation id="2122601567107267586">Could not open app</translation> +<translation id="2126426811489709554">Powered by Chrome</translation> +<translation id="2131665479022868825"><ph name="DATA" /> saved</translation> +<translation id="213279576345780926">Closed <ph name="TAB_TITLE" /></translation> +<translation id="2139186145475833000">Add to Home screen</translation> +<translation id="2142289305367051020">Your favourite pages are here</translation> +<translation id="2146738493024040262">Open Instant App</translation> +<translation id="2148716181193084225">Today</translation> +<translation id="2154484045852737596">Edit card</translation> +<translation id="2154710561487035718">Copy URL</translation> +<translation id="2156074688469523661">Remaining sites (<ph name="NUMBER_OF_SITES" />)</translation> +<translation id="2206488550163399966"><ph name="APP_NAME" />, web app. <ph name="APP_URL" /></translation> +<translation id="2227444325776770048">Continue as <ph name="USER_FULL_NAME" /></translation> +<translation id="2232379019872353004">Sends some system information and page content to Google</translation> +<translation id="2234876718134438132">Sync and Google services</translation> +<translation id="2259659629660284697">Export passwords…</translation> +<translation id="2268044343513325586">Refine</translation> +<translation id="2280910239864711607">Open a new tab in private mode</translation> +<translation id="2286841657746966508">Billing address</translation> +<translation id="230115972905494466">No compatible devices found</translation> +<translation id="2315043854645842844">Client side certificate selection is not supported by the operating system.</translation> +<translation id="2321086116217818302">Preparing passwords…</translation> +<translation id="2321958826496381788">Drag the slider until you can read this comfortably. Text should look at least this big after double-tapping on a paragraph.</translation> +<translation id="2323763861024343754">Site storage</translation> +<translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised by you or your parents at any time. Google may use content on sites that you visit, as well as browsing activity and interactions, to personalise Chrome and Google services such as Translate, Search and ads.</translation> +<translation id="2328985652426384049">Can’t sign in</translation> +<translation id="2342981853652716282">Sign in to Chrome to get your bookmarks, passwords and more on all your devices.</translation> +<translation id="2343328333327081434">Installing…</translation> +<translation id="2346253980530904022">Google servers will optimise the pages that you visit, except for HTTPS and Incognito.</translation> +<translation id="2349710944427398404">Total data used by Chrome, including accounts, bookmarks and saved settings</translation> +<translation id="2351097562818989364">Your translate settings have been reset.</translation> +<translation id="2359808026110333948">Continue</translation> +<translation id="2369533728426058518">open tabs</translation> +<translation id="2387895666653383613">Text scaling</translation> +<translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> +<translation id="2410754283952462441">Choose an account</translation> +<translation id="2414672073755873541">No content here</translation> +<translation id="2414886740292270097">Dark</translation> +<translation id="2416359993254398973">Chrome needs permission to access your camera for this site.</translation> +<translation id="2426805022920575512">Choose another account</translation> +<translation id="2433507940547922241">Appearance</translation> +<translation id="2434158240863470628">Download complete <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2436117022029368436">Communicates with Google to improve browsing and Chrome</translation> +<translation id="2440823041667407902">Location access</translation> +<translation id="2450083983707403292">Do you want to start downloading <ph name="FILE_NAME" /> again?</translation> +<translation id="2476578072172137802">Site Settings</translation> +<translation id="2482878487686419369">Notifications</translation> +<translation id="2496180316473517155">Browsing history</translation> +<translation id="2498359688066513246">Help & feedback</translation> +<translation id="2501278716633472235">Go back</translation> +<translation id="2513403576141822879">For more settings that relate to privacy, security and data collection, see <ph name="BEGIN_LINK" />Sync and Google services<ph name="END_LINK" /></translation> +<translation id="2523184218357549926">Sends URLs of pages that you visit to Google</translation> +<translation id="2526148617758225454">Data Saver is on. Manage it in Settings.</translation> +<translation id="2532336938189706096">Web View</translation> +<translation id="2536728043171574184">Viewing an offline copy of this page</translation> +<translation id="2546283357679194313">Cookies and site data</translation> +<translation id="2567385386134582609">IMAGE</translation> +<translation id="2570922361219980984">Location access is also off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="257931822824936280">Expanded – click to collapse.</translation> +<translation id="2581165646603367611">This will clear cookies, cache and other data of sites Chrome doesn't think is important.</translation> +<translation id="2586657967955657006">Clipboard</translation> +<translation id="2587052924345400782">Newer version is available</translation> +<translation id="2593272815202181319">Monospace</translation> +<translation id="2612676031748830579">Card number</translation> +<translation id="2621115761605608342">Allow JavaScript for a specific site.</translation> +<translation id="2625189173221582860">Password copied</translation> +<translation id="2631006050119455616">Saved</translation> +<translation id="2633278372998075009">Private tabs</translation> +<translation id="2647434099613338025">Add language</translation> +<translation id="2650751991977523696">Download file again?</translation> +<translation id="2653659639078652383">Submit</translation> +<translation id="2677748264148917807">Leave</translation> +<translation id="2704606927547763573">Copied</translation> +<translation id="2707726405694321444">Refresh page</translation> +<translation id="2709516037105925701">Auto-fill</translation> +<translation id="271033894570825754">New</translation> +<translation id="2728754400939377704">Sort by site</translation> +<translation id="2744248271121720757">Tap a word to search instantly or see related actions</translation> +<translation id="2762000892062317888">just now</translation> +<translation id="2777555524387840389"><ph name="SECONDS" /> secs left</translation> +<translation id="2781151931089541271">1 sec left</translation> +<translation id="2803478378562657435">Showing saved passwords and password options</translation> +<translation id="2810645512293415242">Simplified page to save data and load faster.</translation> +<translation id="281504910091592009">View and manage saved passwords in your <ph name="BEGIN_LINK" />Google account<ph name="END_LINK" /></translation> +<translation id="2818669890320396765">To get your bookmarks on all your devices, sign in and turn on sync</translation> +<translation id="2836148919159985482">Touch the back button to exit full screen.</translation> +<translation id="2842985007712546952">Parent folder</translation> +<translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Previous track</translation> +<translation id="2876764156902388290">Chrome is using less data to show you this page</translation> +<translation id="2888126860611144412">About Chrome</translation> +<translation id="2891154217021530873">Stop page loading</translation> +<translation id="2900528713135656174">Create event</translation> +<translation id="2902702728133930130">Chrome failed during start-up with an unexpected error.</translation> +<translation id="290376772003165898">Page is not in <ph name="LANGUAGE" />?</translation> +<translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> +<translation id="2913331724188855103">Allow sites to save and read cookie data (recommended)</translation> +<translation id="2932150158123903946">Google <ph name="APP_NAME" /> storage</translation> +<translation id="2943166482989655199">Improve Chrome and its security by sending system and usage data to Google</translation> +<translation id="2956410042958133412">This account is managed by <ph name="PARENT_NAME_1" /> and <ph name="PARENT_NAME_2" />.</translation> +<translation id="2960796085439532066">Copyright <ph name="YEAR" /> Google Inc. All rights reserved.</translation> +<translation id="2962095958535813455">Switched to incognito tabs</translation> +<translation id="2968755619301702150">Certificate viewer</translation> +<translation id="2979025552038692506">Selected Incognito Tab</translation> +<translation id="2989523299700148168">Recently Visited</translation> +<translation id="2996291259634659425">Create passphrase</translation> +<translation id="2996809686854298943">URL required</translation> +<translation id="300526633675317032">This will clear all <ph name="SIZE_IN_KB" /> of website storage.</translation> +<translation id="3029613699374795922">Downloaded <ph name="KBS" /> KB</translation> +<translation id="3029704984691124060">Passphrases do not match</translation> +<translation id="3036750288708366620"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /></translation> +<translation id="3045654778214005718">See more like this from Google</translation> +<translation id="305593374596241526">Location is off; turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="307908932405420782">More articles will appear soon. Enjoy your morning!</translation> +<translation id="3089395242580810162">Open in incognito tab</translation> +<translation id="311456632243022227">Multiple links opened in Chrome</translation> +<translation id="3115898365077584848">Show info</translation> +<translation id="3137521801621304719">Leave incognito mode</translation> +<translation id="3148434565183091099">To get your bookmarks on all your devices, sign in to Chrome.</translation> +<translation id="3157842584138209013">See how much data you've saved from the More Options button</translation> +<translation id="3166827708714933426">Tab and window shortcuts</translation> +<translation id="3190152372525844641">Turn on permissions for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> stored data</translation> +<translation id="3207960819495026254">Bookmarked</translation> +<translation id="321773570071367578">If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="3227137524299004712">Microphone</translation> +<translation id="3232754137068452469">Web App</translation> +<translation id="3234355010754616171">New private tab</translation> +<translation id="3236059992281584593">1 min left</translation> +<translation id="3244271242291266297">MM</translation> +<translation id="3254409185687681395">Bookmark this page</translation> +<translation id="3259831549858767975">Make everything on the page smaller</translation> +<translation id="3269093882174072735">Load image</translation> +<translation id="3269956123044984603">To get your tabs from your other devices, turn on “Auto-sync data” in Android account settings.</translation> +<translation id="3282568296779691940">Sign in to Chrome</translation> +<translation id="32895400574683172">Notifications are allowed</translation> +<translation id="3295602654194328831">Hide info</translation> +<translation id="3298243779924642547">Lite</translation> +<translation id="3303414029551471755">Proceed to download the content?</translation> +<translation id="3328801116991980348">Site information</translation> +<translation id="3341058695485821946">See how much data you've saved</translation> +<translation id="3350687908700087792">Close all incognito tabs</translation> +<translation id="3365671512111106261">Unavailable when Data Saver is turned on</translation> +<translation id="3367813778245106622">Sign in again to start sync</translation> +<translation id="3377025655491224618">Private tab</translation> +<translation id="3384347053049321195">Share image</translation> +<translation id="3386292677130313581">Ask before allowing sites to know your location (recommended)</translation> +<translation id="3387650086002190359"><ph name="FILE_NAME" /> download failed due to file system errors.</translation> +<translation id="339329030417445648">This site tends to show intrusive ads</translation> +<translation id="3398320232533725830">Open the bookmarks manager</translation> +<translation id="3414952576877147120">Size:</translation> +<translation id="3443221991560634068">Reload the current page</translation> +<translation id="3452612588551937789">Sign in with your Google Account to get your bookmarks, history, passwords and other settings on all your devices.</translation> +<translation id="3485359633434254965">{FILES,plural, =1{%1$d file downloaded}other{%1$d files downloaded}}</translation> +<translation id="3492207499832628349">New incognito tab</translation> +<translation id="3493531032208478708"><ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /> about suggested content</translation> +<translation id="3518985090088779359">Accept & continue</translation> +<translation id="3522247891732774234">Update available. More options</translation> +<translation id="3527085408025491307">Folder</translation> +<translation id="3542235761944717775"><ph name="KILOBYTES" /> KB available</translation> +<translation id="3549644494707163724">Encrypt all synced data with your own sync passphrase</translation> +<translation id="3549657413697417275">Search your history</translation> +<translation id="3552151358455404883">Manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="3557336313807607643">Add to contacts</translation> +<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="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="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="3600792891314830896">Mute sites that play sound</translation> +<translation id="360207483134687714">Help improve the VR experience in Chrome</translation> +<translation id="3616113530831147358">Audio</translation> +<translation id="3620176948598597475">Resetting erases Data Saver history, including the list of visited sites.</translation> +<translation id="3630011985153972676">Allow Chrome to download articles for you when on Wi-Fi under settings.</translation> +<translation id="3632295766818638029">Unmask password</translation> +<translation id="363596933471559332">Automatically sign in to websites using stored credentials. When the feature is off, you’ll be asked for verification every time before signing in to a website.</translation> +<translation id="3661699943263275414">Third-party websites can save and read cookie data</translation> +<translation id="3662546969139119822">No history here</translation> +<translation id="3672452749423051839">Navigation error suggestions</translation> +<translation id="3692944402865947621"><ph name="FILE_NAME" /> download failed because storage location is not reachable.</translation> +<translation id="3712575778697986964">Reset Data Saver?</translation> +<translation id="3714981814255182093">Open the Find Bar</translation> +<translation id="3716182511346448902">This page uses too much memory, so Chrome paused it.</translation> +<translation id="3739899004075612870">Bookmarked in <ph name="PRODUCT_NAME" /></translation> +<translation id="3744111309925758534"><ph name="MEGABYTES" /> MB other apps</translation> +<translation id="3744111561329211289">Background sync</translation> +<translation id="3773755127849930740"><ph name="BEGIN_LINK" />Turn on Bluetooth<ph name="END_LINK" /> to allow pairing</translation> +<translation id="3778956594442850293">Added to Home screen</translation> +<translation id="3781011235031427080">More like this opened at half height</translation> +<translation id="3789841737615482174">Install</translation> +<translation id="3810838688059735925">Video</translation> +<translation id="3810973564298564668">Manage</translation> +<translation id="3819178904835489326"><ph name="NUMBER_OF_DOWNLOADS" /> downloads deleted</translation> +<translation id="3819562311292413223">Download articles for you</translation> +<translation id="3822502789641063741">Clear site storage?</translation> +<translation id="385051799172605136">Back</translation> +<translation id="3859306556332390985">Seek forward</translation> +<translation id="3868004864571585162">Cookies, media licences and site data</translation> +<translation id="3894427358181296146">Add folder</translation> +<translation id="3895926599014793903">Force enable zoom</translation> +<translation id="3927692899758076493">Sans Serif</translation> +<translation id="3928666092801078803">Combine my data</translation> +<translation id="393697183122708255">No enabled voice search available</translation> +<translation id="3950820424414687140">Sign in</translation> +<translation id="395206256282351086">Search and site suggestions disabled</translation> +<translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> +<translation id="3967822245660637423">Download complete</translation> +<translation id="397583555483684758">Sync has stopped working</translation> +<translation id="3976396876660209797">Remove and recreate this shortcut</translation> +<translation id="3985215325736559418">Do you want to download <ph name="FILE_NAME" /> again?</translation> +<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="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> +<translation id="3997476611815694295">Unimportant storage</translation> +<translation id="4002066346123236978">Title</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# hr}other{# hrs}}</translation> +<translation id="4042870126885713738">Show suggestions when a web address does not resolve or a connection cannot be made</translation> +<translation id="4046123991198612571">Next track</translation> +<translation id="4048707525896921369">Learn about topics on websites without leaving the page. Tap to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results and other details. + +To adjust your search term, long press to select. To refine your search, slide the panel all the way up and tap the search box.</translation> +<translation id="4056223980640387499">Sepia</translation> +<translation id="4060598801229743805">Options available near the top of the screen</translation> +<translation id="4062305924942672200">Legal information</translation> +<translation id="4084682180776658562">Bookmark</translation> +<translation id="4084712963632273211">From <ph name="PUBLISHER_ORIGIN" /> – <ph name="BEGIN_DEEMPHASIZED" />delivered by Google<ph name="END_DEEMPHASIZED" /></translation> +<translation id="4084836577264234537"><ph name="MEGABYTES" /> MB downloaded</translation> +<translation id="4089831646916293264">This feature may interfere with access to premium data services provided by your operator.</translation> +<translation id="4095146165863963773">Delete app data?</translation> +<translation id="4097739989936358050">This app is running in Chrome.</translation> +<translation id="4099578267706723511">Help make Chrome better by sending usage statistics and crash reports to Google.</translation> +<translation id="410351446219883937">Autoplay</translation> +<translation id="4113030288477039509">Managed by your administrator</translation> +<translation id="4116038641877404294">Download pages to use them offline</translation> +<translation id="4127069705158143605">{BOOKMARKS_COUNT,plural, =1{%1$d bookmark}other{%1$d bookmarks}}</translation> +<translation id="4149994727733219643">Simplified view for web pages</translation> +<translation id="4159800535322890630">Block sites from accessing your sensors</translation> +<translation id="4165986682804962316">Site settings</translation> +<translation id="4170011742729630528">The service is not available; try again later.</translation> +<translation id="4179980317383591987"><ph name="AMOUNT" /> used</translation> +<translation id="4181841719683918333">Languages</translation> +<translation id="4192273449750167573">Review your settings on the next screen</translation> +<translation id="4195643157523330669">Open in new tab</translation> +<translation id="4198423547019359126">No available download locations</translation> +<translation id="4209895695669353772">To get personalised content suggested by Google, turn on sync</translation> +<translation id="4226663524361240545">Notifications may vibrate the device</translation> +<translation id="4242533952199664413">Open settings</translation> +<translation id="4243710787042215766">Open in private tab</translation> +<translation id="424864128008805179">Sign out of Chrome?</translation> +<translation id="4256782883801055595">Open-source licences</translation> +<translation id="4259722352634471385">Navigation is blocked: <ph name="URL" /></translation> +<translation id="4262028915562328938">Sync error occurred, tap to get details.</translation> +<translation id="4269820728363426813">Copy link address</translation> +<translation id="4275663329226226506">Media</translation> +<translation id="4278390842282768270">Allowed</translation> +<translation id="4307992518367153382">Basics</translation> +<translation id="4351244548802238354">Close dialogue</translation> +<translation id="4378154925671717803">Phone</translation> +<translation id="4384468725000734951">Using Sogou for search</translation> +<translation id="4398088515904522762">To use this feature, turn on <ph name="BEGIN_LINK" />Activity and interactions<ph name="END_LINK" />.</translation> +<translation id="4404568932422911380">No bookmarks</translation> +<translation id="4409723563706114196">Use page predictions</translation> +<translation id="4412992751769744546">Allow third-party cookies</translation> +<translation id="4419556793104466535">Control sync, personalisation and more</translation> +<translation id="4432792777822557199">Pages in <ph name="SOURCE_LANGUAGE" /> will be translated to <ph name="TARGET_LANGUAGE" /> from now on</translation> +<translation id="4434045419905280838">Pop-ups and redirects</translation> +<translation id="4452411734226507615">Close <ph name="TAB_TITLE" /> tab</translation> +<translation id="4452548195519783679">Bookmarked to <ph name="FOLDER_NAME" /></translation> +<translation id="4453340223357552416"><ph name="FILE_NAME" /> downloaded in <ph name="PRODUCT_NAME" /></translation> +<translation id="4468959413250150279">Mute sound for a specific site.</translation> +<translation id="4472118726404937099">To sync and personalise across devices, sign in and turn on sync</translation> +<translation id="447252321002412580">Help improve Chrome's features and performance</translation> +<translation id="4479647676395637221">Ask first before allowing sites to use your camera (recommended)</translation> +<translation id="4487967297491345095">All Chrome’s app data will be deleted permanently. This includes all files, settings, accounts, databases, etc.</translation> +<translation id="4508440807153586353">Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting you'll need to reset sync. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation> +<translation id="4513387527876475750">{DAYS,plural, =1{# day ago}other{# days ago}}</translation> +<translation id="451872707440238414">Search your bookmarks</translation> +<translation id="4521489764227272523">The selected data has been removed from Chrome and your synced devices. + +Your Google Account may have other forms of browsing history such as searches and activity from other Google services at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="4532845899244822526">Choose folder</translation> +<translation id="4550003330909367850">To view or copy your password here, set screen lock on this device.</translation> +<translation id="4558311620361989323">Web page shortcuts</translation> +<translation id="4561979708150884304">No connection</translation> +<translation id="4565377596337484307">Hide password</translation> +<translation id="4570913071927164677">Details</translation> +<translation id="4572422548854449519">Sign in to managed account</translation> +<translation id="4581964774250883625">You’ve gone incognito.</translation> +<translation id="4583164079174244168">{MINUTES,plural, =1{# minute ago}other{# minutes ago}}</translation> +<translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">This offline page is from <ph name="CREATION_TIME" /> and may differ from the online version.</translation> +<translation id="4605958867780575332">Item removed: <ph name="ITEM_TITLE" /></translation> +<translation id="4616150815774728855">Open <ph name="WEBAPK_NAME" /></translation> +<translation id="4634124774493850572">Use password</translation> +<translation id="4645575059429386691">Managed by your parent</translation> +<translation id="4660011489602794167">Show keyboard</translation> +<translation id="4663756553811254707"><ph name="NUMBER_OF_BOOKMARKS" /> bookmarks deleted</translation> +<translation id="4665282149850138822"><ph name="NAME" /> was added to your Home screen</translation> +<translation id="4684427112815847243">Sync everything</translation> +<translation id="4695891336199304370">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}other{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}}</translation> +<translation id="4698034686595694889">View offline in <ph name="APP_NAME" /></translation> +<translation id="4698413471314543145">Critical functionality required to run Chrome is missing; either your Chrome installation is incomplete or not compatible with this version of Android.</translation> +<translation id="4699172675775169585">Cached images and files</translation> +<translation id="4714588616299687897">Save up to 60% of your data</translation> +<translation id="4719927025381752090">Offer to translate</translation> +<translation id="4720023427747327413">Open in <ph name="PRODUCT_NAME" /></translation> +<translation id="4720982865791209136">Help improve Chrome. <ph name="BEGIN_LINK" />Take survey<ph name="END_LINK" /></translation> +<translation id="4730876730346568982">You are switching sync accounts from <ph name="ACCOUNT_EMAIL_OLD" /> to <ph name="ACCOUNT_EMAIL_NEW" />. Your existing Chrome data is managed by <ph name="MANAGED_DOMAIN" />. This will delete your data from this device, but your data will remain in <ph name="ACCOUNT_EMAIL_OLD" />.</translation> +<translation id="473775607612524610">Update</translation> +<translation id="4738836084190194332">Last synced: <ph name="WHEN" /></translation> +<translation id="4749960740855309258">Open a new tab</translation> +<translation id="4751476147751820511">Motion or light sensors</translation> +<translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download complete.}other{# downloads complete.}}</translation> +<translation id="4766369052440583386">Data Saver is on</translation> +<translation id="4797039098279997504">Touch to return to <ph name="URL_OF_THE_CURRENT_TAB" /></translation> +<translation id="4807098396393229769">Name on card</translation> +<translation id="4807963036345170158">Data Saver is off</translation> +<translation id="4816465935029283692">Data types</translation> +<translation id="4837753911714442426">Open options to print page</translation> +<translation id="4842092870884894799">Showing password generation pop-up</translation> +<translation id="4850886885716139402">View</translation> +<translation id="4860895144060829044">Call</translation> +<translation id="4874967477260347223">Media Licenses</translation> +<translation id="4875775213178255010">Content Suggestions</translation> +<translation id="4878404682131129617">Establishing a tunnel via proxy server failed</translation> +<translation id="4881695831933465202">Open</translation> +<translation id="488187801263602086">Rename file</translation> +<translation id="4882831918239250449">Control how your browsing history is used to personalise Search, ads and more</translation> +<translation id="4883379392681899581">Leave private mode</translation> +<translation id="4885273946141277891">Unsupported number of Chrome instances.</translation> +<translation id="4910889077668685004">Payment apps</translation> +<translation id="4913161338056004800">Reset statistics</translation> +<translation id="4913169188695071480">Stop refreshing</translation> +<translation id="4915549754973153784"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /> while scanning for devices…</translation> +<translation id="4943872375798546930">No results</translation> +<translation id="4956460920135325549">Lite page delivered by Google.</translation> +<translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> is sharing your screen</translation> +<translation id="4961334780091921942">Your passwords, history & more on all devices</translation> +<translation id="4961700429721424617">You are signing out of an account managed by <ph name="MANAGED_DOMAIN" />. This will delete your Chrome data from this device, but your data will remain in your Google account.</translation> +<translation id="497421865427891073">go forward</translation> +<translation id="4988210275050210843">Downloading file (<ph name="MEGABYTES" />).</translation> +<translation id="4988526792673242964">Pages</translation> +<translation id="4996978546172906250">Share via</translation> +<translation id="5004339818306944878">Use up to 60% less data and speed up the web. Google servers will optimise the pages you visit.</translation> +<translation id="5004416275253351869">Google activity controls</translation> +<translation id="5005498671520578047">Copy password</translation> +<translation id="5011311129201317034"><ph name="SITE" /> wants to connect</translation> +<translation id="5013696553129441713">No new suggestions</translation> +<translation id="5016205925109358554">Serif</translation> +<translation id="5039804452771397117">Allow</translation> +<translation id="5040262127954254034">Privacy</translation> +<translation id="5063480226653192405">Usage</translation> +<translation id="5087580092889165836">Add card</translation> +<translation id="5100237604440890931">Collapsed – click to expand.</translation> +<translation id="510275257476243843">1 hour left</translation> +<translation id="5123685120097942451">Incognito tab</translation> +<translation id="5127805178023152808">Sync is off</translation> +<translation id="5129038482087801250">Install web app</translation> +<translation id="5139940364318403933">Learn how to use Google Drive</translation> +<translation id="515227803646670480">Clear stored data</translation> +<translation id="5152843274749979095">No supported apps installed</translation> +<translation id="5161254044473106830">Title required</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download failed.}other{# downloads failed.}}</translation> +<translation id="5168917394043976756">Open navigation drawer</translation> +<translation id="5171365962177408781">Tap to load the new tab page and view suggested articles</translation> +<translation id="5184329579814168207">Open in Chrome</translation> +<translation id="5199929503336119739">Work profile</translation> +<translation id="5210286577605176222">Jump to the previous tab</translation> +<translation id="5210365745912300556">Close tab</translation> +<translation id="5222676887888702881">Sign out</translation> +<translation id="5224771365102442243">With video</translation> +<translation id="5233638681132016545">New tab</translation> +<translation id="5240817131241497236">The settings that control sync, personalisation and other Google services in Chrome have changed. This may affect your current settings.</translation> +<translation id="5264003212305142034"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised at any time. Google may use content on sites that you visit, plus browser activity and interactions, to personalise Chrome and other Google services such as Translate, Search and ads.</translation> +<translation id="5271967389191913893">Device cannot open the content to be downloaded.</translation> +<translation id="528192093759286357">Drag from top and touch the back button to exit full screen.</translation> +<translation id="5284584623296338184">Changes to your bookmarks, history, passwords and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google account.</translation> +<translation id="5300589172476337783">Show</translation> +<translation id="5301954838959518834">OK, got it</translation> +<translation id="5304593522240415983">This field cannot be blank</translation> +<translation id="5308380583665731573">Connect</translation> +<translation id="5308603654685598744">When this feature is turned on, Chrome will offer to translate pages written in other languages using Google Translate.</translation> +<translation id="5313967007315987356">Add site</translation> +<translation id="5317780077021120954">Save</translation> +<translation id="5324858694974489420">Parental Settings</translation> +<translation id="5327248766486351172">Name</translation> +<translation id="5335288049665977812">Allow sites to run JavaScript (recommended)</translation> +<translation id="5345040418939504969">Deleted <ph name="BOOKMARK_TITLE" /></translation> +<translation id="5372829067651257087">URL copied.</translation> +<translation id="5391532827096253100">Your connection to this site is not secure. Site information</translation> +<translation id="5400569084694353794">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="5403644198645076998">Only allow certain sites</translation> +<translation id="5414836363063783498">Verifying…</translation> +<translation id="5423934151118863508">Your most visited pages will appear here</translation> +<translation id="5424588387303617268"><ph name="GIGABYTES" /> GB available</translation> +<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="5447765697759493033">This site will not be translated</translation> +<translation id="545042621069398927">Speeding up your download.</translation> +<translation id="5456381639095306749">Download page</translation> +<translation id="5466407412363861127">This feature uses <ph name="BEGIN_LINK" />sync<ph name="END_LINK" />.</translation> +<translation id="548278423535722844">Open in maps app</translation> +<translation id="5487521232677179737">Clear data</translation> +<translation id="5487729733663684359">Chrome updates are no longer supported for this version of Android.</translation> +<translation id="5494920125229734069">Select all</translation> +<translation id="550684401320795253">Updating Chrome...</translation> +<translation id="5512137114520586844">This account is managed by <ph name="PARENT_NAME" />.</translation> +<translation id="5514904542973294328">Disabled by the administrator of this device</translation> +<translation id="5515439363601853141">Unlock to view your password</translation> +<translation id="5515716148775388141">Your icons have moved to the bottom of the screen</translation> +<translation id="5517095782334947753">You have bookmarks, history, passwords and other settings from <ph name="FROM_ACCOUNT" />.</translation> +<translation id="5524843473235508879">Redirect blocked.</translation> +<translation id="5527082711130173040">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK1" />Update permissions<ph name="END_LINK1" />. Location access is also <ph name="BEGIN_LINK2" />turned off for this device<ph name="END_LINK2" />.</translation> +<translation id="5527111080432883924">Ask before allowing sites to read text and images from the clipboard (recommended)</translation> +<translation id="5530766185686772672">Close incognito tabs</translation> +<translation id="5534640966246046842">Site copied</translation> +<translation id="5537099431952529648">You and your parents can manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="5556459405103347317">Reload</translation> +<translation id="5561549206367097665">Waiting for network…</translation> +<translation id="557283862590186398">Chrome needs permission to access your microphone for this site.</translation> +<translation id="55737423895878184">Location and notifications are allowed</translation> +<translation id="5578795271662203820">Search <ph name="SEARCH_ENGINE" /> for this image</translation> +<translation id="5595485650161345191">Edit address</translation> +<translation id="5596627076506792578">More options</translation> +<translation id="5620299005957670886">Allow sites to access your sensors (recommended)</translation> +<translation id="5620928963363755975">Find your files and pages in Downloads from the More Options button</translation> +<translation id="5626134646977739690">Name:</translation> +<translation id="5639724618331995626">Allow all sites</translation> +<translation id="5648166631817621825">Last 7 days</translation> +<translation id="5655963694829536461">Search your downloads</translation> +<translation id="5659593005791499971">Email</translation> +<translation id="5665379678064389456">Create event in <ph name="APP_NAME" /></translation> +<translation id="5668404140385795438">Override a website’s request to prevent zooming in</translation> +<translation id="5676636989614905379">Cannot play video on <ph name="SCREEN_NAME" />.</translation> +<translation id="5677928146339483299">Blocked</translation> +<translation id="5684874026226664614">Oops. This page could not be translated.</translation> +<translation id="5686790454216892815">File name too long</translation> +<translation id="5689516760719285838">Location</translation> +<translation id="5719837394786370183">Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your incognito tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your Internet service provider or the websites you visit.</translation> +<translation id="572328651809341494">Recent tabs</translation> +<translation id="5726692708398506830">Make everything on the page bigger</translation> +<translation id="5738816946784116349">Chrome Downloads</translation> +<translation id="5748802427693696783">Switched to standard tabs</translation> +<translation id="5749068826913805084">Chrome needs storage access to download files.</translation> +<translation id="5763382633136178763">Incognito tabs</translation> +<translation id="5763514718066511291">Tap to copy the URL for this app</translation> +<translation id="5765780083710877561">Description:</translation> +<translation id="5777170031995031090">Control how Google uses your browsing history to personalise Search, ads and other Google services.</translation> +<translation id="5793665092639000975">Using <ph name="SPACE_USED" /> of <ph name="SPACE_AVAILABLE" /></translation> +<translation id="5804241973901381774">Permissions</translation> +<translation id="5809361687334836369">{HOURS,plural, =1{# hour ago}other{# hours ago}}</translation> +<translation id="5817918615728894473">Pair</translation> +<translation id="583281660410589416">Unknown</translation> +<translation id="5833397272224757657">Uses content on sites that you visit, plus browser activity and interactions, for personalisation</translation> +<translation id="5833984609253377421">Share link</translation> +<translation id="584427517463557805">Selected private tab</translation> +<translation id="5854790677617711513">Older than 30 days</translation> +<translation id="5858741533101922242">Chrome is unable to turn on Bluetooth adaptor</translation> +<translation id="5860033963881614850">Off</translation> +<translation id="5862731021271217234">To get your tabs from your other devices, turn on sync</translation> +<translation id="5864174910718532887">Details: Sorted by site name</translation> +<translation id="5864419784173784555">Waiting for another download…</translation> +<translation id="5865733239029070421">Automatically sends usage statistics and crash reports to Google</translation> +<translation id="5869522115854928033">Saved passwords</translation> +<translation id="5878455346526065919">Block ads from sites that tend to show intrusive ads</translation> +<translation id="5902828464777634901">All local data stored by this website, including cookies, will be deleted.</translation> +<translation id="5911030830365207728">Google Translate</translation> +<translation id="5916664084637901428">On</translation> +<translation id="5919204609460789179">Update <ph name="PRODUCT_NAME" /> to start sync</translation> +<translation id="5937580074298050696"><ph name="AMOUNT" /> saved</translation> +<translation id="5939518447894949180">Reset</translation> +<translation id="5942872142862698679">Using Google for search</translation> +<translation id="5952764234151283551">Sends the URL of a page that you're trying to reach to Google</translation> +<translation id="5956665950594638604">Open the Chrome Help Centre in a new tab</translation> +<translation id="5958275228015807058">Find your files and pages in Downloads</translation> +<translation id="5962718611393537961">Tap to collapse</translation> +<translation id="5990142338020175451">More personal Google services, such as better page suggestions</translation> +<translation id="6000066717592683814">Keep Google</translation> +<translation id="6005538289190791541">Suggested password</translation> +<translation id="6039379616847168523">Jump to the next tab</translation> +<translation id="6040143037577758943">Close</translation> +<translation id="6042308850641462728">More</translation> +<translation id="604996488070107836"><ph name="FILE_NAME" /> download failed due to an unknown error.</translation> +<translation id="605721222689873409">YY</translation> +<translation id="6075798973483050474">Edit home page</translation> +<translation id="60923314841986378"><ph name="HOURS" /> hours left</translation> +<translation id="60924377787140961">More articles will appear soon. Enjoy your afternoon!</translation> +<translation id="6099151465289169210">Switched to private tabs</translation> +<translation id="6108923351542677676">Setup in progress…</translation> +<translation id="6111020039983847643">data used</translation> +<translation id="6112702117600201073">Refreshing page</translation> +<translation id="6127379762771434464">Item removed</translation> +<translation id="6140912465461743537">Country/Region</translation> +<translation id="6154478581116148741">Turn on screen lock in Settings to export your passwords from this device</translation> +<translation id="6159335304067198720"><ph name="PERCENT" /> data savings</translation> +<translation id="6165508094623778733">Learn more</translation> +<translation id="6177111841848151710">Blocked for current search engine</translation> +<translation id="6177390657002841081">Turn on Data Saver</translation> +<translation id="6181444274883918285">Add site exception</translation> +<translation id="618993374665929060">More like this opened at full height</translation> +<translation id="6192333916571137726">Download File</translation> +<translation id="6192792657125177640">Exceptions</translation> +<translation id="6206551242102657620">Connection is secure. Site information</translation> +<translation id="6210748933810148297">Not <ph name="EMAIL" />?</translation> +<translation id="6216432067784365534"><ph name="NAME_OF_LIST_ITEM" /> Options</translation> +<translation id="6221633008163990886">Unlock to export your passwords</translation> +<translation id="6232535412751077445">Enabling “Do Not Track” means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request and how the request is interpreted. + +For example, some websites may respond to this request by showing you ads that aren’t based on other websites that you’ve visited. Many websites will still collect and use your browsing data – for example to improve security, to provide content, ads and recommendations and to generate reporting statistics.</translation> +<translation id="6255999984061454636">Content suggestions</translation> +<translation id="6277522088822131679">There was a problem printing the page. Please try again.</translation> +<translation id="6295158916970320988">All sites</translation> +<translation id="629730747756840877">Account</translation> +<translation id="6303969859164067831">Sign out and turn off sync</translation> +<translation id="6320088164292336938">Vibrate</translation> +<translation id="6324034347079777476">Android system sync disabled</translation> +<translation id="6333140779060797560">Share via <ph name="APPLICATION" /></translation> +<translation id="6336451774241870485">New private tab</translation> +<translation id="6337234675334993532">Encryption</translation> +<translation id="6341580099087024258">Ask where to save files</translation> +<translation id="6343192674172527289">No downloads found</translation> +<translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}}</translation> +<translation id="6364438453358674297">Remove suggestion from history?</translation> +<translation id="6378173571450987352">Details: Sorted by amount of data used</translation> +<translation id="6383961787135158834">Clear Site Storage…</translation> +<translation id="6388207532828177975">Clear & reset</translation> +<translation id="6393863479814692971">Chrome needs permission to access your camera and microphone for this site.</translation> +<translation id="6395288395575013217">LINK</translation> +<translation id="6404511346730675251">Edit bookmark</translation> +<translation id="6406506848690869874">Sync</translation> +<translation id="641643625718530986">Print…</translation> +<translation id="6416782512398055893">Downloaded <ph name="MBS" /> MB</translation> +<translation id="6433501201775827830">Choose your search engine</translation> +<translation id="6437478888915024427">Page info</translation> +<translation id="6447842834002726250">Cookies</translation> +<translation id="6448273550210938826">Search and URL suggestions</translation> +<translation id="6461962085415701688">Can’t open file</translation> +<translation id="6475951671322991020">Download video</translation> +<translation id="6482749332252372425"><ph name="FILE_NAME" /> download failed due to lack of storage space.</translation> +<translation id="6496823230996795692">To use <ph name="APP_NAME" /> for the first time, please connect to the Internet.</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6534565668554028783">Google took too long to respond</translation> +<translation id="6538442820324228105">Downloaded <ph name="GBS" /> GB</translation> +<translation id="654446541061731451">Select a tab to beam</translation> +<translation id="6545017243486555795">Clear All Data</translation> +<translation id="6556716549745717622">Block if site tends to show intrusive ads (recommended)</translation> +<translation id="6560414384669816528">Search with Sogou</translation> +<translation id="6566259936974865419">Chrome has saved you <ph name="GIGABYTES" /> GB</translation> +<translation id="6573096386450695060">Always allow</translation> +<translation id="6573431926118603307">Tabs that you've opened in Chrome on your other devices will appear here.</translation> +<translation id="6575643671698722332">Reset failed. Ensure that your device is online and try again.</translation> +<translation id="6583199322650523874">Bookmark the current page</translation> +<translation id="6584721918629302382">AR</translation> +<translation id="6593061639179217415">Desktop site</translation> +<translation id="6600954340915313787">Copied to Chrome</translation> +<translation id="6608650720463149374"><ph name="GIGABYTES" /> GB</translation> +<translation id="6610147964972079463">Close private tabs</translation> +<translation id="6612358246767739896">Protected content</translation> +<translation id="6627583120233659107">Edit folder</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6643649862576733715">Sort by amount of data saved</translation> +<translation id="6648977384226967773">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}other{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}}</translation> +<translation id="6656545060687952787">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK" />Update permissions<ph name="END_LINK" /></translation> +<translation id="6657585470893396449">Password</translation> +<translation id="6659594942844771486">Tab</translation> +<translation id="666268767214822976">Use a prediction service to show related queries and popular websites as you type in the address bar</translation> +<translation id="666731172850799929">Open in <ph name="APP_NAME" /></translation> +<translation id="666981079809192359">Chrome Privacy Notice</translation> +<translation id="6697492270171225480">Show suggestions for similar pages when a page can't be found</translation> +<translation id="6697947395630195233">Chrome needs access to your location to share your location with this site.</translation> +<translation id="6698801883190606802">Manage synced data</translation> +<translation id="6710213216561001401">Previous</translation> +<translation id="6712388303105732168">See more like this from Google using the More Like This button</translation> +<translation id="6738867403308150051">Downloading…</translation> +<translation id="6746124502594467657">Move down</translation> +<translation id="6762156594045689028">To change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="6766622839693428701">Swipe down to close.</translation> +<translation id="6770414673596662518">Chrome’s Safe Browsing system will also be used to detect malicious pages and protect you from phishing, malware and harmful downloads.</translation> +<translation id="6776813977906306442">Download videos to watch later using the Download button</translation> +<translation id="6790428901817661496">Play</translation> +<translation id="679325081238418596">Get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="6820607729870073286">You have no saved website settings.</translation> +<translation id="6820686453637990663">CVC</translation> +<translation id="6831043979455480757">Translate</translation> +<translation id="6846298663435243399">Loading…</translation> +<translation id="685040365210406336">Make no changes</translation> +<translation id="6850409657436465440">Your download is still in progress</translation> +<translation id="6850830437481525139"><ph name="TAB_COUNT" /> tabs closed</translation> +<translation id="6864459304226931083">Download image</translation> +<translation id="6865313869410766144">Autofill form data</translation> +<translation id="6868088497967843822">Sign in to get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="688738109438487280">Add existing data to <ph name="TO_ACCOUNT" />.</translation> +<translation id="6891726759199484455">Unlock to copy your password</translation> +<translation id="6891858906296486776">{OPEN_TABS,plural, =1{%1$d open tab}other{%1$d open tabs}}</translation> +<translation id="6896758677409633944">Copy</translation> +<translation id="6910211073230771657">Deleted</translation> +<translation id="6912998170423641340">Block sites from reading text and images from the clipboard</translation> +<translation id="6914783257214138813">Your passwords will be visible to anyone who can see the exported file.</translation> +<translation id="6942665639005891494">Change the default download location at any time using the Settings menu option</translation> +<translation id="6945221475159498467">Select</translation> +<translation id="6963642900430330478">This page is dangerous. Site information</translation> +<translation id="6963766334940102469">Delete bookmarks</translation> +<translation id="6965382102122355670">OK</translation> +<translation id="6978479750597523876">Reset translate settings</translation> +<translation id="6979737339423435258">All time</translation> +<translation id="6981982820502123353">Accessibility</translation> +<translation id="6985347914332179298">No downloads here</translation> +<translation id="6990079615885386641">Get the app from the Google Play Store: <ph name="APP_ACTION" /></translation> +<translation id="699220179437400583">Automatically report details of possible security incidents to Google</translation> +<translation id="6992289844737586249">Ask first before allowing sites to use your microphone (recommended)</translation> +<translation id="7016516562562142042">Allowed for current search engine</translation> +<translation id="7021515813996758557"><ph name="FILE_NAME" /> downloaded</translation> +<translation id="7022756207310403729">Open in browser</translation> +<translation id="702463548815491781">Recommended when TalkBack or Switch Access are on</translation> +<translation id="7029809446516969842">Passwords</translation> +<translation id="7031882061095297553">Sync to</translation> +<translation id="7032663816368481562">When you tap More like this <ph name="ICON" /> in the address bar, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="7034608350006174882">Cards and addresses using Google Pay</translation> +<translation id="7053983685419859001">Block</translation> +<translation id="7055152154916055070">Redirect blocked:</translation> +<translation id="7062545763355031412">Accept and switch accounts</translation> +<translation id="7063006564040364415">Could not connect to the sync server.</translation> +<translation id="7066151586745993502">{NUM_SELECTED,plural, =1{1 selected}other{# selected}}</translation> +<translation id="7077143737582773186">SD Card</translation> +<translation id="7087918508125750058"><ph name="ITEM_COUNT" /> selected. Options available near top of the screen</translation> +<translation id="7108338896283013870">Hide</translation> +<translation id="7121362699166175603">Clears history and autocompletions in the address bar. 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="7128222689758636196">Allow for current search engine</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7139148793369023665">More like this closed</translation> +<translation id="7141896414559753902">Block sites from showing pop-ups and redirects (recommended)</translation> +<translation id="7149158118503947153"><ph name="BEGIN_LINK" />Load original page<ph name="END_LINK" /> from <ph name="DOMAIN_NAME" /></translation> +<translation id="7149893636342594995">Last 24 Hours</translation> +<translation id="7176368934862295254"><ph name="KILOBYTES" /> KB</translation> +<translation id="7177466738963138057">You can change this later in Settings</translation> +<translation id="7180611975245234373">Refresh</translation> +<translation id="7189372733857464326">Waiting for Google Play Services to finish updating</translation> +<translation id="7189598951263744875">Share...</translation> +<translation id="7191430249889272776">Tab opened in background.</translation> +<translation id="723171743924126238">Select images</translation> +<translation id="7243308994586599757">Options available near bottom of the screen</translation> +<translation id="7250468141469952378"><ph name="ITEM_COUNT" /> selected</translation> +<translation id="7251326866581677552">Blocked from some sites</translation> +<translation id="7253272406652746122">Add a Google account from the Accounts page in your device’s Settings app.</translation> +<translation id="7274013316676448362">Blocked site</translation> +<translation id="729975465115245577">Your device doesn’t have an app to store the passwords file.</translation> +<translation id="7302081693174882195">Details: Sorted by amount of data saved</translation> +<translation id="7333031090786104871">Still adding previous site</translation> +<translation id="7352939065658542140">VIDEO</translation> +<translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Share 1 selected item}other{Share # selected items}}</translation> +<translation id="7359002509206457351">Access payment methods</translation> +<translation id="7366340029385295517">Casting to <ph name="SCREEN_NAME" /></translation> +<translation id="7375125077091615385">Type:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> +<translation id="7400418766976504921">URL</translation> +<translation id="7403691278183511381">Chrome First Run Experience</translation> +<translation id="741204030948306876">Yes, I'm in</translation> +<translation id="7413229368719586778">Start date <ph name="DATE" /></translation> +<translation id="7423098979219808738">Ask first</translation> +<translation id="7423538860840206698">Blocked from reading clipboard</translation> +<translation id="7431991332293347422">Control how your browsing history is used to personalise Search and more</translation> +<translation id="7437998757836447326">Sign out of Chrome</translation> +<translation id="7444811645081526538">More categories</translation> +<translation id="7445411102860286510">Allow sites to automatically play muted videos (recommended)</translation> +<translation id="7454641608352164238">Not enough space</translation> +<translation id="7455923816558154057">Tap to view</translation> +<translation id="7465104139234185284">Close all private tabs</translation> +<translation id="7473891865547856676">No Thanks</translation> +<translation id="7475192538862203634">If you’re seeing this frequently, try these <ph name="BEGIN_LINK" />suggestions<ph name="END_LINK" />.</translation> +<translation id="7475688122056506577">SD card not found. Some of your files may be missing.</translation> +<translation id="748127970106343339">Confirm device credential deletion</translation> +<translation id="7481312909269577407">Forward</translation> +<translation id="7493994139787901920"><ph name="VERSION" /> (Updated <ph name="TIME_SINCE_UPDATE" />)</translation> +<translation id="7494879913343971937">Show passwords</translation> +<translation id="7494974237137038751">data saved</translation> +<translation id="7498271377022651285">Please wait…</translation> +<translation id="7514365320538308">Download</translation> +<translation id="751961395872307827">Can't connect to the site</translation> +<translation id="7521387064766892559">JavaScript</translation> +<translation id="7542481630195938534">Can’t get suggestions</translation> +<translation id="7562080006725997899">Clear browsing data</translation> +<translation id="756809126120519699">Cleared Chrome data</translation> +<translation id="757524316907819857">Block sites from playing protected content</translation> +<translation id="7589445247086920869">Block for current search engine</translation> +<translation id="7593557518625677601">Open Android settings and re-enable Android system sync to start Chrome sync</translation> +<translation id="7596558890252710462">Operating system</translation> +<translation id="7605594153474022051">Sync isn't working</translation> +<translation id="7612619742409846846">Signed in to Google as</translation> +<translation id="7619072057915878432"><ph name="FILE_NAME" /> download failed due to network failures.</translation> +<translation id="7624880197989616768"><ph name="BEGIN_LINK1" />Get help<ph name="END_LINK1" /> or <ph name="BEGIN_LINK2" />re-scan<ph name="END_LINK2" /></translation> +<translation id="7626032353295482388">Welcome to Chrome</translation> +<translation id="7638584964844754484">Incorrect passphrase</translation> +<translation id="7641339528570811325">Clear browsing data…</translation> +<translation id="7648422057306047504">Encrypt passwords with Google credentials</translation> +<translation id="7649070708921625228">Help</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7665369617277396874">Add account</translation> +<translation id="7682724950699840886">Try the following tips: make sure that there is enough space on your device; try to export again.</translation> +<translation id="7698359219371678927">Create email in <ph name="APP_NAME" /></translation> +<translation id="7704317875155739195">Auto-complete searches and URLs</translation> +<translation id="773466115871691567">Always translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> +<translation id="773905249182896430">Protects you and your device from dangerous sites</translation> +<translation id="7762668264895820836">SD Card <ph name="SD_CARD_NUMBER" /></translation> +<translation id="7764225426217299476">Add address</translation> +<translation id="7765158879357617694">Move</translation> +<translation id="7769602470925380267">Accept and sign out</translation> +<translation id="7772032839648071052">Confirm passphrase</translation> +<translation id="7774809984919390718">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}other{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}}</translation> +<translation id="7781829728241885113">Yesterday</translation> +<translation id="7791543448312431591">Add</translation> +<translation id="780301667611848630">No, thank you</translation> +<translation id="7810647596859435254">Open with…</translation> +<translation id="7821588508402923572">Your data savings will appear here</translation> +<translation id="7832327313660264358">The data that you sync to Google and the features that you use will not change</translation> +<translation id="7837721118676387834">Allow auto-play of muted videos for a specific site.</translation> +<translation id="7846076177841592234">Cancel selection</translation> +<translation id="784934925303690534">Time range</translation> +<translation id="7851858861565204677">Other Devices</translation> +<translation id="7854964836418414587">Close more like this</translation> +<translation id="7875915731392087153">Create email</translation> +<translation id="7876243839304621966">Remove all</translation> +<translation id="7882131421121961860">No history found</translation> +<translation id="7882806643839505685">Allow sound for a specific site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Downloading file.}other{Downloading # files.}}</translation> +<translation id="7929962904089429003">Opening the menu</translation> +<translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> is out of date.</translation> +<translation id="7947953824732555851">Accept and sign in</translation> +<translation id="7963646190083259054">Vendor:</translation> +<translation id="7981313251711023384">Preload pages for faster browsing and searching</translation> +<translation id="79859296434321399">To view augmented reality content, install ARCore</translation> +<translation id="7986741934819883144">Select a contact</translation> +<translation id="7987073022710626672">Chrome Terms of Service</translation> +<translation id="7987764905897278458">Get more Google smarts</translation> +<translation id="7998918019931843664">Re-open closed tab</translation> +<translation id="7999064672810608036">Are you sure that you want to clear all local data, including cookies, and reset all permissions for this website?</translation> +<translation id="8004582292198964060">Browser</translation> +<translation id="8007176423574883786">Turned off for this device</translation> +<translation id="8015452622527143194">Return everything on the page to default size</translation> +<translation id="802154636333426148">Download failed</translation> +<translation id="8026334261755873520">Clear browsing data</translation> +<translation id="8035133914807600019">New folder…</translation> +<translation id="8037411810184515274">VR</translation> +<translation id="8037686209485537503">More like this</translation> +<translation id="8037750541064988519"><ph name="DAYS" /> days left</translation> +<translation id="804335162455518893">SD card not found</translation> +<translation id="805047784848435650">Based on your browsing history</translation> +<translation id="8051695050440594747"><ph name="MEGABYTES" /> MB available</translation> +<translation id="8058746566562539958">Open in new Chrome tab</translation> +<translation id="8063895661287329888">Failed to add bookmark.</translation> +<translation id="806745655614357130">Keep my data separate</translation> +<translation id="8068648041423924542">Unable to select certificate.</translation> +<translation id="8073388330009372546">Open image in new tab</translation> +<translation id="8084114998886531721">Saved password</translation> +<translation id="8087000398470557479">This content is from <ph name="DOMAIN_NAME" />, delivered by Google.</translation> +<translation id="8103578431304235997">Incognito Tab</translation> +<translation id="8105951947646329362">Suggest related pages</translation> +<translation id="8109613176066109935">To get your bookmarks on all your devices, turn on sync</translation> +<translation id="8116925261070264013">Muted</translation> +<translation id="813082847718468539">View site information</translation> +<translation id="8156139159503939589">What languages do you read?</translation> +<translation id="8168435359814927499">Content</translation> +<translation id="8186512483418048923"><ph name="FILES" /> files left</translation> +<translation id="8190358571722158785">1 day left</translation> +<translation id="8200772114523450471">Resume</translation> +<translation id="8209050860603202033">Open image</translation> +<translation id="8220488350232498290"><ph name="GIGABYTES" /> GB downloaded</translation> +<translation id="8249310407154411074">Move to top</translation> +<translation id="8250920743982581267">Documents</translation> +<translation id="825412236959742607">This page uses too much memory, so Chrome removed some content.</translation> +<translation id="8260126382462817229">Try signing in again</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8266862848225348053">Download location</translation> +<translation id="8274165955039650276">See downloads</translation> +<translation id="8283853025636624853">Syncing to <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8310344678080805313">Standard tabs</translation> +<translation id="8313455859591948645">Edit startup page</translation> +<translation id="8316092324682955408"><ph name="DOMAIN_NAME" /> and more sites</translation> +<translation id="8339163506404995330">Pages in <ph name="LANGUAGE" /> will not be translated</translation> +<translation id="8349013245300336738">Sort by amount of data used</translation> +<translation id="8372893542064058268">Allow Background Sync for a specific site.</translation> +<translation id="8374821112118309944">You need to update TalkBack to a newer version.</translation> +<translation id="8393700583063109961">Send message</translation> +<translation id="8413126021676339697">Show full history</translation> +<translation id="8428213095426709021">Settings</translation> +<translation id="8438566539970814960">Make searches and browsing better</translation> +<translation id="8441146129660941386">Seek backward</translation> +<translation id="8445448999790540984">Can’t export passwords</translation> +<translation id="8447861592752582886">Revoke device permission</translation> +<translation id="8477071352266846533">Sync off for <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8487700953926739672">Available offline</translation> +<translation id="8489271220582375723">Open the history page</translation> +<translation id="8493948351860045254">Free up space</translation> +<translation id="8497726226069778601">Nothing to see here… yet</translation> +<translation id="8503559462189395349">Chrome Passwords</translation> +<translation id="8503813439785031346">Username</translation> +<translation id="8504988642345501642">When you scroll up, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="8507520749471379845">Passwords available</translation> +<translation id="8514477925623180633">Export passwords stored with Chrome</translation> +<translation id="8514577642972634246">Enter incognito mode</translation> +<translation id="851751545965956758">Block sites from connecting to devices</translation> +<translation id="8523928698583292556">Delete stored password</translation> +<translation id="854522910157234410">Open this page:</translation> +<translation id="8558485628462305855">To view augmented reality content, update ARCore</translation> +<translation id="8559990750235505898">Offer to translate pages in other languages</translation> +<translation id="8562452229998620586">Your saved passwords will appear here.</translation> +<translation id="8569404424186215731">since <ph name="DATE" /></translation> +<translation id="8571213806525832805">Last 4 weeks</translation> +<translation id="857509777403223202">More articles will appear soon. Enjoy your evening!</translation> +<translation id="857943718398505171">Allowed (recommended)</translation> +<translation id="8583805026567836021">Clearing account data</translation> +<translation id="8609465669617005112">Move up</translation> +<translation id="8616006591992756292">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="8617240290563765734">Open the suggested URL specified in the downloaded content?</translation> +<translation id="862875433388403934">Content (films, music, etc.) downloaded in other applications may no longer be playable until those applications re-acquire licences based on a new device credential. To obtain new licences, connect to the Internet and play your downloaded content.</translation> +<translation id="8636825310635137004">To get your tabs from your other devices, turn on sync.</translation> +<translation id="8641930654639604085">Try to block mature sites</translation> +<translation id="8662811608048051533">Signs you out of most sites.</translation> +<translation id="8664979001105139458">File name already exists</translation> +<translation id="8676374126336081632">Clear input</translation> +<translation id="8687353297350450808">{N_BARS,plural, =1{Signal Strength Level: # bar}other{Signal Strength Level: # bars}}</translation> +<translation id="868929229000858085">Search your contacts</translation> +<translation id="869891660844655955">Expiry date</translation> +<translation id="8719023831149562936">Can’t beam current tab</translation> +<translation id="8725066075913043281">Try again</translation> +<translation id="8728487861892616501">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8730621377337864115">Done</translation> +<translation id="8748850008226585750">Contents hidden</translation> +<translation id="8751914237388039244">Select an image</translation> +<translation id="8788968922598763114">Reopen the last closed tab</translation> +<translation id="8812260976093120287">On some websites, you can pay with above supported payment apps on your device.</translation> +<translation id="8816439037877937734"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome's <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8820817407110198400">Bookmarks</translation> +<translation id="8823704566850948458">Suggest password...</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> +<translation id="883806473910249246">An error occurred while downloading the content.</translation> +<translation id="8840953339110955557">This page may differ from the online version.</translation> +<translation id="8847988622838149491">USB</translation> +<translation id="8853345339104747198"><ph name="TAB_TITLE" />, tab</translation> +<translation id="885701979325669005">Storage</translation> +<translation id="8901170036886848654">No bookmarks found</translation> +<translation id="8909135823018751308">Share…</translation> +<translation id="8912362522468806198">Google Account</translation> +<translation id="8920114477895755567">Waiting for details of parents.</translation> +<translation id="8922289737868596582">Download pages from the More Options button to use them offline</translation> +<translation id="8941729603749328384">www.example.com</translation> +<translation id="8942627711005830162">Open in other window</translation> +<translation id="8951232171465285730">Chrome has saved you <ph name="MEGABYTES" /> MB</translation> +<translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> +<translation id="8972098258593396643">Download to default folder?</translation> +<translation id="8979405271719829084">Download videos to watch later</translation> +<translation id="8981454092730389528">Google Activity Controls</translation> +<translation id="8983677657449185470">Help improve Safe Browsing</translation> +<translation id="8986494364107987395">Automatically send usage statistics and crash reports to Google</translation> +<translation id="8993760627012879038">Open a new tab in Incognito mode</translation> +<translation id="8998729206196772491">You are signing in with an account managed by <ph name="MANAGED_DOMAIN" /> and giving its administrator control over your Chrome data. Your data will become permanently tied to this account. Signing out of Chrome will delete your data from this device, but it will remain stored in your Google account.</translation> +<translation id="9019902583201351841">Managed by your parents</translation> +<translation id="9040142327097499898">Notifications are allowed. Location is off for this device.</translation> +<translation id="9050666287014529139">Passphrase</translation> +<translation id="9060538597317784206">View app <ph name="APP_NAME" /> on the Play Store. Rating: <ph name="APP_RATING" />.</translation> +<translation id="9063523880881406963">Turn off Request desktop site</translation> +<translation id="9065203028668620118">Edit</translation> +<translation id="9070377983101773829">Start voice search</translation> +<translation id="9071742570345586758">To view virtual reality content, install Google VR Services</translation> +<translation id="9074336505530349563">To get personalised content suggested by Google, sign in and turn on sync</translation> +<translation id="9080642952018487277">Enter private mode</translation> +<translation id="9086455579313502267">Unable to access the network</translation> +<translation id="9099018167121903954"><ph name="KILOBYTES" /> KB downloaded</translation> +<translation id="9100505651305367705">Offer to show articles in simplified view, when supported</translation> +<translation id="9100610230175265781">Passphrase required</translation> +<translation id="9100939710791843300">Tap the home button to load the new tab page and view suggested articles</translation> +<translation id="9133515669113036225">Reset device credentials</translation> +<translation id="9133703968756164531"><ph name="ITEM_NAME" /> (<ph name="ITEM_ID" />)</translation> +<translation id="9137013805542155359">Show original</translation> +<translation id="9139068048179869749">Ask before allowing sites to send notifications (recommended)</translation> +<translation id="9155898266292537608">You can also search with a quick tap on a word</translation> +<translation id="9188680907066685419">Sign out of managed account</translation> +<translation id="9204836675896933765">1 file left</translation> +<translation id="9206873250291191720">A</translation> +<translation id="9218033835049520260">Suggest strong password...</translation> +<translation id="9219103736887031265">Images</translation> +<translation id="932327136139879170">Home</translation> +<translation id="932599481871055447">Save data and browse faster</translation> +<translation id="938850635132480979">Error: <ph name="ERROR_CODE" /></translation> +<translation id="945522503751344254">Send feedback</translation> +<translation id="945632385593298557">Access your microphone</translation> +<translation id="951339005376969845">Delete existing data. You can retrieve it by switching back to <ph name="FROM_ACCOUNT" />.</translation> +<translation id="95817756606698420">Chrome can use <ph name="BEGIN_BOLD" />Sogou<ph name="END_BOLD" /> for search in China. You can change this in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="970715775301869095"><ph name="MINUTES" /> mins left</translation> +<translation id="974555521953189084">Enter your passphrase to start sync</translation> +<translation id="981121421437150478">Offline</translation> +<translation id="982182592107339124">This will clear data for all sites, including:</translation> +<translation id="983192555821071799">Close all tabs</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_gu.xtb b/chrome/android/java/strings/translations/android_chrome_strings_gu.xtb new file mode 100644 index 0000000..615f9c6 --- /dev/null +++ b/chrome/android/java/strings/translations/android_chrome_strings_gu.xtb
@@ -0,0 +1,1056 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="gu"> +<translation id="1006017844123154345">Open Online</translation> +<translation id="1036727731225946849">Adding <ph name="WEBAPK_NAME" />...</translation> +<translation id="1041308826830691739">From websites</translation> +<translation id="1049743911850919806">Incognito</translation> +<translation id="1054301162707478098">You’ve gone private.</translation> +<translation id="10614374240317010">Never saved</translation> +<translation id="1067922213147265141">Other Google services</translation> +<translation id="1068672505746868501">Never translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="10713315585330490"><ph name="FILE_SIZE" /> – <ph name="DESCRIPTION" /></translation> +<translation id="1080790410959514870">You are signing out of an account managed by <ph name="DOMAIN_NAME" />. This will delete the Chrome data stored on this device, but the data will remain in your Google Account.</translation> +<translation id="1105960400813249514">Screen Capture</translation> +<translation id="1111673857033749125">Bookmarks saved on your other devices will appear here.</translation> +<translation id="1113597929977215864">Show simplified view</translation> +<translation id="1121094540300013208">Usage and crash reports</translation> +<translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download pending.}other{# downloads pending.}}</translation> +<translation id="1145536944570833626">Delete existing data.</translation> +<translation id="1146678959555564648">Enter VR</translation> +<translation id="114721135501989771">Get Google smarts in Chrome</translation> +<translation id="1157102636231978136">Your browsing data and activity, synced to your Google account</translation> +<translation id="116280672541001035">Used</translation> +<translation id="1172593791219290334">Startup Page</translation> +<translation id="1175310183703641346">Your bookmarks, history, passwords and more will no longer be synced to your Google account</translation> +<translation id="1178581264944972037">Pause</translation> +<translation id="1181037720776840403">Remove</translation> +<translation id="1197267115302279827">Move bookmarks</translation> +<translation id="119944043368869598">Clear all</translation> +<translation id="1201402288615127009">Next</translation> +<translation id="1204037785786432551">Download link</translation> +<translation id="1206892813135768548">Copy link text</translation> +<translation id="1208340532756947324">To sync and personalise across devices, turn on sync</translation> +<translation id="1209206284964581585">Hide for now</translation> +<translation id="123724288017357924">Reload the current page, ignoring cached content</translation> +<translation id="124116460088058876">More languages</translation> +<translation id="124678866338384709">Close current tab</translation> +<translation id="1258753120186372309">Google doodle: <ph name="DOODLE_DESCRIPTION" /></translation> +<translation id="1259100630977430756">Pages that you view in private tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your private tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going private doesn’t hide your browsing from your employer, your Internet service provider or the websites that you visit.</translation> +<translation id="127138278192656016">Use sync and all services</translation> +<translation id="1272079795634619415">Stop</translation> +<translation id="1283039547216852943">Tap to expand</translation> +<translation id="1285320974508926690">Never translate this site</translation> +<translation id="1291207594882862231">Clear history, cookies, site data, cache…</translation> +<translation id="129553762522093515">Recently closed</translation> +<translation id="1326317727527857210">To get your tabs from your other devices, sign in to Chrome.</translation> +<translation id="1332501820983677155">Google Chrome feature shortcuts</translation> +<translation id="1360432990279830238">Sign out and turn off sync?</translation> +<translation id="136248372334525878">Preload pages for faster loading and offline reading</translation> +<translation id="1369915414381695676">Site <ph name="SITE_NAME" /> added</translation> +<translation id="1373696734384179344">Insufficient memory to download the selected content.</translation> +<translation id="1376578503827013741">Computing…</translation> +<translation id="138361230106469022">Hi, <ph name="FULL_NAME" /></translation> +<translation id="1383876407941801731">Search</translation> +<translation id="1384959399684842514">Download paused</translation> +<translation id="1389974829397082527">No bookmarks here</translation> +<translation id="1397811292916898096">Search with <ph name="PRODUCT_NAME" /></translation> +<translation id="1397854323885047133">Sync and personalisation</translation> +<translation id="1404122904123200417">Embedded in <ph name="WEBSITE_URL" /></translation> +<translation id="1406000523432664303">“Do Not Track”</translation> +<translation id="1407135791313364759">Open all</translation> +<translation id="1409426117486808224">Simplified view for open tabs</translation> +<translation id="1409879593029778104"><ph name="FILE_NAME" /> download prevented because file already exists.</translation> +<translation id="1414981605391750300">Contacting Google. This may take a minute…</translation> +<translation id="1416550906796893042">Application version</translation> +<translation id="1430915738399379752">Print</translation> +<translation id="1445680696957526815">Chrome’s components are incompatible with one another. Chrome may be upgrading, please try again in a few minutes. If the problem continues, try uninstalling and re-installing Chrome.</translation> +<translation id="1446450296470737166">Allow full control of MIDI devices</translation> +<translation id="145097072038377568">Turned off in Android Settings</translation> +<translation id="1477626028522505441"><ph name="FILE_NAME" /> download failed due to server issues.</translation> +<translation id="1506061864768559482">Search engine</translation> +<translation id="1513352483775369820">Bookmarks and web history</translation> +<translation id="1513858653616922153">Delete password</translation> +<translation id="1516229014686355813">Tap to Search sends the selected word and the current page as context to Google Search. You can turn it off in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="1539064842193522527">Link opened in Chrome</translation> +<translation id="1549000191223877751">Move to other window</translation> +<translation id="1553358976309200471">Update Chrome</translation> +<translation id="1566400915470565838">To use <ph name="APP_NAME" />, please connect to the Internet.</translation> +<translation id="1569387923882100876">Connected device</translation> +<translation id="1571304935088121812">Copy username</translation> +<translation id="1576370611341449972">Download occurs only on Wi-Fi</translation> +<translation id="1612196535745283361">Chrome needs location access to scan for devices. Location access is <ph name="BEGIN_LINK" />turned off for this device<ph name="END_LINK" />.</translation> +<translation id="162035744160882748">Turn on sync, personalisation and other Google services</translation> +<translation id="1620510694547887537">Camera</translation> +<translation id="1623104350909869708">Prevent this page from creating additional dialogues</translation> +<translation id="1628019612362412531">{NUM_SELECTED,plural, =1{Remove 1 selected item}other{Remove # selected items}}</translation> +<translation id="1641113438599504367">Safe Browsing</translation> +<translation id="164269334534774161">You are viewing an offline copy of this page from <ph name="CREATION_TIME" /></translation> +<translation id="1644574205037202324">History</translation> +<translation id="1647391597548383849">Access your camera</translation> +<translation id="1660204651932907780">Allow sites to play sound (recommended)</translation> +<translation id="1670399744444387456">Basic</translation> +<translation id="1671236975893690980">Download pending...</translation> +<translation id="1672586136351118594">Don‘t show again</translation> +<translation id="1709438864123551175">Data Saver</translation> +<translation id="1718835860248848330">Last hour</translation> +<translation id="1729516292547892356">To view virtual reality content, update Google VR Services</translation> +<translation id="1733116627827457509"><ph name="FILE_SIZE" /> – Updated <ph name="TIME_SINCE_UPDATE" /></translation> +<translation id="1736419249208073774">Explore</translation> +<translation id="1743802530341753419">Ask before allowing sites to connect to a device (recommended)</translation> +<translation id="1749561566933687563">Sync your bookmarks</translation> +<translation id="17513872634828108">Open tabs</translation> +<translation id="1756600373018374892">Tap this button for quick access to your tabs.</translation> +<translation id="1779089405699405702">Image decoder</translation> +<translation id="1782483593938241562">End date <ph name="DATE" /></translation> +<translation id="1792959175193046959">Change the default download location at any time</translation> +<translation id="1807246157184219062">Light</translation> +<translation id="1821253160463689938">Uses cookies to remember your preferences, even if you don't visit those pages</translation> +<translation id="1829244130665387512">Find in page</translation> +<translation id="1832521218263067499">Security incidents</translation> +<translation id="1853692000353488670">New incognito tab</translation> +<translation id="1868024384445905608">Chrome now downloads files faster</translation> +<translation id="1878302395768190018">You can customise this at any time in Chrome Settings</translation> +<translation id="1880072593381090678">Popular pages from Chrome</translation> +<translation id="1883903952484604915">My files</translation> +<translation id="1887786770086287077">Location access is off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1891331835972267886"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="189172778771606813">Close navigation drawer</translation> +<translation id="1919345977826869612">Ads</translation> +<translation id="1919950603503897840">Select contacts</translation> +<translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/<ph name="FILE_SIZE_WITH_UNITS" /></translation> +<translation id="1933845786846280168">Selected Tab</translation> +<translation id="1938981467853765413">Provide feedback</translation> +<translation id="194341124344773587">Turn on permission for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1943432128510653496">Save passwords</translation> +<translation id="1944384637046898011">Encrypt all with Google password as of <ph name="TIME" /></translation> +<translation id="1946005195648379376">Control how Google uses your browsing history to personalise Search and other Google services.</translation> +<translation id="1952172573699511566">Websites will show text in your preferred language, when possible.</translation> +<translation id="195283394249132567">Personalised Google services</translation> +<translation id="1966710179511230534">Please update your sign-in details.</translation> +<translation id="1974060860693918893">Advanced</translation> +<translation id="1984937141057606926">Allowed, except third-party</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> button</translation> +<translation id="1989112275319619282">Browse</translation> +<translation id="1993768208584545658"><ph name="SITE" /> wants to pair</translation> +<translation id="1994173015038366702">Site URL</translation> +<translation id="2000419248597011803">Sends some cookies and searches from the address bar and search box to your default search engine</translation> +<translation id="2002537628803770967">Credit cards and addresses using Google Pay</translation> +<translation id="200815880754187296"><ph name="KILOBYTES" /> KB other apps</translation> +<translation id="2017836877785168846">Clears history and autocompletions in the address bar.</translation> +<translation id="2021896219286479412">Full screen site controls</translation> +<translation id="2038563949887743358">Turn on Request desktop site</translation> +<translation id="2045104531052923016"><ph name="GIGABYTES" /> GB other apps</translation> +<translation id="2063713494490388661">Tap to Search</translation> +<translation id="2079545284768500474">Undo</translation> +<translation id="2082238445998314030">Result <ph name="RESULT_NUMBER" /> of <ph name="TOTAL_RESULTS" /></translation> +<translation id="2086652334978798447">To get personalised content suggested by Google, sign in to Chrome.</translation> +<translation id="2091887806945687916">Sound</translation> +<translation id="2095887075102408547">When this feature is turned on, Chrome will use Google servers to compress pages that you visit before downloading them. Pages accessed using private connections (HTTPS) or in Incognito tabs will not be optimised or seen by Google.</translation> +<translation id="2096012225669085171">Sync and personalise across devices</translation> +<translation id="2100273922101894616">Auto Sign-in</translation> +<translation id="2111511281910874386">Go to page</translation> +<translation id="2120297377148151361">Activity and interactions</translation> +<translation id="2122601567107267586">Could not open app</translation> +<translation id="2126426811489709554">Powered by Chrome</translation> +<translation id="2131665479022868825"><ph name="DATA" /> saved</translation> +<translation id="213279576345780926">Closed <ph name="TAB_TITLE" /></translation> +<translation id="2139186145475833000">Add to Home screen</translation> +<translation id="2142289305367051020">Your favourite pages are here</translation> +<translation id="2146738493024040262">Open Instant App</translation> +<translation id="2148716181193084225">Today</translation> +<translation id="2154484045852737596">Edit card</translation> +<translation id="2154710561487035718">Copy URL</translation> +<translation id="2156074688469523661">Remaining sites (<ph name="NUMBER_OF_SITES" />)</translation> +<translation id="2206488550163399966"><ph name="APP_NAME" />, web app. <ph name="APP_URL" /></translation> +<translation id="2227444325776770048">Continue as <ph name="USER_FULL_NAME" /></translation> +<translation id="2232379019872353004">Sends some system information and page content to Google</translation> +<translation id="2234876718134438132">Sync and Google services</translation> +<translation id="2259659629660284697">Export passwords…</translation> +<translation id="2268044343513325586">Refine</translation> +<translation id="2280910239864711607">Open a new tab in private mode</translation> +<translation id="2286841657746966508">Billing address</translation> +<translation id="230115972905494466">No compatible devices found</translation> +<translation id="2315043854645842844">Client side certificate selection is not supported by the operating system.</translation> +<translation id="2321086116217818302">Preparing passwords…</translation> +<translation id="2321958826496381788">Drag the slider until you can read this comfortably. Text should look at least this big after double-tapping on a paragraph.</translation> +<translation id="2323763861024343754">Site storage</translation> +<translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised by you or your parents at any time. Google may use content on sites that you visit, as well as browsing activity and interactions, to personalise Chrome and Google services such as Translate, Search and ads.</translation> +<translation id="2328985652426384049">Can’t sign in</translation> +<translation id="2342981853652716282">Sign in to Chrome to get your bookmarks, passwords and more on all your devices.</translation> +<translation id="2343328333327081434">Installing…</translation> +<translation id="2346253980530904022">Google servers will optimise the pages that you visit, except for HTTPS and Incognito.</translation> +<translation id="2349710944427398404">Total data used by Chrome, including accounts, bookmarks and saved settings</translation> +<translation id="2351097562818989364">Your translate settings have been reset.</translation> +<translation id="2359808026110333948">Continue</translation> +<translation id="2369533728426058518">open tabs</translation> +<translation id="2387895666653383613">Text scaling</translation> +<translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> +<translation id="2410754283952462441">Choose an account</translation> +<translation id="2414672073755873541">No content here</translation> +<translation id="2414886740292270097">Dark</translation> +<translation id="2416359993254398973">Chrome needs permission to access your camera for this site.</translation> +<translation id="2426805022920575512">Choose another account</translation> +<translation id="2433507940547922241">Appearance</translation> +<translation id="2434158240863470628">Download complete <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2436117022029368436">Communicates with Google to improve browsing and Chrome</translation> +<translation id="2440823041667407902">Location access</translation> +<translation id="2450083983707403292">Do you want to start downloading <ph name="FILE_NAME" /> again?</translation> +<translation id="2476578072172137802">Site Settings</translation> +<translation id="2482878487686419369">Notifications</translation> +<translation id="2496180316473517155">Browsing history</translation> +<translation id="2498359688066513246">Help & feedback</translation> +<translation id="2501278716633472235">Go back</translation> +<translation id="2513403576141822879">For more settings that relate to privacy, security and data collection, see <ph name="BEGIN_LINK" />Sync and Google services<ph name="END_LINK" /></translation> +<translation id="2523184218357549926">Sends URLs of pages that you visit to Google</translation> +<translation id="2526148617758225454">Data Saver is on. Manage it in Settings.</translation> +<translation id="2532336938189706096">Web View</translation> +<translation id="2536728043171574184">Viewing an offline copy of this page</translation> +<translation id="2546283357679194313">Cookies and site data</translation> +<translation id="2567385386134582609">IMAGE</translation> +<translation id="2570922361219980984">Location access is also off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="257931822824936280">Expanded – click to collapse.</translation> +<translation id="2581165646603367611">This will clear cookies, cache and other data of sites Chrome doesn't think is important.</translation> +<translation id="2586657967955657006">Clipboard</translation> +<translation id="2587052924345400782">Newer version is available</translation> +<translation id="2593272815202181319">Monospace</translation> +<translation id="2612676031748830579">Card number</translation> +<translation id="2621115761605608342">Allow JavaScript for a specific site.</translation> +<translation id="2625189173221582860">Password copied</translation> +<translation id="2631006050119455616">Saved</translation> +<translation id="2633278372998075009">Private tabs</translation> +<translation id="2647434099613338025">Add language</translation> +<translation id="2650751991977523696">Download file again?</translation> +<translation id="2653659639078652383">Submit</translation> +<translation id="2677748264148917807">Leave</translation> +<translation id="2704606927547763573">Copied</translation> +<translation id="2707726405694321444">Refresh page</translation> +<translation id="2709516037105925701">Auto-fill</translation> +<translation id="271033894570825754">New</translation> +<translation id="2728754400939377704">Sort by site</translation> +<translation id="2744248271121720757">Tap a word to search instantly or see related actions</translation> +<translation id="2762000892062317888">just now</translation> +<translation id="2777555524387840389"><ph name="SECONDS" /> secs left</translation> +<translation id="2781151931089541271">1 sec left</translation> +<translation id="2803478378562657435">Showing saved passwords and password options</translation> +<translation id="2810645512293415242">Simplified page to save data and load faster.</translation> +<translation id="281504910091592009">View and manage saved passwords in your <ph name="BEGIN_LINK" />Google account<ph name="END_LINK" /></translation> +<translation id="2818669890320396765">To get your bookmarks on all your devices, sign in and turn on sync</translation> +<translation id="2836148919159985482">Touch the back button to exit full screen.</translation> +<translation id="2842985007712546952">Parent folder</translation> +<translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Previous track</translation> +<translation id="2876764156902388290">Chrome is using less data to show you this page</translation> +<translation id="2888126860611144412">About Chrome</translation> +<translation id="2891154217021530873">Stop page loading</translation> +<translation id="2900528713135656174">Create event</translation> +<translation id="2902702728133930130">Chrome failed during start-up with an unexpected error.</translation> +<translation id="290376772003165898">Page is not in <ph name="LANGUAGE" />?</translation> +<translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> +<translation id="2913331724188855103">Allow sites to save and read cookie data (recommended)</translation> +<translation id="2932150158123903946">Google <ph name="APP_NAME" /> storage</translation> +<translation id="2943166482989655199">Improve Chrome and its security by sending system and usage data to Google</translation> +<translation id="2956410042958133412">This account is managed by <ph name="PARENT_NAME_1" /> and <ph name="PARENT_NAME_2" />.</translation> +<translation id="2960796085439532066">Copyright <ph name="YEAR" /> Google Inc. All rights reserved.</translation> +<translation id="2962095958535813455">Switched to incognito tabs</translation> +<translation id="2968755619301702150">Certificate viewer</translation> +<translation id="2979025552038692506">Selected Incognito Tab</translation> +<translation id="2989523299700148168">Recently Visited</translation> +<translation id="2996291259634659425">Create passphrase</translation> +<translation id="2996809686854298943">URL required</translation> +<translation id="300526633675317032">This will clear all <ph name="SIZE_IN_KB" /> of website storage.</translation> +<translation id="3029613699374795922">Downloaded <ph name="KBS" /> KB</translation> +<translation id="3029704984691124060">Passphrases do not match</translation> +<translation id="3036750288708366620"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /></translation> +<translation id="3045654778214005718">See more like this from Google</translation> +<translation id="305593374596241526">Location is off; turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="307908932405420782">More articles will appear soon. Enjoy your morning!</translation> +<translation id="3089395242580810162">Open in incognito tab</translation> +<translation id="311456632243022227">Multiple links opened in Chrome</translation> +<translation id="3115898365077584848">Show info</translation> +<translation id="3137521801621304719">Leave incognito mode</translation> +<translation id="3148434565183091099">To get your bookmarks on all your devices, sign in to Chrome.</translation> +<translation id="3157842584138209013">See how much data you've saved from the More Options button</translation> +<translation id="3166827708714933426">Tab and window shortcuts</translation> +<translation id="3190152372525844641">Turn on permissions for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> stored data</translation> +<translation id="3207960819495026254">Bookmarked</translation> +<translation id="321773570071367578">If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="3227137524299004712">Microphone</translation> +<translation id="3232754137068452469">Web App</translation> +<translation id="3234355010754616171">New private tab</translation> +<translation id="3236059992281584593">1 min left</translation> +<translation id="3244271242291266297">MM</translation> +<translation id="3254409185687681395">Bookmark this page</translation> +<translation id="3259831549858767975">Make everything on the page smaller</translation> +<translation id="3269093882174072735">Load image</translation> +<translation id="3269956123044984603">To get your tabs from your other devices, turn on “Auto-sync data” in Android account settings.</translation> +<translation id="3282568296779691940">Sign in to Chrome</translation> +<translation id="32895400574683172">Notifications are allowed</translation> +<translation id="3295602654194328831">Hide info</translation> +<translation id="3298243779924642547">Lite</translation> +<translation id="3303414029551471755">Proceed to download the content?</translation> +<translation id="3328801116991980348">Site information</translation> +<translation id="3341058695485821946">See how much data you've saved</translation> +<translation id="3350687908700087792">Close all incognito tabs</translation> +<translation id="3365671512111106261">Unavailable when Data Saver is turned on</translation> +<translation id="3367813778245106622">Sign in again to start sync</translation> +<translation id="3377025655491224618">Private tab</translation> +<translation id="3384347053049321195">Share image</translation> +<translation id="3386292677130313581">Ask before allowing sites to know your location (recommended)</translation> +<translation id="3387650086002190359"><ph name="FILE_NAME" /> download failed due to file system errors.</translation> +<translation id="339329030417445648">This site tends to show intrusive ads</translation> +<translation id="3398320232533725830">Open the bookmarks manager</translation> +<translation id="3414952576877147120">Size:</translation> +<translation id="3443221991560634068">Reload the current page</translation> +<translation id="3452612588551937789">Sign in with your Google Account to get your bookmarks, history, passwords and other settings on all your devices.</translation> +<translation id="3485359633434254965">{FILES,plural, =1{%1$d file downloaded}other{%1$d files downloaded}}</translation> +<translation id="3492207499832628349">New incognito tab</translation> +<translation id="3493531032208478708"><ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /> about suggested content</translation> +<translation id="3518985090088779359">Accept & continue</translation> +<translation id="3522247891732774234">Update available. More options</translation> +<translation id="3527085408025491307">Folder</translation> +<translation id="3542235761944717775"><ph name="KILOBYTES" /> KB available</translation> +<translation id="3549644494707163724">Encrypt all synced data with your own sync passphrase</translation> +<translation id="3549657413697417275">Search your history</translation> +<translation id="3552151358455404883">Manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="3557336313807607643">Add to contacts</translation> +<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="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="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="3600792891314830896">Mute sites that play sound</translation> +<translation id="360207483134687714">Help improve the VR experience in Chrome</translation> +<translation id="3616113530831147358">Audio</translation> +<translation id="3620176948598597475">Resetting erases Data Saver history, including the list of visited sites.</translation> +<translation id="3630011985153972676">Allow Chrome to download articles for you when on Wi-Fi under settings.</translation> +<translation id="3632295766818638029">Unmask password</translation> +<translation id="363596933471559332">Automatically sign in to websites using stored credentials. When the feature is off, you’ll be asked for verification every time before signing in to a website.</translation> +<translation id="3661699943263275414">Third-party websites can save and read cookie data</translation> +<translation id="3662546969139119822">No history here</translation> +<translation id="3672452749423051839">Navigation error suggestions</translation> +<translation id="3692944402865947621"><ph name="FILE_NAME" /> download failed because storage location is not reachable.</translation> +<translation id="3712575778697986964">Reset Data Saver?</translation> +<translation id="3714981814255182093">Open the Find Bar</translation> +<translation id="3716182511346448902">This page uses too much memory, so Chrome paused it.</translation> +<translation id="3739899004075612870">Bookmarked in <ph name="PRODUCT_NAME" /></translation> +<translation id="3744111309925758534"><ph name="MEGABYTES" /> MB other apps</translation> +<translation id="3744111561329211289">Background sync</translation> +<translation id="3773755127849930740"><ph name="BEGIN_LINK" />Turn on Bluetooth<ph name="END_LINK" /> to allow pairing</translation> +<translation id="3778956594442850293">Added to Home screen</translation> +<translation id="3781011235031427080">More like this opened at half height</translation> +<translation id="3789841737615482174">Install</translation> +<translation id="3810838688059735925">Video</translation> +<translation id="3810973564298564668">Manage</translation> +<translation id="3819178904835489326"><ph name="NUMBER_OF_DOWNLOADS" /> downloads deleted</translation> +<translation id="3819562311292413223">Download articles for you</translation> +<translation id="3822502789641063741">Clear site storage?</translation> +<translation id="385051799172605136">Back</translation> +<translation id="3859306556332390985">Seek forward</translation> +<translation id="3868004864571585162">Cookies, media licences and site data</translation> +<translation id="3894427358181296146">Add folder</translation> +<translation id="3895926599014793903">Force enable zoom</translation> +<translation id="3927692899758076493">Sans Serif</translation> +<translation id="3928666092801078803">Combine my data</translation> +<translation id="393697183122708255">No enabled voice search available</translation> +<translation id="3950820424414687140">Sign in</translation> +<translation id="395206256282351086">Search and site suggestions disabled</translation> +<translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> +<translation id="3967822245660637423">Download complete</translation> +<translation id="397583555483684758">Sync has stopped working</translation> +<translation id="3976396876660209797">Remove and recreate this shortcut</translation> +<translation id="3985215325736559418">Do you want to download <ph name="FILE_NAME" /> again?</translation> +<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="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> +<translation id="3997476611815694295">Unimportant storage</translation> +<translation id="4002066346123236978">Title</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# hr}other{# hrs}}</translation> +<translation id="4042870126885713738">Show suggestions when a web address does not resolve or a connection cannot be made</translation> +<translation id="4046123991198612571">Next track</translation> +<translation id="4048707525896921369">Learn about topics on websites without leaving the page. Tap to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results and other details. + +To adjust your search term, long press to select. To refine your search, slide the panel all the way up and tap the search box.</translation> +<translation id="4056223980640387499">Sepia</translation> +<translation id="4060598801229743805">Options available near the top of the screen</translation> +<translation id="4062305924942672200">Legal information</translation> +<translation id="4084682180776658562">Bookmark</translation> +<translation id="4084712963632273211">From <ph name="PUBLISHER_ORIGIN" /> – <ph name="BEGIN_DEEMPHASIZED" />delivered by Google<ph name="END_DEEMPHASIZED" /></translation> +<translation id="4084836577264234537"><ph name="MEGABYTES" /> MB downloaded</translation> +<translation id="4089831646916293264">This feature may interfere with access to premium data services provided by your operator.</translation> +<translation id="4095146165863963773">Delete app data?</translation> +<translation id="4097739989936358050">This app is running in Chrome.</translation> +<translation id="4099578267706723511">Help make Chrome better by sending usage statistics and crash reports to Google.</translation> +<translation id="410351446219883937">Autoplay</translation> +<translation id="4113030288477039509">Managed by your administrator</translation> +<translation id="4116038641877404294">Download pages to use them offline</translation> +<translation id="4127069705158143605">{BOOKMARKS_COUNT,plural, =1{%1$d bookmark}other{%1$d bookmarks}}</translation> +<translation id="4149994727733219643">Simplified view for web pages</translation> +<translation id="4159800535322890630">Block sites from accessing your sensors</translation> +<translation id="4165986682804962316">Site settings</translation> +<translation id="4170011742729630528">The service is not available; try again later.</translation> +<translation id="4179980317383591987"><ph name="AMOUNT" /> used</translation> +<translation id="4181841719683918333">Languages</translation> +<translation id="4192273449750167573">Review your settings on the next screen</translation> +<translation id="4195643157523330669">Open in new tab</translation> +<translation id="4198423547019359126">No available download locations</translation> +<translation id="4209895695669353772">To get personalised content suggested by Google, turn on sync</translation> +<translation id="4226663524361240545">Notifications may vibrate the device</translation> +<translation id="4242533952199664413">Open settings</translation> +<translation id="4243710787042215766">Open in private tab</translation> +<translation id="424864128008805179">Sign out of Chrome?</translation> +<translation id="4256782883801055595">Open-source licences</translation> +<translation id="4259722352634471385">Navigation is blocked: <ph name="URL" /></translation> +<translation id="4262028915562328938">Sync error occurred, tap to get details.</translation> +<translation id="4269820728363426813">Copy link address</translation> +<translation id="4275663329226226506">Media</translation> +<translation id="4278390842282768270">Allowed</translation> +<translation id="4307992518367153382">Basics</translation> +<translation id="4351244548802238354">Close dialogue</translation> +<translation id="4378154925671717803">Phone</translation> +<translation id="4384468725000734951">Using Sogou for search</translation> +<translation id="4398088515904522762">To use this feature, turn on <ph name="BEGIN_LINK" />Activity and interactions<ph name="END_LINK" />.</translation> +<translation id="4404568932422911380">No bookmarks</translation> +<translation id="4409723563706114196">Use page predictions</translation> +<translation id="4412992751769744546">Allow third-party cookies</translation> +<translation id="4419556793104466535">Control sync, personalisation and more</translation> +<translation id="4432792777822557199">Pages in <ph name="SOURCE_LANGUAGE" /> will be translated to <ph name="TARGET_LANGUAGE" /> from now on</translation> +<translation id="4434045419905280838">Pop-ups and redirects</translation> +<translation id="4452411734226507615">Close <ph name="TAB_TITLE" /> tab</translation> +<translation id="4452548195519783679">Bookmarked to <ph name="FOLDER_NAME" /></translation> +<translation id="4453340223357552416"><ph name="FILE_NAME" /> downloaded in <ph name="PRODUCT_NAME" /></translation> +<translation id="4468959413250150279">Mute sound for a specific site.</translation> +<translation id="4472118726404937099">To sync and personalise across devices, sign in and turn on sync</translation> +<translation id="447252321002412580">Help improve Chrome's features and performance</translation> +<translation id="4479647676395637221">Ask first before allowing sites to use your camera (recommended)</translation> +<translation id="4487967297491345095">All Chrome’s app data will be deleted permanently. This includes all files, settings, accounts, databases, etc.</translation> +<translation id="4508440807153586353">Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting you'll need to reset sync. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation> +<translation id="4513387527876475750">{DAYS,plural, =1{# day ago}other{# days ago}}</translation> +<translation id="451872707440238414">Search your bookmarks</translation> +<translation id="4521489764227272523">The selected data has been removed from Chrome and your synced devices. + +Your Google Account may have other forms of browsing history such as searches and activity from other Google services at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="4532845899244822526">Choose folder</translation> +<translation id="4550003330909367850">To view or copy your password here, set screen lock on this device.</translation> +<translation id="4558311620361989323">Web page shortcuts</translation> +<translation id="4561979708150884304">No connection</translation> +<translation id="4565377596337484307">Hide password</translation> +<translation id="4570913071927164677">Details</translation> +<translation id="4572422548854449519">Sign in to managed account</translation> +<translation id="4581964774250883625">You’ve gone incognito.</translation> +<translation id="4583164079174244168">{MINUTES,plural, =1{# minute ago}other{# minutes ago}}</translation> +<translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">This offline page is from <ph name="CREATION_TIME" /> and may differ from the online version.</translation> +<translation id="4605958867780575332">Item removed: <ph name="ITEM_TITLE" /></translation> +<translation id="4616150815774728855">Open <ph name="WEBAPK_NAME" /></translation> +<translation id="4634124774493850572">Use password</translation> +<translation id="4645575059429386691">Managed by your parent</translation> +<translation id="4660011489602794167">Show keyboard</translation> +<translation id="4663756553811254707"><ph name="NUMBER_OF_BOOKMARKS" /> bookmarks deleted</translation> +<translation id="4665282149850138822"><ph name="NAME" /> was added to your Home screen</translation> +<translation id="4684427112815847243">Sync everything</translation> +<translation id="4695891336199304370">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}other{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}}</translation> +<translation id="4698034686595694889">View offline in <ph name="APP_NAME" /></translation> +<translation id="4698413471314543145">Critical functionality required to run Chrome is missing; either your Chrome installation is incomplete or not compatible with this version of Android.</translation> +<translation id="4699172675775169585">Cached images and files</translation> +<translation id="4714588616299687897">Save up to 60% of your data</translation> +<translation id="4719927025381752090">Offer to translate</translation> +<translation id="4720023427747327413">Open in <ph name="PRODUCT_NAME" /></translation> +<translation id="4720982865791209136">Help improve Chrome. <ph name="BEGIN_LINK" />Take survey<ph name="END_LINK" /></translation> +<translation id="4730876730346568982">You are switching sync accounts from <ph name="ACCOUNT_EMAIL_OLD" /> to <ph name="ACCOUNT_EMAIL_NEW" />. Your existing Chrome data is managed by <ph name="MANAGED_DOMAIN" />. This will delete your data from this device, but your data will remain in <ph name="ACCOUNT_EMAIL_OLD" />.</translation> +<translation id="473775607612524610">Update</translation> +<translation id="4738836084190194332">Last synced: <ph name="WHEN" /></translation> +<translation id="4749960740855309258">Open a new tab</translation> +<translation id="4751476147751820511">Motion or light sensors</translation> +<translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download complete.}other{# downloads complete.}}</translation> +<translation id="4766369052440583386">Data Saver is on</translation> +<translation id="4797039098279997504">Touch to return to <ph name="URL_OF_THE_CURRENT_TAB" /></translation> +<translation id="4807098396393229769">Name on card</translation> +<translation id="4807963036345170158">Data Saver is off</translation> +<translation id="4816465935029283692">Data types</translation> +<translation id="4837753911714442426">Open options to print page</translation> +<translation id="4842092870884894799">Showing password generation pop-up</translation> +<translation id="4850886885716139402">View</translation> +<translation id="4860895144060829044">Call</translation> +<translation id="4874967477260347223">Media Licenses</translation> +<translation id="4875775213178255010">Content Suggestions</translation> +<translation id="4878404682131129617">Establishing a tunnel via proxy server failed</translation> +<translation id="4881695831933465202">Open</translation> +<translation id="488187801263602086">Rename file</translation> +<translation id="4882831918239250449">Control how your browsing history is used to personalise Search, ads and more</translation> +<translation id="4883379392681899581">Leave private mode</translation> +<translation id="4885273946141277891">Unsupported number of Chrome instances.</translation> +<translation id="4910889077668685004">Payment apps</translation> +<translation id="4913161338056004800">Reset statistics</translation> +<translation id="4913169188695071480">Stop refreshing</translation> +<translation id="4915549754973153784"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /> while scanning for devices…</translation> +<translation id="4943872375798546930">No results</translation> +<translation id="4956460920135325549">Lite page delivered by Google.</translation> +<translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> is sharing your screen</translation> +<translation id="4961334780091921942">Your passwords, history & more on all devices</translation> +<translation id="4961700429721424617">You are signing out of an account managed by <ph name="MANAGED_DOMAIN" />. This will delete your Chrome data from this device, but your data will remain in your Google account.</translation> +<translation id="497421865427891073">go forward</translation> +<translation id="4988210275050210843">Downloading file (<ph name="MEGABYTES" />).</translation> +<translation id="4988526792673242964">Pages</translation> +<translation id="4996978546172906250">Share via</translation> +<translation id="5004339818306944878">Use up to 60% less data and speed up the web. Google servers will optimise the pages you visit.</translation> +<translation id="5004416275253351869">Google activity controls</translation> +<translation id="5005498671520578047">Copy password</translation> +<translation id="5011311129201317034"><ph name="SITE" /> wants to connect</translation> +<translation id="5013696553129441713">No new suggestions</translation> +<translation id="5016205925109358554">Serif</translation> +<translation id="5039804452771397117">Allow</translation> +<translation id="5040262127954254034">Privacy</translation> +<translation id="5063480226653192405">Usage</translation> +<translation id="5087580092889165836">Add card</translation> +<translation id="5100237604440890931">Collapsed – click to expand.</translation> +<translation id="510275257476243843">1 hour left</translation> +<translation id="5123685120097942451">Incognito tab</translation> +<translation id="5127805178023152808">Sync is off</translation> +<translation id="5129038482087801250">Install web app</translation> +<translation id="5139940364318403933">Learn how to use Google Drive</translation> +<translation id="515227803646670480">Clear stored data</translation> +<translation id="5152843274749979095">No supported apps installed</translation> +<translation id="5161254044473106830">Title required</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download failed.}other{# downloads failed.}}</translation> +<translation id="5168917394043976756">Open navigation drawer</translation> +<translation id="5171365962177408781">Tap to load the new tab page and view suggested articles</translation> +<translation id="5184329579814168207">Open in Chrome</translation> +<translation id="5199929503336119739">Work profile</translation> +<translation id="5210286577605176222">Jump to the previous tab</translation> +<translation id="5210365745912300556">Close tab</translation> +<translation id="5222676887888702881">Sign out</translation> +<translation id="5224771365102442243">With video</translation> +<translation id="5233638681132016545">New tab</translation> +<translation id="5240817131241497236">The settings that control sync, personalisation and other Google services in Chrome have changed. This may affect your current settings.</translation> +<translation id="5264003212305142034"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised at any time. Google may use content on sites that you visit, plus browser activity and interactions, to personalise Chrome and other Google services such as Translate, Search and ads.</translation> +<translation id="5271967389191913893">Device cannot open the content to be downloaded.</translation> +<translation id="528192093759286357">Drag from top and touch the back button to exit full screen.</translation> +<translation id="5284584623296338184">Changes to your bookmarks, history, passwords and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google account.</translation> +<translation id="5300589172476337783">Show</translation> +<translation id="5301954838959518834">OK, got it</translation> +<translation id="5304593522240415983">This field cannot be blank</translation> +<translation id="5308380583665731573">Connect</translation> +<translation id="5308603654685598744">When this feature is turned on, Chrome will offer to translate pages written in other languages using Google Translate.</translation> +<translation id="5313967007315987356">Add site</translation> +<translation id="5317780077021120954">Save</translation> +<translation id="5324858694974489420">Parental Settings</translation> +<translation id="5327248766486351172">Name</translation> +<translation id="5335288049665977812">Allow sites to run JavaScript (recommended)</translation> +<translation id="5345040418939504969">Deleted <ph name="BOOKMARK_TITLE" /></translation> +<translation id="5372829067651257087">URL copied.</translation> +<translation id="5391532827096253100">Your connection to this site is not secure. Site information</translation> +<translation id="5400569084694353794">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="5403644198645076998">Only allow certain sites</translation> +<translation id="5414836363063783498">Verifying…</translation> +<translation id="5423934151118863508">Your most visited pages will appear here</translation> +<translation id="5424588387303617268"><ph name="GIGABYTES" /> GB available</translation> +<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="5447765697759493033">This site will not be translated</translation> +<translation id="545042621069398927">Speeding up your download.</translation> +<translation id="5456381639095306749">Download page</translation> +<translation id="5466407412363861127">This feature uses <ph name="BEGIN_LINK" />sync<ph name="END_LINK" />.</translation> +<translation id="548278423535722844">Open in maps app</translation> +<translation id="5487521232677179737">Clear data</translation> +<translation id="5487729733663684359">Chrome updates are no longer supported for this version of Android.</translation> +<translation id="5494920125229734069">Select all</translation> +<translation id="550684401320795253">Updating Chrome...</translation> +<translation id="5512137114520586844">This account is managed by <ph name="PARENT_NAME" />.</translation> +<translation id="5514904542973294328">Disabled by the administrator of this device</translation> +<translation id="5515439363601853141">Unlock to view your password</translation> +<translation id="5515716148775388141">Your icons have moved to the bottom of the screen</translation> +<translation id="5517095782334947753">You have bookmarks, history, passwords and other settings from <ph name="FROM_ACCOUNT" />.</translation> +<translation id="5524843473235508879">Redirect blocked.</translation> +<translation id="5527082711130173040">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK1" />Update permissions<ph name="END_LINK1" />. Location access is also <ph name="BEGIN_LINK2" />turned off for this device<ph name="END_LINK2" />.</translation> +<translation id="5527111080432883924">Ask before allowing sites to read text and images from the clipboard (recommended)</translation> +<translation id="5530766185686772672">Close incognito tabs</translation> +<translation id="5534640966246046842">Site copied</translation> +<translation id="5537099431952529648">You and your parents can manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="5556459405103347317">Reload</translation> +<translation id="5561549206367097665">Waiting for network…</translation> +<translation id="557283862590186398">Chrome needs permission to access your microphone for this site.</translation> +<translation id="55737423895878184">Location and notifications are allowed</translation> +<translation id="5578795271662203820">Search <ph name="SEARCH_ENGINE" /> for this image</translation> +<translation id="5595485650161345191">Edit address</translation> +<translation id="5596627076506792578">More options</translation> +<translation id="5620299005957670886">Allow sites to access your sensors (recommended)</translation> +<translation id="5620928963363755975">Find your files and pages in Downloads from the More Options button</translation> +<translation id="5626134646977739690">Name:</translation> +<translation id="5639724618331995626">Allow all sites</translation> +<translation id="5648166631817621825">Last 7 days</translation> +<translation id="5655963694829536461">Search your downloads</translation> +<translation id="5659593005791499971">Email</translation> +<translation id="5665379678064389456">Create event in <ph name="APP_NAME" /></translation> +<translation id="5668404140385795438">Override a website’s request to prevent zooming in</translation> +<translation id="5676636989614905379">Cannot play video on <ph name="SCREEN_NAME" />.</translation> +<translation id="5677928146339483299">Blocked</translation> +<translation id="5684874026226664614">Oops. This page could not be translated.</translation> +<translation id="5686790454216892815">File name too long</translation> +<translation id="5689516760719285838">Location</translation> +<translation id="5719837394786370183">Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your incognito tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your Internet service provider or the websites you visit.</translation> +<translation id="572328651809341494">Recent tabs</translation> +<translation id="5726692708398506830">Make everything on the page bigger</translation> +<translation id="5738816946784116349">Chrome Downloads</translation> +<translation id="5748802427693696783">Switched to standard tabs</translation> +<translation id="5749068826913805084">Chrome needs storage access to download files.</translation> +<translation id="5763382633136178763">Incognito tabs</translation> +<translation id="5763514718066511291">Tap to copy the URL for this app</translation> +<translation id="5765780083710877561">Description:</translation> +<translation id="5777170031995031090">Control how Google uses your browsing history to personalise Search, ads and other Google services.</translation> +<translation id="5793665092639000975">Using <ph name="SPACE_USED" /> of <ph name="SPACE_AVAILABLE" /></translation> +<translation id="5804241973901381774">Permissions</translation> +<translation id="5809361687334836369">{HOURS,plural, =1{# hour ago}other{# hours ago}}</translation> +<translation id="5817918615728894473">Pair</translation> +<translation id="583281660410589416">Unknown</translation> +<translation id="5833397272224757657">Uses content on sites that you visit, plus browser activity and interactions, for personalisation</translation> +<translation id="5833984609253377421">Share link</translation> +<translation id="584427517463557805">Selected private tab</translation> +<translation id="5854790677617711513">Older than 30 days</translation> +<translation id="5858741533101922242">Chrome is unable to turn on Bluetooth adaptor</translation> +<translation id="5860033963881614850">Off</translation> +<translation id="5862731021271217234">To get your tabs from your other devices, turn on sync</translation> +<translation id="5864174910718532887">Details: Sorted by site name</translation> +<translation id="5864419784173784555">Waiting for another download…</translation> +<translation id="5865733239029070421">Automatically sends usage statistics and crash reports to Google</translation> +<translation id="5869522115854928033">Saved passwords</translation> +<translation id="5878455346526065919">Block ads from sites that tend to show intrusive ads</translation> +<translation id="5902828464777634901">All local data stored by this website, including cookies, will be deleted.</translation> +<translation id="5911030830365207728">Google Translate</translation> +<translation id="5916664084637901428">On</translation> +<translation id="5919204609460789179">Update <ph name="PRODUCT_NAME" /> to start sync</translation> +<translation id="5937580074298050696"><ph name="AMOUNT" /> saved</translation> +<translation id="5939518447894949180">Reset</translation> +<translation id="5942872142862698679">Using Google for search</translation> +<translation id="5952764234151283551">Sends the URL of a page that you're trying to reach to Google</translation> +<translation id="5956665950594638604">Open the Chrome Help Centre in a new tab</translation> +<translation id="5958275228015807058">Find your files and pages in Downloads</translation> +<translation id="5962718611393537961">Tap to collapse</translation> +<translation id="5990142338020175451">More personal Google services, such as better page suggestions</translation> +<translation id="6000066717592683814">Keep Google</translation> +<translation id="6005538289190791541">Suggested password</translation> +<translation id="6039379616847168523">Jump to the next tab</translation> +<translation id="6040143037577758943">Close</translation> +<translation id="6042308850641462728">More</translation> +<translation id="604996488070107836"><ph name="FILE_NAME" /> download failed due to an unknown error.</translation> +<translation id="605721222689873409">YY</translation> +<translation id="6075798973483050474">Edit home page</translation> +<translation id="60923314841986378"><ph name="HOURS" /> hours left</translation> +<translation id="60924377787140961">More articles will appear soon. Enjoy your afternoon!</translation> +<translation id="6099151465289169210">Switched to private tabs</translation> +<translation id="6108923351542677676">Setup in progress…</translation> +<translation id="6111020039983847643">data used</translation> +<translation id="6112702117600201073">Refreshing page</translation> +<translation id="6127379762771434464">Item removed</translation> +<translation id="6140912465461743537">Country/Region</translation> +<translation id="6154478581116148741">Turn on screen lock in Settings to export your passwords from this device</translation> +<translation id="6159335304067198720"><ph name="PERCENT" /> data savings</translation> +<translation id="6165508094623778733">Learn more</translation> +<translation id="6177111841848151710">Blocked for current search engine</translation> +<translation id="6177390657002841081">Turn on Data Saver</translation> +<translation id="6181444274883918285">Add site exception</translation> +<translation id="618993374665929060">More like this opened at full height</translation> +<translation id="6192333916571137726">Download File</translation> +<translation id="6192792657125177640">Exceptions</translation> +<translation id="6206551242102657620">Connection is secure. Site information</translation> +<translation id="6210748933810148297">Not <ph name="EMAIL" />?</translation> +<translation id="6216432067784365534"><ph name="NAME_OF_LIST_ITEM" /> Options</translation> +<translation id="6221633008163990886">Unlock to export your passwords</translation> +<translation id="6232535412751077445">Enabling “Do Not Track” means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request and how the request is interpreted. + +For example, some websites may respond to this request by showing you ads that aren’t based on other websites that you’ve visited. Many websites will still collect and use your browsing data – for example to improve security, to provide content, ads and recommendations and to generate reporting statistics.</translation> +<translation id="6255999984061454636">Content suggestions</translation> +<translation id="6277522088822131679">There was a problem printing the page. Please try again.</translation> +<translation id="6295158916970320988">All sites</translation> +<translation id="629730747756840877">Account</translation> +<translation id="6303969859164067831">Sign out and turn off sync</translation> +<translation id="6320088164292336938">Vibrate</translation> +<translation id="6324034347079777476">Android system sync disabled</translation> +<translation id="6333140779060797560">Share via <ph name="APPLICATION" /></translation> +<translation id="6336451774241870485">New private tab</translation> +<translation id="6337234675334993532">Encryption</translation> +<translation id="6341580099087024258">Ask where to save files</translation> +<translation id="6343192674172527289">No downloads found</translation> +<translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}}</translation> +<translation id="6364438453358674297">Remove suggestion from history?</translation> +<translation id="6378173571450987352">Details: Sorted by amount of data used</translation> +<translation id="6383961787135158834">Clear Site Storage…</translation> +<translation id="6388207532828177975">Clear & reset</translation> +<translation id="6393863479814692971">Chrome needs permission to access your camera and microphone for this site.</translation> +<translation id="6395288395575013217">LINK</translation> +<translation id="6404511346730675251">Edit bookmark</translation> +<translation id="6406506848690869874">Sync</translation> +<translation id="641643625718530986">Print…</translation> +<translation id="6416782512398055893">Downloaded <ph name="MBS" /> MB</translation> +<translation id="6433501201775827830">Choose your search engine</translation> +<translation id="6437478888915024427">Page info</translation> +<translation id="6447842834002726250">Cookies</translation> +<translation id="6448273550210938826">Search and URL suggestions</translation> +<translation id="6461962085415701688">Can’t open file</translation> +<translation id="6475951671322991020">Download video</translation> +<translation id="6482749332252372425"><ph name="FILE_NAME" /> download failed due to lack of storage space.</translation> +<translation id="6496823230996795692">To use <ph name="APP_NAME" /> for the first time, please connect to the Internet.</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6534565668554028783">Google took too long to respond</translation> +<translation id="6538442820324228105">Downloaded <ph name="GBS" /> GB</translation> +<translation id="654446541061731451">Select a tab to beam</translation> +<translation id="6545017243486555795">Clear All Data</translation> +<translation id="6556716549745717622">Block if site tends to show intrusive ads (recommended)</translation> +<translation id="6560414384669816528">Search with Sogou</translation> +<translation id="6566259936974865419">Chrome has saved you <ph name="GIGABYTES" /> GB</translation> +<translation id="6573096386450695060">Always allow</translation> +<translation id="6573431926118603307">Tabs that you've opened in Chrome on your other devices will appear here.</translation> +<translation id="6575643671698722332">Reset failed. Ensure that your device is online and try again.</translation> +<translation id="6583199322650523874">Bookmark the current page</translation> +<translation id="6584721918629302382">AR</translation> +<translation id="6593061639179217415">Desktop site</translation> +<translation id="6600954340915313787">Copied to Chrome</translation> +<translation id="6608650720463149374"><ph name="GIGABYTES" /> GB</translation> +<translation id="6610147964972079463">Close private tabs</translation> +<translation id="6612358246767739896">Protected content</translation> +<translation id="6627583120233659107">Edit folder</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6643649862576733715">Sort by amount of data saved</translation> +<translation id="6648977384226967773">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}other{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}}</translation> +<translation id="6656545060687952787">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK" />Update permissions<ph name="END_LINK" /></translation> +<translation id="6657585470893396449">Password</translation> +<translation id="6659594942844771486">Tab</translation> +<translation id="666268767214822976">Use a prediction service to show related queries and popular websites as you type in the address bar</translation> +<translation id="666731172850799929">Open in <ph name="APP_NAME" /></translation> +<translation id="666981079809192359">Chrome Privacy Notice</translation> +<translation id="6697492270171225480">Show suggestions for similar pages when a page can't be found</translation> +<translation id="6697947395630195233">Chrome needs access to your location to share your location with this site.</translation> +<translation id="6698801883190606802">Manage synced data</translation> +<translation id="6710213216561001401">Previous</translation> +<translation id="6712388303105732168">See more like this from Google using the More Like This button</translation> +<translation id="6738867403308150051">Downloading…</translation> +<translation id="6746124502594467657">Move down</translation> +<translation id="6762156594045689028">To change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="6766622839693428701">Swipe down to close.</translation> +<translation id="6770414673596662518">Chrome’s Safe Browsing system will also be used to detect malicious pages and protect you from phishing, malware and harmful downloads.</translation> +<translation id="6776813977906306442">Download videos to watch later using the Download button</translation> +<translation id="6790428901817661496">Play</translation> +<translation id="679325081238418596">Get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="6820607729870073286">You have no saved website settings.</translation> +<translation id="6820686453637990663">CVC</translation> +<translation id="6831043979455480757">Translate</translation> +<translation id="6846298663435243399">Loading…</translation> +<translation id="685040365210406336">Make no changes</translation> +<translation id="6850409657436465440">Your download is still in progress</translation> +<translation id="6850830437481525139"><ph name="TAB_COUNT" /> tabs closed</translation> +<translation id="6864459304226931083">Download image</translation> +<translation id="6865313869410766144">Autofill form data</translation> +<translation id="6868088497967843822">Sign in to get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="688738109438487280">Add existing data to <ph name="TO_ACCOUNT" />.</translation> +<translation id="6891726759199484455">Unlock to copy your password</translation> +<translation id="6891858906296486776">{OPEN_TABS,plural, =1{%1$d open tab}other{%1$d open tabs}}</translation> +<translation id="6896758677409633944">Copy</translation> +<translation id="6910211073230771657">Deleted</translation> +<translation id="6912998170423641340">Block sites from reading text and images from the clipboard</translation> +<translation id="6914783257214138813">Your passwords will be visible to anyone who can see the exported file.</translation> +<translation id="6942665639005891494">Change the default download location at any time using the Settings menu option</translation> +<translation id="6945221475159498467">Select</translation> +<translation id="6963642900430330478">This page is dangerous. Site information</translation> +<translation id="6963766334940102469">Delete bookmarks</translation> +<translation id="6965382102122355670">OK</translation> +<translation id="6978479750597523876">Reset translate settings</translation> +<translation id="6979737339423435258">All time</translation> +<translation id="6981982820502123353">Accessibility</translation> +<translation id="6985347914332179298">No downloads here</translation> +<translation id="6990079615885386641">Get the app from the Google Play Store: <ph name="APP_ACTION" /></translation> +<translation id="699220179437400583">Automatically report details of possible security incidents to Google</translation> +<translation id="6992289844737586249">Ask first before allowing sites to use your microphone (recommended)</translation> +<translation id="7016516562562142042">Allowed for current search engine</translation> +<translation id="7021515813996758557"><ph name="FILE_NAME" /> downloaded</translation> +<translation id="7022756207310403729">Open in browser</translation> +<translation id="702463548815491781">Recommended when TalkBack or Switch Access are on</translation> +<translation id="7029809446516969842">Passwords</translation> +<translation id="7031882061095297553">Sync to</translation> +<translation id="7032663816368481562">When you tap More like this <ph name="ICON" /> in the address bar, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="7034608350006174882">Cards and addresses using Google Pay</translation> +<translation id="7053983685419859001">Block</translation> +<translation id="7055152154916055070">Redirect blocked:</translation> +<translation id="7062545763355031412">Accept and switch accounts</translation> +<translation id="7063006564040364415">Could not connect to the sync server.</translation> +<translation id="7066151586745993502">{NUM_SELECTED,plural, =1{1 selected}other{# selected}}</translation> +<translation id="7077143737582773186">SD Card</translation> +<translation id="7087918508125750058"><ph name="ITEM_COUNT" /> selected. Options available near top of the screen</translation> +<translation id="7108338896283013870">Hide</translation> +<translation id="7121362699166175603">Clears history and autocompletions in the address bar. 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="7128222689758636196">Allow for current search engine</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7139148793369023665">More like this closed</translation> +<translation id="7141896414559753902">Block sites from showing pop-ups and redirects (recommended)</translation> +<translation id="7149158118503947153"><ph name="BEGIN_LINK" />Load original page<ph name="END_LINK" /> from <ph name="DOMAIN_NAME" /></translation> +<translation id="7149893636342594995">Last 24 Hours</translation> +<translation id="7176368934862295254"><ph name="KILOBYTES" /> KB</translation> +<translation id="7177466738963138057">You can change this later in Settings</translation> +<translation id="7180611975245234373">Refresh</translation> +<translation id="7189372733857464326">Waiting for Google Play Services to finish updating</translation> +<translation id="7189598951263744875">Share...</translation> +<translation id="7191430249889272776">Tab opened in background.</translation> +<translation id="723171743924126238">Select images</translation> +<translation id="7243308994586599757">Options available near bottom of the screen</translation> +<translation id="7250468141469952378"><ph name="ITEM_COUNT" /> selected</translation> +<translation id="7251326866581677552">Blocked from some sites</translation> +<translation id="7253272406652746122">Add a Google account from the Accounts page in your device’s Settings app.</translation> +<translation id="7274013316676448362">Blocked site</translation> +<translation id="729975465115245577">Your device doesn’t have an app to store the passwords file.</translation> +<translation id="7302081693174882195">Details: Sorted by amount of data saved</translation> +<translation id="7333031090786104871">Still adding previous site</translation> +<translation id="7352939065658542140">VIDEO</translation> +<translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Share 1 selected item}other{Share # selected items}}</translation> +<translation id="7359002509206457351">Access payment methods</translation> +<translation id="7366340029385295517">Casting to <ph name="SCREEN_NAME" /></translation> +<translation id="7375125077091615385">Type:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> +<translation id="7400418766976504921">URL</translation> +<translation id="7403691278183511381">Chrome First Run Experience</translation> +<translation id="741204030948306876">Yes, I'm in</translation> +<translation id="7413229368719586778">Start date <ph name="DATE" /></translation> +<translation id="7423098979219808738">Ask first</translation> +<translation id="7423538860840206698">Blocked from reading clipboard</translation> +<translation id="7431991332293347422">Control how your browsing history is used to personalise Search and more</translation> +<translation id="7437998757836447326">Sign out of Chrome</translation> +<translation id="7444811645081526538">More categories</translation> +<translation id="7445411102860286510">Allow sites to automatically play muted videos (recommended)</translation> +<translation id="7454641608352164238">Not enough space</translation> +<translation id="7455923816558154057">Tap to view</translation> +<translation id="7465104139234185284">Close all private tabs</translation> +<translation id="7473891865547856676">No Thanks</translation> +<translation id="7475192538862203634">If you’re seeing this frequently, try these <ph name="BEGIN_LINK" />suggestions<ph name="END_LINK" />.</translation> +<translation id="7475688122056506577">SD card not found. Some of your files may be missing.</translation> +<translation id="748127970106343339">Confirm device credential deletion</translation> +<translation id="7481312909269577407">Forward</translation> +<translation id="7493994139787901920"><ph name="VERSION" /> (Updated <ph name="TIME_SINCE_UPDATE" />)</translation> +<translation id="7494879913343971937">Show passwords</translation> +<translation id="7494974237137038751">data saved</translation> +<translation id="7498271377022651285">Please wait…</translation> +<translation id="7514365320538308">Download</translation> +<translation id="751961395872307827">Can't connect to the site</translation> +<translation id="7521387064766892559">JavaScript</translation> +<translation id="7542481630195938534">Can’t get suggestions</translation> +<translation id="7562080006725997899">Clear browsing data</translation> +<translation id="756809126120519699">Cleared Chrome data</translation> +<translation id="757524316907819857">Block sites from playing protected content</translation> +<translation id="7589445247086920869">Block for current search engine</translation> +<translation id="7593557518625677601">Open Android settings and re-enable Android system sync to start Chrome sync</translation> +<translation id="7596558890252710462">Operating system</translation> +<translation id="7605594153474022051">Sync isn't working</translation> +<translation id="7612619742409846846">Signed in to Google as</translation> +<translation id="7619072057915878432"><ph name="FILE_NAME" /> download failed due to network failures.</translation> +<translation id="7624880197989616768"><ph name="BEGIN_LINK1" />Get help<ph name="END_LINK1" /> or <ph name="BEGIN_LINK2" />re-scan<ph name="END_LINK2" /></translation> +<translation id="7626032353295482388">Welcome to Chrome</translation> +<translation id="7638584964844754484">Incorrect passphrase</translation> +<translation id="7641339528570811325">Clear browsing data…</translation> +<translation id="7648422057306047504">Encrypt passwords with Google credentials</translation> +<translation id="7649070708921625228">Help</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7665369617277396874">Add account</translation> +<translation id="7682724950699840886">Try the following tips: make sure that there is enough space on your device; try to export again.</translation> +<translation id="7698359219371678927">Create email in <ph name="APP_NAME" /></translation> +<translation id="7704317875155739195">Auto-complete searches and URLs</translation> +<translation id="773466115871691567">Always translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> +<translation id="773905249182896430">Protects you and your device from dangerous sites</translation> +<translation id="7762668264895820836">SD Card <ph name="SD_CARD_NUMBER" /></translation> +<translation id="7764225426217299476">Add address</translation> +<translation id="7765158879357617694">Move</translation> +<translation id="7769602470925380267">Accept and sign out</translation> +<translation id="7772032839648071052">Confirm passphrase</translation> +<translation id="7774809984919390718">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}other{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}}</translation> +<translation id="7781829728241885113">Yesterday</translation> +<translation id="7791543448312431591">Add</translation> +<translation id="780301667611848630">No, thank you</translation> +<translation id="7810647596859435254">Open with…</translation> +<translation id="7821588508402923572">Your data savings will appear here</translation> +<translation id="7832327313660264358">The data that you sync to Google and the features that you use will not change</translation> +<translation id="7837721118676387834">Allow auto-play of muted videos for a specific site.</translation> +<translation id="7846076177841592234">Cancel selection</translation> +<translation id="784934925303690534">Time range</translation> +<translation id="7851858861565204677">Other Devices</translation> +<translation id="7854964836418414587">Close more like this</translation> +<translation id="7875915731392087153">Create email</translation> +<translation id="7876243839304621966">Remove all</translation> +<translation id="7882131421121961860">No history found</translation> +<translation id="7882806643839505685">Allow sound for a specific site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Downloading file.}other{Downloading # files.}}</translation> +<translation id="7929962904089429003">Opening the menu</translation> +<translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> is out of date.</translation> +<translation id="7947953824732555851">Accept and sign in</translation> +<translation id="7963646190083259054">Vendor:</translation> +<translation id="7981313251711023384">Preload pages for faster browsing and searching</translation> +<translation id="79859296434321399">To view augmented reality content, install ARCore</translation> +<translation id="7986741934819883144">Select a contact</translation> +<translation id="7987073022710626672">Chrome Terms of Service</translation> +<translation id="7987764905897278458">Get more Google smarts</translation> +<translation id="7998918019931843664">Re-open closed tab</translation> +<translation id="7999064672810608036">Are you sure that you want to clear all local data, including cookies, and reset all permissions for this website?</translation> +<translation id="8004582292198964060">Browser</translation> +<translation id="8007176423574883786">Turned off for this device</translation> +<translation id="8015452622527143194">Return everything on the page to default size</translation> +<translation id="802154636333426148">Download failed</translation> +<translation id="8026334261755873520">Clear browsing data</translation> +<translation id="8035133914807600019">New folder…</translation> +<translation id="8037411810184515274">VR</translation> +<translation id="8037686209485537503">More like this</translation> +<translation id="8037750541064988519"><ph name="DAYS" /> days left</translation> +<translation id="804335162455518893">SD card not found</translation> +<translation id="805047784848435650">Based on your browsing history</translation> +<translation id="8051695050440594747"><ph name="MEGABYTES" /> MB available</translation> +<translation id="8058746566562539958">Open in new Chrome tab</translation> +<translation id="8063895661287329888">Failed to add bookmark.</translation> +<translation id="806745655614357130">Keep my data separate</translation> +<translation id="8068648041423924542">Unable to select certificate.</translation> +<translation id="8073388330009372546">Open image in new tab</translation> +<translation id="8084114998886531721">Saved password</translation> +<translation id="8087000398470557479">This content is from <ph name="DOMAIN_NAME" />, delivered by Google.</translation> +<translation id="8103578431304235997">Incognito Tab</translation> +<translation id="8105951947646329362">Suggest related pages</translation> +<translation id="8109613176066109935">To get your bookmarks on all your devices, turn on sync</translation> +<translation id="8116925261070264013">Muted</translation> +<translation id="813082847718468539">View site information</translation> +<translation id="8156139159503939589">What languages do you read?</translation> +<translation id="8168435359814927499">Content</translation> +<translation id="8186512483418048923"><ph name="FILES" /> files left</translation> +<translation id="8190358571722158785">1 day left</translation> +<translation id="8200772114523450471">Resume</translation> +<translation id="8209050860603202033">Open image</translation> +<translation id="8220488350232498290"><ph name="GIGABYTES" /> GB downloaded</translation> +<translation id="8249310407154411074">Move to top</translation> +<translation id="8250920743982581267">Documents</translation> +<translation id="825412236959742607">This page uses too much memory, so Chrome removed some content.</translation> +<translation id="8260126382462817229">Try signing in again</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8266862848225348053">Download location</translation> +<translation id="8274165955039650276">See downloads</translation> +<translation id="8283853025636624853">Syncing to <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8310344678080805313">Standard tabs</translation> +<translation id="8313455859591948645">Edit startup page</translation> +<translation id="8316092324682955408"><ph name="DOMAIN_NAME" /> and more sites</translation> +<translation id="8339163506404995330">Pages in <ph name="LANGUAGE" /> will not be translated</translation> +<translation id="8349013245300336738">Sort by amount of data used</translation> +<translation id="8372893542064058268">Allow Background Sync for a specific site.</translation> +<translation id="8374821112118309944">You need to update TalkBack to a newer version.</translation> +<translation id="8393700583063109961">Send message</translation> +<translation id="8413126021676339697">Show full history</translation> +<translation id="8428213095426709021">Settings</translation> +<translation id="8438566539970814960">Make searches and browsing better</translation> +<translation id="8441146129660941386">Seek backward</translation> +<translation id="8445448999790540984">Can’t export passwords</translation> +<translation id="8447861592752582886">Revoke device permission</translation> +<translation id="8477071352266846533">Sync off for <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8487700953926739672">Available offline</translation> +<translation id="8489271220582375723">Open the history page</translation> +<translation id="8493948351860045254">Free up space</translation> +<translation id="8497726226069778601">Nothing to see here… yet</translation> +<translation id="8503559462189395349">Chrome Passwords</translation> +<translation id="8503813439785031346">Username</translation> +<translation id="8504988642345501642">When you scroll up, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="8507520749471379845">Passwords available</translation> +<translation id="8514477925623180633">Export passwords stored with Chrome</translation> +<translation id="8514577642972634246">Enter incognito mode</translation> +<translation id="851751545965956758">Block sites from connecting to devices</translation> +<translation id="8523928698583292556">Delete stored password</translation> +<translation id="854522910157234410">Open this page:</translation> +<translation id="8558485628462305855">To view augmented reality content, update ARCore</translation> +<translation id="8559990750235505898">Offer to translate pages in other languages</translation> +<translation id="8562452229998620586">Your saved passwords will appear here.</translation> +<translation id="8569404424186215731">since <ph name="DATE" /></translation> +<translation id="8571213806525832805">Last 4 weeks</translation> +<translation id="857509777403223202">More articles will appear soon. Enjoy your evening!</translation> +<translation id="857943718398505171">Allowed (recommended)</translation> +<translation id="8583805026567836021">Clearing account data</translation> +<translation id="8609465669617005112">Move up</translation> +<translation id="8616006591992756292">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="8617240290563765734">Open the suggested URL specified in the downloaded content?</translation> +<translation id="862875433388403934">Content (films, music, etc.) downloaded in other applications may no longer be playable until those applications re-acquire licences based on a new device credential. To obtain new licences, connect to the Internet and play your downloaded content.</translation> +<translation id="8636825310635137004">To get your tabs from your other devices, turn on sync.</translation> +<translation id="8641930654639604085">Try to block mature sites</translation> +<translation id="8662811608048051533">Signs you out of most sites.</translation> +<translation id="8664979001105139458">File name already exists</translation> +<translation id="8676374126336081632">Clear input</translation> +<translation id="8687353297350450808">{N_BARS,plural, =1{Signal Strength Level: # bar}other{Signal Strength Level: # bars}}</translation> +<translation id="868929229000858085">Search your contacts</translation> +<translation id="869891660844655955">Expiry date</translation> +<translation id="8719023831149562936">Can’t beam current tab</translation> +<translation id="8725066075913043281">Try again</translation> +<translation id="8728487861892616501">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8730621377337864115">Done</translation> +<translation id="8748850008226585750">Contents hidden</translation> +<translation id="8751914237388039244">Select an image</translation> +<translation id="8788968922598763114">Reopen the last closed tab</translation> +<translation id="8812260976093120287">On some websites, you can pay with above supported payment apps on your device.</translation> +<translation id="8816439037877937734"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome's <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8820817407110198400">Bookmarks</translation> +<translation id="8823704566850948458">Suggest password...</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> +<translation id="883806473910249246">An error occurred while downloading the content.</translation> +<translation id="8840953339110955557">This page may differ from the online version.</translation> +<translation id="8847988622838149491">USB</translation> +<translation id="8853345339104747198"><ph name="TAB_TITLE" />, tab</translation> +<translation id="885701979325669005">Storage</translation> +<translation id="8901170036886848654">No bookmarks found</translation> +<translation id="8909135823018751308">Share…</translation> +<translation id="8912362522468806198">Google Account</translation> +<translation id="8920114477895755567">Waiting for details of parents.</translation> +<translation id="8922289737868596582">Download pages from the More Options button to use them offline</translation> +<translation id="8941729603749328384">www.example.com</translation> +<translation id="8942627711005830162">Open in other window</translation> +<translation id="8951232171465285730">Chrome has saved you <ph name="MEGABYTES" /> MB</translation> +<translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> +<translation id="8972098258593396643">Download to default folder?</translation> +<translation id="8979405271719829084">Download videos to watch later</translation> +<translation id="8981454092730389528">Google Activity Controls</translation> +<translation id="8983677657449185470">Help improve Safe Browsing</translation> +<translation id="8986494364107987395">Automatically send usage statistics and crash reports to Google</translation> +<translation id="8993760627012879038">Open a new tab in Incognito mode</translation> +<translation id="8998729206196772491">You are signing in with an account managed by <ph name="MANAGED_DOMAIN" /> and giving its administrator control over your Chrome data. Your data will become permanently tied to this account. Signing out of Chrome will delete your data from this device, but it will remain stored in your Google account.</translation> +<translation id="9019902583201351841">Managed by your parents</translation> +<translation id="9040142327097499898">Notifications are allowed. Location is off for this device.</translation> +<translation id="9050666287014529139">Passphrase</translation> +<translation id="9060538597317784206">View app <ph name="APP_NAME" /> on the Play Store. Rating: <ph name="APP_RATING" />.</translation> +<translation id="9063523880881406963">Turn off Request desktop site</translation> +<translation id="9065203028668620118">Edit</translation> +<translation id="9070377983101773829">Start voice search</translation> +<translation id="9071742570345586758">To view virtual reality content, install Google VR Services</translation> +<translation id="9074336505530349563">To get personalised content suggested by Google, sign in and turn on sync</translation> +<translation id="9080642952018487277">Enter private mode</translation> +<translation id="9086455579313502267">Unable to access the network</translation> +<translation id="9099018167121903954"><ph name="KILOBYTES" /> KB downloaded</translation> +<translation id="9100505651305367705">Offer to show articles in simplified view, when supported</translation> +<translation id="9100610230175265781">Passphrase required</translation> +<translation id="9100939710791843300">Tap the home button to load the new tab page and view suggested articles</translation> +<translation id="9133515669113036225">Reset device credentials</translation> +<translation id="9133703968756164531"><ph name="ITEM_NAME" /> (<ph name="ITEM_ID" />)</translation> +<translation id="9137013805542155359">Show original</translation> +<translation id="9139068048179869749">Ask before allowing sites to send notifications (recommended)</translation> +<translation id="9155898266292537608">You can also search with a quick tap on a word</translation> +<translation id="9188680907066685419">Sign out of managed account</translation> +<translation id="9204836675896933765">1 file left</translation> +<translation id="9206873250291191720">A</translation> +<translation id="9218033835049520260">Suggest strong password...</translation> +<translation id="9219103736887031265">Images</translation> +<translation id="932327136139879170">Home</translation> +<translation id="932599481871055447">Save data and browse faster</translation> +<translation id="938850635132480979">Error: <ph name="ERROR_CODE" /></translation> +<translation id="945522503751344254">Send feedback</translation> +<translation id="945632385593298557">Access your microphone</translation> +<translation id="951339005376969845">Delete existing data. You can retrieve it by switching back to <ph name="FROM_ACCOUNT" />.</translation> +<translation id="95817756606698420">Chrome can use <ph name="BEGIN_BOLD" />Sogou<ph name="END_BOLD" /> for search in China. You can change this in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="970715775301869095"><ph name="MINUTES" /> mins left</translation> +<translation id="974555521953189084">Enter your passphrase to start sync</translation> +<translation id="981121421437150478">Offline</translation> +<translation id="982182592107339124">This will clear data for all sites, including:</translation> +<translation id="983192555821071799">Close all tabs</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_kn.xtb b/chrome/android/java/strings/translations/android_chrome_strings_kn.xtb new file mode 100644 index 0000000..976c78f --- /dev/null +++ b/chrome/android/java/strings/translations/android_chrome_strings_kn.xtb
@@ -0,0 +1,1056 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="kn"> +<translation id="1006017844123154345">Open Online</translation> +<translation id="1036727731225946849">Adding <ph name="WEBAPK_NAME" />...</translation> +<translation id="1041308826830691739">From websites</translation> +<translation id="1049743911850919806">Incognito</translation> +<translation id="1054301162707478098">You’ve gone private.</translation> +<translation id="10614374240317010">Never saved</translation> +<translation id="1067922213147265141">Other Google services</translation> +<translation id="1068672505746868501">Never translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="10713315585330490"><ph name="FILE_SIZE" /> – <ph name="DESCRIPTION" /></translation> +<translation id="1080790410959514870">You are signing out of an account managed by <ph name="DOMAIN_NAME" />. This will delete the Chrome data stored on this device, but the data will remain in your Google Account.</translation> +<translation id="1105960400813249514">Screen Capture</translation> +<translation id="1111673857033749125">Bookmarks saved on your other devices will appear here.</translation> +<translation id="1113597929977215864">Show simplified view</translation> +<translation id="1121094540300013208">Usage and crash reports</translation> +<translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download pending.}other{# downloads pending.}}</translation> +<translation id="1145536944570833626">Delete existing data.</translation> +<translation id="1146678959555564648">Enter VR</translation> +<translation id="114721135501989771">Get Google smarts in Chrome</translation> +<translation id="1157102636231978136">Your browsing data and activity, synced to your Google account</translation> +<translation id="116280672541001035">Used</translation> +<translation id="1172593791219290334">Startup Page</translation> +<translation id="1175310183703641346">Your bookmarks, history, passwords and more will no longer be synced to your Google account</translation> +<translation id="1178581264944972037">Pause</translation> +<translation id="1181037720776840403">Remove</translation> +<translation id="1197267115302279827">Move bookmarks</translation> +<translation id="119944043368869598">Clear all</translation> +<translation id="1201402288615127009">Next</translation> +<translation id="1204037785786432551">Download link</translation> +<translation id="1206892813135768548">Copy link text</translation> +<translation id="1208340532756947324">To sync and personalise across devices, turn on sync</translation> +<translation id="1209206284964581585">Hide for now</translation> +<translation id="123724288017357924">Reload the current page, ignoring cached content</translation> +<translation id="124116460088058876">More languages</translation> +<translation id="124678866338384709">Close current tab</translation> +<translation id="1258753120186372309">Google doodle: <ph name="DOODLE_DESCRIPTION" /></translation> +<translation id="1259100630977430756">Pages that you view in private tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your private tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going private doesn’t hide your browsing from your employer, your Internet service provider or the websites that you visit.</translation> +<translation id="127138278192656016">Use sync and all services</translation> +<translation id="1272079795634619415">Stop</translation> +<translation id="1283039547216852943">Tap to expand</translation> +<translation id="1285320974508926690">Never translate this site</translation> +<translation id="1291207594882862231">Clear history, cookies, site data, cache…</translation> +<translation id="129553762522093515">Recently closed</translation> +<translation id="1326317727527857210">To get your tabs from your other devices, sign in to Chrome.</translation> +<translation id="1332501820983677155">Google Chrome feature shortcuts</translation> +<translation id="1360432990279830238">Sign out and turn off sync?</translation> +<translation id="136248372334525878">Preload pages for faster loading and offline reading</translation> +<translation id="1369915414381695676">Site <ph name="SITE_NAME" /> added</translation> +<translation id="1373696734384179344">Insufficient memory to download the selected content.</translation> +<translation id="1376578503827013741">Computing…</translation> +<translation id="138361230106469022">Hi, <ph name="FULL_NAME" /></translation> +<translation id="1383876407941801731">Search</translation> +<translation id="1384959399684842514">Download paused</translation> +<translation id="1389974829397082527">No bookmarks here</translation> +<translation id="1397811292916898096">Search with <ph name="PRODUCT_NAME" /></translation> +<translation id="1397854323885047133">Sync and personalisation</translation> +<translation id="1404122904123200417">Embedded in <ph name="WEBSITE_URL" /></translation> +<translation id="1406000523432664303">“Do Not Track”</translation> +<translation id="1407135791313364759">Open all</translation> +<translation id="1409426117486808224">Simplified view for open tabs</translation> +<translation id="1409879593029778104"><ph name="FILE_NAME" /> download prevented because file already exists.</translation> +<translation id="1414981605391750300">Contacting Google. This may take a minute…</translation> +<translation id="1416550906796893042">Application version</translation> +<translation id="1430915738399379752">Print</translation> +<translation id="1445680696957526815">Chrome’s components are incompatible with one another. Chrome may be upgrading, please try again in a few minutes. If the problem continues, try uninstalling and re-installing Chrome.</translation> +<translation id="1446450296470737166">Allow full control of MIDI devices</translation> +<translation id="145097072038377568">Turned off in Android Settings</translation> +<translation id="1477626028522505441"><ph name="FILE_NAME" /> download failed due to server issues.</translation> +<translation id="1506061864768559482">Search engine</translation> +<translation id="1513352483775369820">Bookmarks and web history</translation> +<translation id="1513858653616922153">Delete password</translation> +<translation id="1516229014686355813">Tap to Search sends the selected word and the current page as context to Google Search. You can turn it off in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="1539064842193522527">Link opened in Chrome</translation> +<translation id="1549000191223877751">Move to other window</translation> +<translation id="1553358976309200471">Update Chrome</translation> +<translation id="1566400915470565838">To use <ph name="APP_NAME" />, please connect to the Internet.</translation> +<translation id="1569387923882100876">Connected device</translation> +<translation id="1571304935088121812">Copy username</translation> +<translation id="1576370611341449972">Download occurs only on Wi-Fi</translation> +<translation id="1612196535745283361">Chrome needs location access to scan for devices. Location access is <ph name="BEGIN_LINK" />turned off for this device<ph name="END_LINK" />.</translation> +<translation id="162035744160882748">Turn on sync, personalisation and other Google services</translation> +<translation id="1620510694547887537">Camera</translation> +<translation id="1623104350909869708">Prevent this page from creating additional dialogues</translation> +<translation id="1628019612362412531">{NUM_SELECTED,plural, =1{Remove 1 selected item}other{Remove # selected items}}</translation> +<translation id="1641113438599504367">Safe Browsing</translation> +<translation id="164269334534774161">You are viewing an offline copy of this page from <ph name="CREATION_TIME" /></translation> +<translation id="1644574205037202324">History</translation> +<translation id="1647391597548383849">Access your camera</translation> +<translation id="1660204651932907780">Allow sites to play sound (recommended)</translation> +<translation id="1670399744444387456">Basic</translation> +<translation id="1671236975893690980">Download pending...</translation> +<translation id="1672586136351118594">Don‘t show again</translation> +<translation id="1709438864123551175">Data Saver</translation> +<translation id="1718835860248848330">Last hour</translation> +<translation id="1729516292547892356">To view virtual reality content, update Google VR Services</translation> +<translation id="1733116627827457509"><ph name="FILE_SIZE" /> – Updated <ph name="TIME_SINCE_UPDATE" /></translation> +<translation id="1736419249208073774">Explore</translation> +<translation id="1743802530341753419">Ask before allowing sites to connect to a device (recommended)</translation> +<translation id="1749561566933687563">Sync your bookmarks</translation> +<translation id="17513872634828108">Open tabs</translation> +<translation id="1756600373018374892">Tap this button for quick access to your tabs.</translation> +<translation id="1779089405699405702">Image decoder</translation> +<translation id="1782483593938241562">End date <ph name="DATE" /></translation> +<translation id="1792959175193046959">Change the default download location at any time</translation> +<translation id="1807246157184219062">Light</translation> +<translation id="1821253160463689938">Uses cookies to remember your preferences, even if you don't visit those pages</translation> +<translation id="1829244130665387512">Find in page</translation> +<translation id="1832521218263067499">Security incidents</translation> +<translation id="1853692000353488670">New incognito tab</translation> +<translation id="1868024384445905608">Chrome now downloads files faster</translation> +<translation id="1878302395768190018">You can customise this at any time in Chrome Settings</translation> +<translation id="1880072593381090678">Popular pages from Chrome</translation> +<translation id="1883903952484604915">My files</translation> +<translation id="1887786770086287077">Location access is off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1891331835972267886"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="189172778771606813">Close navigation drawer</translation> +<translation id="1919345977826869612">Ads</translation> +<translation id="1919950603503897840">Select contacts</translation> +<translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/<ph name="FILE_SIZE_WITH_UNITS" /></translation> +<translation id="1933845786846280168">Selected Tab</translation> +<translation id="1938981467853765413">Provide feedback</translation> +<translation id="194341124344773587">Turn on permission for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1943432128510653496">Save passwords</translation> +<translation id="1944384637046898011">Encrypt all with Google password as of <ph name="TIME" /></translation> +<translation id="1946005195648379376">Control how Google uses your browsing history to personalise Search and other Google services.</translation> +<translation id="1952172573699511566">Websites will show text in your preferred language, when possible.</translation> +<translation id="195283394249132567">Personalised Google services</translation> +<translation id="1966710179511230534">Please update your sign-in details.</translation> +<translation id="1974060860693918893">Advanced</translation> +<translation id="1984937141057606926">Allowed, except third-party</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> button</translation> +<translation id="1989112275319619282">Browse</translation> +<translation id="1993768208584545658"><ph name="SITE" /> wants to pair</translation> +<translation id="1994173015038366702">Site URL</translation> +<translation id="2000419248597011803">Sends some cookies and searches from the address bar and search box to your default search engine</translation> +<translation id="2002537628803770967">Credit cards and addresses using Google Pay</translation> +<translation id="200815880754187296"><ph name="KILOBYTES" /> KB other apps</translation> +<translation id="2017836877785168846">Clears history and autocompletions in the address bar.</translation> +<translation id="2021896219286479412">Full screen site controls</translation> +<translation id="2038563949887743358">Turn on Request desktop site</translation> +<translation id="2045104531052923016"><ph name="GIGABYTES" /> GB other apps</translation> +<translation id="2063713494490388661">Tap to Search</translation> +<translation id="2079545284768500474">Undo</translation> +<translation id="2082238445998314030">Result <ph name="RESULT_NUMBER" /> of <ph name="TOTAL_RESULTS" /></translation> +<translation id="2086652334978798447">To get personalised content suggested by Google, sign in to Chrome.</translation> +<translation id="2091887806945687916">Sound</translation> +<translation id="2095887075102408547">When this feature is turned on, Chrome will use Google servers to compress pages that you visit before downloading them. Pages accessed using private connections (HTTPS) or in Incognito tabs will not be optimised or seen by Google.</translation> +<translation id="2096012225669085171">Sync and personalise across devices</translation> +<translation id="2100273922101894616">Auto Sign-in</translation> +<translation id="2111511281910874386">Go to page</translation> +<translation id="2120297377148151361">Activity and interactions</translation> +<translation id="2122601567107267586">Could not open app</translation> +<translation id="2126426811489709554">Powered by Chrome</translation> +<translation id="2131665479022868825"><ph name="DATA" /> saved</translation> +<translation id="213279576345780926">Closed <ph name="TAB_TITLE" /></translation> +<translation id="2139186145475833000">Add to Home screen</translation> +<translation id="2142289305367051020">Your favourite pages are here</translation> +<translation id="2146738493024040262">Open Instant App</translation> +<translation id="2148716181193084225">Today</translation> +<translation id="2154484045852737596">Edit card</translation> +<translation id="2154710561487035718">Copy URL</translation> +<translation id="2156074688469523661">Remaining sites (<ph name="NUMBER_OF_SITES" />)</translation> +<translation id="2206488550163399966"><ph name="APP_NAME" />, web app. <ph name="APP_URL" /></translation> +<translation id="2227444325776770048">Continue as <ph name="USER_FULL_NAME" /></translation> +<translation id="2232379019872353004">Sends some system information and page content to Google</translation> +<translation id="2234876718134438132">Sync and Google services</translation> +<translation id="2259659629660284697">Export passwords…</translation> +<translation id="2268044343513325586">Refine</translation> +<translation id="2280910239864711607">Open a new tab in private mode</translation> +<translation id="2286841657746966508">Billing address</translation> +<translation id="230115972905494466">No compatible devices found</translation> +<translation id="2315043854645842844">Client side certificate selection is not supported by the operating system.</translation> +<translation id="2321086116217818302">Preparing passwords…</translation> +<translation id="2321958826496381788">Drag the slider until you can read this comfortably. Text should look at least this big after double-tapping on a paragraph.</translation> +<translation id="2323763861024343754">Site storage</translation> +<translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised by you or your parents at any time. Google may use content on sites that you visit, as well as browsing activity and interactions, to personalise Chrome and Google services such as Translate, Search and ads.</translation> +<translation id="2328985652426384049">Can’t sign in</translation> +<translation id="2342981853652716282">Sign in to Chrome to get your bookmarks, passwords and more on all your devices.</translation> +<translation id="2343328333327081434">Installing…</translation> +<translation id="2346253980530904022">Google servers will optimise the pages that you visit, except for HTTPS and Incognito.</translation> +<translation id="2349710944427398404">Total data used by Chrome, including accounts, bookmarks and saved settings</translation> +<translation id="2351097562818989364">Your translate settings have been reset.</translation> +<translation id="2359808026110333948">Continue</translation> +<translation id="2369533728426058518">open tabs</translation> +<translation id="2387895666653383613">Text scaling</translation> +<translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> +<translation id="2410754283952462441">Choose an account</translation> +<translation id="2414672073755873541">No content here</translation> +<translation id="2414886740292270097">Dark</translation> +<translation id="2416359993254398973">Chrome needs permission to access your camera for this site.</translation> +<translation id="2426805022920575512">Choose another account</translation> +<translation id="2433507940547922241">Appearance</translation> +<translation id="2434158240863470628">Download complete <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2436117022029368436">Communicates with Google to improve browsing and Chrome</translation> +<translation id="2440823041667407902">Location access</translation> +<translation id="2450083983707403292">Do you want to start downloading <ph name="FILE_NAME" /> again?</translation> +<translation id="2476578072172137802">Site Settings</translation> +<translation id="2482878487686419369">Notifications</translation> +<translation id="2496180316473517155">Browsing history</translation> +<translation id="2498359688066513246">Help & feedback</translation> +<translation id="2501278716633472235">Go back</translation> +<translation id="2513403576141822879">For more settings that relate to privacy, security and data collection, see <ph name="BEGIN_LINK" />Sync and Google services<ph name="END_LINK" /></translation> +<translation id="2523184218357549926">Sends URLs of pages that you visit to Google</translation> +<translation id="2526148617758225454">Data Saver is on. Manage it in Settings.</translation> +<translation id="2532336938189706096">Web View</translation> +<translation id="2536728043171574184">Viewing an offline copy of this page</translation> +<translation id="2546283357679194313">Cookies and site data</translation> +<translation id="2567385386134582609">IMAGE</translation> +<translation id="2570922361219980984">Location access is also off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="257931822824936280">Expanded – click to collapse.</translation> +<translation id="2581165646603367611">This will clear cookies, cache and other data of sites Chrome doesn't think is important.</translation> +<translation id="2586657967955657006">Clipboard</translation> +<translation id="2587052924345400782">Newer version is available</translation> +<translation id="2593272815202181319">Monospace</translation> +<translation id="2612676031748830579">Card number</translation> +<translation id="2621115761605608342">Allow JavaScript for a specific site.</translation> +<translation id="2625189173221582860">Password copied</translation> +<translation id="2631006050119455616">Saved</translation> +<translation id="2633278372998075009">Private tabs</translation> +<translation id="2647434099613338025">Add language</translation> +<translation id="2650751991977523696">Download file again?</translation> +<translation id="2653659639078652383">Submit</translation> +<translation id="2677748264148917807">Leave</translation> +<translation id="2704606927547763573">Copied</translation> +<translation id="2707726405694321444">Refresh page</translation> +<translation id="2709516037105925701">Auto-fill</translation> +<translation id="271033894570825754">New</translation> +<translation id="2728754400939377704">Sort by site</translation> +<translation id="2744248271121720757">Tap a word to search instantly or see related actions</translation> +<translation id="2762000892062317888">just now</translation> +<translation id="2777555524387840389"><ph name="SECONDS" /> secs left</translation> +<translation id="2781151931089541271">1 sec left</translation> +<translation id="2803478378562657435">Showing saved passwords and password options</translation> +<translation id="2810645512293415242">Simplified page to save data and load faster.</translation> +<translation id="281504910091592009">View and manage saved passwords in your <ph name="BEGIN_LINK" />Google account<ph name="END_LINK" /></translation> +<translation id="2818669890320396765">To get your bookmarks on all your devices, sign in and turn on sync</translation> +<translation id="2836148919159985482">Touch the back button to exit full screen.</translation> +<translation id="2842985007712546952">Parent folder</translation> +<translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Previous track</translation> +<translation id="2876764156902388290">Chrome is using less data to show you this page</translation> +<translation id="2888126860611144412">About Chrome</translation> +<translation id="2891154217021530873">Stop page loading</translation> +<translation id="2900528713135656174">Create event</translation> +<translation id="2902702728133930130">Chrome failed during start-up with an unexpected error.</translation> +<translation id="290376772003165898">Page is not in <ph name="LANGUAGE" />?</translation> +<translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> +<translation id="2913331724188855103">Allow sites to save and read cookie data (recommended)</translation> +<translation id="2932150158123903946">Google <ph name="APP_NAME" /> storage</translation> +<translation id="2943166482989655199">Improve Chrome and its security by sending system and usage data to Google</translation> +<translation id="2956410042958133412">This account is managed by <ph name="PARENT_NAME_1" /> and <ph name="PARENT_NAME_2" />.</translation> +<translation id="2960796085439532066">Copyright <ph name="YEAR" /> Google Inc. All rights reserved.</translation> +<translation id="2962095958535813455">Switched to incognito tabs</translation> +<translation id="2968755619301702150">Certificate viewer</translation> +<translation id="2979025552038692506">Selected Incognito Tab</translation> +<translation id="2989523299700148168">Recently Visited</translation> +<translation id="2996291259634659425">Create passphrase</translation> +<translation id="2996809686854298943">URL required</translation> +<translation id="300526633675317032">This will clear all <ph name="SIZE_IN_KB" /> of website storage.</translation> +<translation id="3029613699374795922">Downloaded <ph name="KBS" /> KB</translation> +<translation id="3029704984691124060">Passphrases do not match</translation> +<translation id="3036750288708366620"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /></translation> +<translation id="3045654778214005718">See more like this from Google</translation> +<translation id="305593374596241526">Location is off; turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="307908932405420782">More articles will appear soon. Enjoy your morning!</translation> +<translation id="3089395242580810162">Open in incognito tab</translation> +<translation id="311456632243022227">Multiple links opened in Chrome</translation> +<translation id="3115898365077584848">Show info</translation> +<translation id="3137521801621304719">Leave incognito mode</translation> +<translation id="3148434565183091099">To get your bookmarks on all your devices, sign in to Chrome.</translation> +<translation id="3157842584138209013">See how much data you've saved from the More Options button</translation> +<translation id="3166827708714933426">Tab and window shortcuts</translation> +<translation id="3190152372525844641">Turn on permissions for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> stored data</translation> +<translation id="3207960819495026254">Bookmarked</translation> +<translation id="321773570071367578">If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="3227137524299004712">Microphone</translation> +<translation id="3232754137068452469">Web App</translation> +<translation id="3234355010754616171">New private tab</translation> +<translation id="3236059992281584593">1 min left</translation> +<translation id="3244271242291266297">MM</translation> +<translation id="3254409185687681395">Bookmark this page</translation> +<translation id="3259831549858767975">Make everything on the page smaller</translation> +<translation id="3269093882174072735">Load image</translation> +<translation id="3269956123044984603">To get your tabs from your other devices, turn on “Auto-sync data” in Android account settings.</translation> +<translation id="3282568296779691940">Sign in to Chrome</translation> +<translation id="32895400574683172">Notifications are allowed</translation> +<translation id="3295602654194328831">Hide info</translation> +<translation id="3298243779924642547">Lite</translation> +<translation id="3303414029551471755">Proceed to download the content?</translation> +<translation id="3328801116991980348">Site information</translation> +<translation id="3341058695485821946">See how much data you've saved</translation> +<translation id="3350687908700087792">Close all incognito tabs</translation> +<translation id="3365671512111106261">Unavailable when Data Saver is turned on</translation> +<translation id="3367813778245106622">Sign in again to start sync</translation> +<translation id="3377025655491224618">Private tab</translation> +<translation id="3384347053049321195">Share image</translation> +<translation id="3386292677130313581">Ask before allowing sites to know your location (recommended)</translation> +<translation id="3387650086002190359"><ph name="FILE_NAME" /> download failed due to file system errors.</translation> +<translation id="339329030417445648">This site tends to show intrusive ads</translation> +<translation id="3398320232533725830">Open the bookmarks manager</translation> +<translation id="3414952576877147120">Size:</translation> +<translation id="3443221991560634068">Reload the current page</translation> +<translation id="3452612588551937789">Sign in with your Google Account to get your bookmarks, history, passwords and other settings on all your devices.</translation> +<translation id="3485359633434254965">{FILES,plural, =1{%1$d file downloaded}other{%1$d files downloaded}}</translation> +<translation id="3492207499832628349">New incognito tab</translation> +<translation id="3493531032208478708"><ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /> about suggested content</translation> +<translation id="3518985090088779359">Accept & continue</translation> +<translation id="3522247891732774234">Update available. More options</translation> +<translation id="3527085408025491307">Folder</translation> +<translation id="3542235761944717775"><ph name="KILOBYTES" /> KB available</translation> +<translation id="3549644494707163724">Encrypt all synced data with your own sync passphrase</translation> +<translation id="3549657413697417275">Search your history</translation> +<translation id="3552151358455404883">Manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="3557336313807607643">Add to contacts</translation> +<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="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="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="3600792891314830896">Mute sites that play sound</translation> +<translation id="360207483134687714">Help improve the VR experience in Chrome</translation> +<translation id="3616113530831147358">Audio</translation> +<translation id="3620176948598597475">Resetting erases Data Saver history, including the list of visited sites.</translation> +<translation id="3630011985153972676">Allow Chrome to download articles for you when on Wi-Fi under settings.</translation> +<translation id="3632295766818638029">Unmask password</translation> +<translation id="363596933471559332">Automatically sign in to websites using stored credentials. When the feature is off, you’ll be asked for verification every time before signing in to a website.</translation> +<translation id="3661699943263275414">Third-party websites can save and read cookie data</translation> +<translation id="3662546969139119822">No history here</translation> +<translation id="3672452749423051839">Navigation error suggestions</translation> +<translation id="3692944402865947621"><ph name="FILE_NAME" /> download failed because storage location is not reachable.</translation> +<translation id="3712575778697986964">Reset Data Saver?</translation> +<translation id="3714981814255182093">Open the Find Bar</translation> +<translation id="3716182511346448902">This page uses too much memory, so Chrome paused it.</translation> +<translation id="3739899004075612870">Bookmarked in <ph name="PRODUCT_NAME" /></translation> +<translation id="3744111309925758534"><ph name="MEGABYTES" /> MB other apps</translation> +<translation id="3744111561329211289">Background sync</translation> +<translation id="3773755127849930740"><ph name="BEGIN_LINK" />Turn on Bluetooth<ph name="END_LINK" /> to allow pairing</translation> +<translation id="3778956594442850293">Added to Home screen</translation> +<translation id="3781011235031427080">More like this opened at half height</translation> +<translation id="3789841737615482174">Install</translation> +<translation id="3810838688059735925">Video</translation> +<translation id="3810973564298564668">Manage</translation> +<translation id="3819178904835489326"><ph name="NUMBER_OF_DOWNLOADS" /> downloads deleted</translation> +<translation id="3819562311292413223">Download articles for you</translation> +<translation id="3822502789641063741">Clear site storage?</translation> +<translation id="385051799172605136">Back</translation> +<translation id="3859306556332390985">Seek forward</translation> +<translation id="3868004864571585162">Cookies, media licences and site data</translation> +<translation id="3894427358181296146">Add folder</translation> +<translation id="3895926599014793903">Force enable zoom</translation> +<translation id="3927692899758076493">Sans Serif</translation> +<translation id="3928666092801078803">Combine my data</translation> +<translation id="393697183122708255">No enabled voice search available</translation> +<translation id="3950820424414687140">Sign in</translation> +<translation id="395206256282351086">Search and site suggestions disabled</translation> +<translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> +<translation id="3967822245660637423">Download complete</translation> +<translation id="397583555483684758">Sync has stopped working</translation> +<translation id="3976396876660209797">Remove and recreate this shortcut</translation> +<translation id="3985215325736559418">Do you want to download <ph name="FILE_NAME" /> again?</translation> +<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="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> +<translation id="3997476611815694295">Unimportant storage</translation> +<translation id="4002066346123236978">Title</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# hr}other{# hrs}}</translation> +<translation id="4042870126885713738">Show suggestions when a web address does not resolve or a connection cannot be made</translation> +<translation id="4046123991198612571">Next track</translation> +<translation id="4048707525896921369">Learn about topics on websites without leaving the page. Tap to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results and other details. + +To adjust your search term, long press to select. To refine your search, slide the panel all the way up and tap the search box.</translation> +<translation id="4056223980640387499">Sepia</translation> +<translation id="4060598801229743805">Options available near the top of the screen</translation> +<translation id="4062305924942672200">Legal information</translation> +<translation id="4084682180776658562">Bookmark</translation> +<translation id="4084712963632273211">From <ph name="PUBLISHER_ORIGIN" /> – <ph name="BEGIN_DEEMPHASIZED" />delivered by Google<ph name="END_DEEMPHASIZED" /></translation> +<translation id="4084836577264234537"><ph name="MEGABYTES" /> MB downloaded</translation> +<translation id="4089831646916293264">This feature may interfere with access to premium data services provided by your operator.</translation> +<translation id="4095146165863963773">Delete app data?</translation> +<translation id="4097739989936358050">This app is running in Chrome.</translation> +<translation id="4099578267706723511">Help make Chrome better by sending usage statistics and crash reports to Google.</translation> +<translation id="410351446219883937">Autoplay</translation> +<translation id="4113030288477039509">Managed by your administrator</translation> +<translation id="4116038641877404294">Download pages to use them offline</translation> +<translation id="4127069705158143605">{BOOKMARKS_COUNT,plural, =1{%1$d bookmark}other{%1$d bookmarks}}</translation> +<translation id="4149994727733219643">Simplified view for web pages</translation> +<translation id="4159800535322890630">Block sites from accessing your sensors</translation> +<translation id="4165986682804962316">Site settings</translation> +<translation id="4170011742729630528">The service is not available; try again later.</translation> +<translation id="4179980317383591987"><ph name="AMOUNT" /> used</translation> +<translation id="4181841719683918333">Languages</translation> +<translation id="4192273449750167573">Review your settings on the next screen</translation> +<translation id="4195643157523330669">Open in new tab</translation> +<translation id="4198423547019359126">No available download locations</translation> +<translation id="4209895695669353772">To get personalised content suggested by Google, turn on sync</translation> +<translation id="4226663524361240545">Notifications may vibrate the device</translation> +<translation id="4242533952199664413">Open settings</translation> +<translation id="4243710787042215766">Open in private tab</translation> +<translation id="424864128008805179">Sign out of Chrome?</translation> +<translation id="4256782883801055595">Open-source licences</translation> +<translation id="4259722352634471385">Navigation is blocked: <ph name="URL" /></translation> +<translation id="4262028915562328938">Sync error occurred, tap to get details.</translation> +<translation id="4269820728363426813">Copy link address</translation> +<translation id="4275663329226226506">Media</translation> +<translation id="4278390842282768270">Allowed</translation> +<translation id="4307992518367153382">Basics</translation> +<translation id="4351244548802238354">Close dialogue</translation> +<translation id="4378154925671717803">Phone</translation> +<translation id="4384468725000734951">Using Sogou for search</translation> +<translation id="4398088515904522762">To use this feature, turn on <ph name="BEGIN_LINK" />Activity and interactions<ph name="END_LINK" />.</translation> +<translation id="4404568932422911380">No bookmarks</translation> +<translation id="4409723563706114196">Use page predictions</translation> +<translation id="4412992751769744546">Allow third-party cookies</translation> +<translation id="4419556793104466535">Control sync, personalisation and more</translation> +<translation id="4432792777822557199">Pages in <ph name="SOURCE_LANGUAGE" /> will be translated to <ph name="TARGET_LANGUAGE" /> from now on</translation> +<translation id="4434045419905280838">Pop-ups and redirects</translation> +<translation id="4452411734226507615">Close <ph name="TAB_TITLE" /> tab</translation> +<translation id="4452548195519783679">Bookmarked to <ph name="FOLDER_NAME" /></translation> +<translation id="4453340223357552416"><ph name="FILE_NAME" /> downloaded in <ph name="PRODUCT_NAME" /></translation> +<translation id="4468959413250150279">Mute sound for a specific site.</translation> +<translation id="4472118726404937099">To sync and personalise across devices, sign in and turn on sync</translation> +<translation id="447252321002412580">Help improve Chrome's features and performance</translation> +<translation id="4479647676395637221">Ask first before allowing sites to use your camera (recommended)</translation> +<translation id="4487967297491345095">All Chrome’s app data will be deleted permanently. This includes all files, settings, accounts, databases, etc.</translation> +<translation id="4508440807153586353">Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting you'll need to reset sync. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation> +<translation id="4513387527876475750">{DAYS,plural, =1{# day ago}other{# days ago}}</translation> +<translation id="451872707440238414">Search your bookmarks</translation> +<translation id="4521489764227272523">The selected data has been removed from Chrome and your synced devices. + +Your Google Account may have other forms of browsing history such as searches and activity from other Google services at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="4532845899244822526">Choose folder</translation> +<translation id="4550003330909367850">To view or copy your password here, set screen lock on this device.</translation> +<translation id="4558311620361989323">Web page shortcuts</translation> +<translation id="4561979708150884304">No connection</translation> +<translation id="4565377596337484307">Hide password</translation> +<translation id="4570913071927164677">Details</translation> +<translation id="4572422548854449519">Sign in to managed account</translation> +<translation id="4581964774250883625">You’ve gone incognito.</translation> +<translation id="4583164079174244168">{MINUTES,plural, =1{# minute ago}other{# minutes ago}}</translation> +<translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">This offline page is from <ph name="CREATION_TIME" /> and may differ from the online version.</translation> +<translation id="4605958867780575332">Item removed: <ph name="ITEM_TITLE" /></translation> +<translation id="4616150815774728855">Open <ph name="WEBAPK_NAME" /></translation> +<translation id="4634124774493850572">Use password</translation> +<translation id="4645575059429386691">Managed by your parent</translation> +<translation id="4660011489602794167">Show keyboard</translation> +<translation id="4663756553811254707"><ph name="NUMBER_OF_BOOKMARKS" /> bookmarks deleted</translation> +<translation id="4665282149850138822"><ph name="NAME" /> was added to your Home screen</translation> +<translation id="4684427112815847243">Sync everything</translation> +<translation id="4695891336199304370">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}other{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}}</translation> +<translation id="4698034686595694889">View offline in <ph name="APP_NAME" /></translation> +<translation id="4698413471314543145">Critical functionality required to run Chrome is missing; either your Chrome installation is incomplete or not compatible with this version of Android.</translation> +<translation id="4699172675775169585">Cached images and files</translation> +<translation id="4714588616299687897">Save up to 60% of your data</translation> +<translation id="4719927025381752090">Offer to translate</translation> +<translation id="4720023427747327413">Open in <ph name="PRODUCT_NAME" /></translation> +<translation id="4720982865791209136">Help improve Chrome. <ph name="BEGIN_LINK" />Take survey<ph name="END_LINK" /></translation> +<translation id="4730876730346568982">You are switching sync accounts from <ph name="ACCOUNT_EMAIL_OLD" /> to <ph name="ACCOUNT_EMAIL_NEW" />. Your existing Chrome data is managed by <ph name="MANAGED_DOMAIN" />. This will delete your data from this device, but your data will remain in <ph name="ACCOUNT_EMAIL_OLD" />.</translation> +<translation id="473775607612524610">Update</translation> +<translation id="4738836084190194332">Last synced: <ph name="WHEN" /></translation> +<translation id="4749960740855309258">Open a new tab</translation> +<translation id="4751476147751820511">Motion or light sensors</translation> +<translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download complete.}other{# downloads complete.}}</translation> +<translation id="4766369052440583386">Data Saver is on</translation> +<translation id="4797039098279997504">Touch to return to <ph name="URL_OF_THE_CURRENT_TAB" /></translation> +<translation id="4807098396393229769">Name on card</translation> +<translation id="4807963036345170158">Data Saver is off</translation> +<translation id="4816465935029283692">Data types</translation> +<translation id="4837753911714442426">Open options to print page</translation> +<translation id="4842092870884894799">Showing password generation pop-up</translation> +<translation id="4850886885716139402">View</translation> +<translation id="4860895144060829044">Call</translation> +<translation id="4874967477260347223">Media Licenses</translation> +<translation id="4875775213178255010">Content Suggestions</translation> +<translation id="4878404682131129617">Establishing a tunnel via proxy server failed</translation> +<translation id="4881695831933465202">Open</translation> +<translation id="488187801263602086">Rename file</translation> +<translation id="4882831918239250449">Control how your browsing history is used to personalise Search, ads and more</translation> +<translation id="4883379392681899581">Leave private mode</translation> +<translation id="4885273946141277891">Unsupported number of Chrome instances.</translation> +<translation id="4910889077668685004">Payment apps</translation> +<translation id="4913161338056004800">Reset statistics</translation> +<translation id="4913169188695071480">Stop refreshing</translation> +<translation id="4915549754973153784"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /> while scanning for devices…</translation> +<translation id="4943872375798546930">No results</translation> +<translation id="4956460920135325549">Lite page delivered by Google.</translation> +<translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> is sharing your screen</translation> +<translation id="4961334780091921942">Your passwords, history & more on all devices</translation> +<translation id="4961700429721424617">You are signing out of an account managed by <ph name="MANAGED_DOMAIN" />. This will delete your Chrome data from this device, but your data will remain in your Google account.</translation> +<translation id="497421865427891073">go forward</translation> +<translation id="4988210275050210843">Downloading file (<ph name="MEGABYTES" />).</translation> +<translation id="4988526792673242964">Pages</translation> +<translation id="4996978546172906250">Share via</translation> +<translation id="5004339818306944878">Use up to 60% less data and speed up the web. Google servers will optimise the pages you visit.</translation> +<translation id="5004416275253351869">Google activity controls</translation> +<translation id="5005498671520578047">Copy password</translation> +<translation id="5011311129201317034"><ph name="SITE" /> wants to connect</translation> +<translation id="5013696553129441713">No new suggestions</translation> +<translation id="5016205925109358554">Serif</translation> +<translation id="5039804452771397117">Allow</translation> +<translation id="5040262127954254034">Privacy</translation> +<translation id="5063480226653192405">Usage</translation> +<translation id="5087580092889165836">Add card</translation> +<translation id="5100237604440890931">Collapsed – click to expand.</translation> +<translation id="510275257476243843">1 hour left</translation> +<translation id="5123685120097942451">Incognito tab</translation> +<translation id="5127805178023152808">Sync is off</translation> +<translation id="5129038482087801250">Install web app</translation> +<translation id="5139940364318403933">Learn how to use Google Drive</translation> +<translation id="515227803646670480">Clear stored data</translation> +<translation id="5152843274749979095">No supported apps installed</translation> +<translation id="5161254044473106830">Title required</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download failed.}other{# downloads failed.}}</translation> +<translation id="5168917394043976756">Open navigation drawer</translation> +<translation id="5171365962177408781">Tap to load the new tab page and view suggested articles</translation> +<translation id="5184329579814168207">Open in Chrome</translation> +<translation id="5199929503336119739">Work profile</translation> +<translation id="5210286577605176222">Jump to the previous tab</translation> +<translation id="5210365745912300556">Close tab</translation> +<translation id="5222676887888702881">Sign out</translation> +<translation id="5224771365102442243">With video</translation> +<translation id="5233638681132016545">New tab</translation> +<translation id="5240817131241497236">The settings that control sync, personalisation and other Google services in Chrome have changed. This may affect your current settings.</translation> +<translation id="5264003212305142034"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised at any time. Google may use content on sites that you visit, plus browser activity and interactions, to personalise Chrome and other Google services such as Translate, Search and ads.</translation> +<translation id="5271967389191913893">Device cannot open the content to be downloaded.</translation> +<translation id="528192093759286357">Drag from top and touch the back button to exit full screen.</translation> +<translation id="5284584623296338184">Changes to your bookmarks, history, passwords and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google account.</translation> +<translation id="5300589172476337783">Show</translation> +<translation id="5301954838959518834">OK, got it</translation> +<translation id="5304593522240415983">This field cannot be blank</translation> +<translation id="5308380583665731573">Connect</translation> +<translation id="5308603654685598744">When this feature is turned on, Chrome will offer to translate pages written in other languages using Google Translate.</translation> +<translation id="5313967007315987356">Add site</translation> +<translation id="5317780077021120954">Save</translation> +<translation id="5324858694974489420">Parental Settings</translation> +<translation id="5327248766486351172">Name</translation> +<translation id="5335288049665977812">Allow sites to run JavaScript (recommended)</translation> +<translation id="5345040418939504969">Deleted <ph name="BOOKMARK_TITLE" /></translation> +<translation id="5372829067651257087">URL copied.</translation> +<translation id="5391532827096253100">Your connection to this site is not secure. Site information</translation> +<translation id="5400569084694353794">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="5403644198645076998">Only allow certain sites</translation> +<translation id="5414836363063783498">Verifying…</translation> +<translation id="5423934151118863508">Your most visited pages will appear here</translation> +<translation id="5424588387303617268"><ph name="GIGABYTES" /> GB available</translation> +<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="5447765697759493033">This site will not be translated</translation> +<translation id="545042621069398927">Speeding up your download.</translation> +<translation id="5456381639095306749">Download page</translation> +<translation id="5466407412363861127">This feature uses <ph name="BEGIN_LINK" />sync<ph name="END_LINK" />.</translation> +<translation id="548278423535722844">Open in maps app</translation> +<translation id="5487521232677179737">Clear data</translation> +<translation id="5487729733663684359">Chrome updates are no longer supported for this version of Android.</translation> +<translation id="5494920125229734069">Select all</translation> +<translation id="550684401320795253">Updating Chrome...</translation> +<translation id="5512137114520586844">This account is managed by <ph name="PARENT_NAME" />.</translation> +<translation id="5514904542973294328">Disabled by the administrator of this device</translation> +<translation id="5515439363601853141">Unlock to view your password</translation> +<translation id="5515716148775388141">Your icons have moved to the bottom of the screen</translation> +<translation id="5517095782334947753">You have bookmarks, history, passwords and other settings from <ph name="FROM_ACCOUNT" />.</translation> +<translation id="5524843473235508879">Redirect blocked.</translation> +<translation id="5527082711130173040">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK1" />Update permissions<ph name="END_LINK1" />. Location access is also <ph name="BEGIN_LINK2" />turned off for this device<ph name="END_LINK2" />.</translation> +<translation id="5527111080432883924">Ask before allowing sites to read text and images from the clipboard (recommended)</translation> +<translation id="5530766185686772672">Close incognito tabs</translation> +<translation id="5534640966246046842">Site copied</translation> +<translation id="5537099431952529648">You and your parents can manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="5556459405103347317">Reload</translation> +<translation id="5561549206367097665">Waiting for network…</translation> +<translation id="557283862590186398">Chrome needs permission to access your microphone for this site.</translation> +<translation id="55737423895878184">Location and notifications are allowed</translation> +<translation id="5578795271662203820">Search <ph name="SEARCH_ENGINE" /> for this image</translation> +<translation id="5595485650161345191">Edit address</translation> +<translation id="5596627076506792578">More options</translation> +<translation id="5620299005957670886">Allow sites to access your sensors (recommended)</translation> +<translation id="5620928963363755975">Find your files and pages in Downloads from the More Options button</translation> +<translation id="5626134646977739690">Name:</translation> +<translation id="5639724618331995626">Allow all sites</translation> +<translation id="5648166631817621825">Last 7 days</translation> +<translation id="5655963694829536461">Search your downloads</translation> +<translation id="5659593005791499971">Email</translation> +<translation id="5665379678064389456">Create event in <ph name="APP_NAME" /></translation> +<translation id="5668404140385795438">Override a website’s request to prevent zooming in</translation> +<translation id="5676636989614905379">Cannot play video on <ph name="SCREEN_NAME" />.</translation> +<translation id="5677928146339483299">Blocked</translation> +<translation id="5684874026226664614">Oops. This page could not be translated.</translation> +<translation id="5686790454216892815">File name too long</translation> +<translation id="5689516760719285838">Location</translation> +<translation id="5719837394786370183">Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your incognito tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your Internet service provider or the websites you visit.</translation> +<translation id="572328651809341494">Recent tabs</translation> +<translation id="5726692708398506830">Make everything on the page bigger</translation> +<translation id="5738816946784116349">Chrome Downloads</translation> +<translation id="5748802427693696783">Switched to standard tabs</translation> +<translation id="5749068826913805084">Chrome needs storage access to download files.</translation> +<translation id="5763382633136178763">Incognito tabs</translation> +<translation id="5763514718066511291">Tap to copy the URL for this app</translation> +<translation id="5765780083710877561">Description:</translation> +<translation id="5777170031995031090">Control how Google uses your browsing history to personalise Search, ads and other Google services.</translation> +<translation id="5793665092639000975">Using <ph name="SPACE_USED" /> of <ph name="SPACE_AVAILABLE" /></translation> +<translation id="5804241973901381774">Permissions</translation> +<translation id="5809361687334836369">{HOURS,plural, =1{# hour ago}other{# hours ago}}</translation> +<translation id="5817918615728894473">Pair</translation> +<translation id="583281660410589416">Unknown</translation> +<translation id="5833397272224757657">Uses content on sites that you visit, plus browser activity and interactions, for personalisation</translation> +<translation id="5833984609253377421">Share link</translation> +<translation id="584427517463557805">Selected private tab</translation> +<translation id="5854790677617711513">Older than 30 days</translation> +<translation id="5858741533101922242">Chrome is unable to turn on Bluetooth adaptor</translation> +<translation id="5860033963881614850">Off</translation> +<translation id="5862731021271217234">To get your tabs from your other devices, turn on sync</translation> +<translation id="5864174910718532887">Details: Sorted by site name</translation> +<translation id="5864419784173784555">Waiting for another download…</translation> +<translation id="5865733239029070421">Automatically sends usage statistics and crash reports to Google</translation> +<translation id="5869522115854928033">Saved passwords</translation> +<translation id="5878455346526065919">Block ads from sites that tend to show intrusive ads</translation> +<translation id="5902828464777634901">All local data stored by this website, including cookies, will be deleted.</translation> +<translation id="5911030830365207728">Google Translate</translation> +<translation id="5916664084637901428">On</translation> +<translation id="5919204609460789179">Update <ph name="PRODUCT_NAME" /> to start sync</translation> +<translation id="5937580074298050696"><ph name="AMOUNT" /> saved</translation> +<translation id="5939518447894949180">Reset</translation> +<translation id="5942872142862698679">Using Google for search</translation> +<translation id="5952764234151283551">Sends the URL of a page that you're trying to reach to Google</translation> +<translation id="5956665950594638604">Open the Chrome Help Centre in a new tab</translation> +<translation id="5958275228015807058">Find your files and pages in Downloads</translation> +<translation id="5962718611393537961">Tap to collapse</translation> +<translation id="5990142338020175451">More personal Google services, such as better page suggestions</translation> +<translation id="6000066717592683814">Keep Google</translation> +<translation id="6005538289190791541">Suggested password</translation> +<translation id="6039379616847168523">Jump to the next tab</translation> +<translation id="6040143037577758943">Close</translation> +<translation id="6042308850641462728">More</translation> +<translation id="604996488070107836"><ph name="FILE_NAME" /> download failed due to an unknown error.</translation> +<translation id="605721222689873409">YY</translation> +<translation id="6075798973483050474">Edit home page</translation> +<translation id="60923314841986378"><ph name="HOURS" /> hours left</translation> +<translation id="60924377787140961">More articles will appear soon. Enjoy your afternoon!</translation> +<translation id="6099151465289169210">Switched to private tabs</translation> +<translation id="6108923351542677676">Setup in progress…</translation> +<translation id="6111020039983847643">data used</translation> +<translation id="6112702117600201073">Refreshing page</translation> +<translation id="6127379762771434464">Item removed</translation> +<translation id="6140912465461743537">Country/Region</translation> +<translation id="6154478581116148741">Turn on screen lock in Settings to export your passwords from this device</translation> +<translation id="6159335304067198720"><ph name="PERCENT" /> data savings</translation> +<translation id="6165508094623778733">Learn more</translation> +<translation id="6177111841848151710">Blocked for current search engine</translation> +<translation id="6177390657002841081">Turn on Data Saver</translation> +<translation id="6181444274883918285">Add site exception</translation> +<translation id="618993374665929060">More like this opened at full height</translation> +<translation id="6192333916571137726">Download File</translation> +<translation id="6192792657125177640">Exceptions</translation> +<translation id="6206551242102657620">Connection is secure. Site information</translation> +<translation id="6210748933810148297">Not <ph name="EMAIL" />?</translation> +<translation id="6216432067784365534"><ph name="NAME_OF_LIST_ITEM" /> Options</translation> +<translation id="6221633008163990886">Unlock to export your passwords</translation> +<translation id="6232535412751077445">Enabling “Do Not Track” means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request and how the request is interpreted. + +For example, some websites may respond to this request by showing you ads that aren’t based on other websites that you’ve visited. Many websites will still collect and use your browsing data – for example to improve security, to provide content, ads and recommendations and to generate reporting statistics.</translation> +<translation id="6255999984061454636">Content suggestions</translation> +<translation id="6277522088822131679">There was a problem printing the page. Please try again.</translation> +<translation id="6295158916970320988">All sites</translation> +<translation id="629730747756840877">Account</translation> +<translation id="6303969859164067831">Sign out and turn off sync</translation> +<translation id="6320088164292336938">Vibrate</translation> +<translation id="6324034347079777476">Android system sync disabled</translation> +<translation id="6333140779060797560">Share via <ph name="APPLICATION" /></translation> +<translation id="6336451774241870485">New private tab</translation> +<translation id="6337234675334993532">Encryption</translation> +<translation id="6341580099087024258">Ask where to save files</translation> +<translation id="6343192674172527289">No downloads found</translation> +<translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}}</translation> +<translation id="6364438453358674297">Remove suggestion from history?</translation> +<translation id="6378173571450987352">Details: Sorted by amount of data used</translation> +<translation id="6383961787135158834">Clear Site Storage…</translation> +<translation id="6388207532828177975">Clear & reset</translation> +<translation id="6393863479814692971">Chrome needs permission to access your camera and microphone for this site.</translation> +<translation id="6395288395575013217">LINK</translation> +<translation id="6404511346730675251">Edit bookmark</translation> +<translation id="6406506848690869874">Sync</translation> +<translation id="641643625718530986">Print…</translation> +<translation id="6416782512398055893">Downloaded <ph name="MBS" /> MB</translation> +<translation id="6433501201775827830">Choose your search engine</translation> +<translation id="6437478888915024427">Page info</translation> +<translation id="6447842834002726250">Cookies</translation> +<translation id="6448273550210938826">Search and URL suggestions</translation> +<translation id="6461962085415701688">Can’t open file</translation> +<translation id="6475951671322991020">Download video</translation> +<translation id="6482749332252372425"><ph name="FILE_NAME" /> download failed due to lack of storage space.</translation> +<translation id="6496823230996795692">To use <ph name="APP_NAME" /> for the first time, please connect to the Internet.</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6534565668554028783">Google took too long to respond</translation> +<translation id="6538442820324228105">Downloaded <ph name="GBS" /> GB</translation> +<translation id="654446541061731451">Select a tab to beam</translation> +<translation id="6545017243486555795">Clear All Data</translation> +<translation id="6556716549745717622">Block if site tends to show intrusive ads (recommended)</translation> +<translation id="6560414384669816528">Search with Sogou</translation> +<translation id="6566259936974865419">Chrome has saved you <ph name="GIGABYTES" /> GB</translation> +<translation id="6573096386450695060">Always allow</translation> +<translation id="6573431926118603307">Tabs that you've opened in Chrome on your other devices will appear here.</translation> +<translation id="6575643671698722332">Reset failed. Ensure that your device is online and try again.</translation> +<translation id="6583199322650523874">Bookmark the current page</translation> +<translation id="6584721918629302382">AR</translation> +<translation id="6593061639179217415">Desktop site</translation> +<translation id="6600954340915313787">Copied to Chrome</translation> +<translation id="6608650720463149374"><ph name="GIGABYTES" /> GB</translation> +<translation id="6610147964972079463">Close private tabs</translation> +<translation id="6612358246767739896">Protected content</translation> +<translation id="6627583120233659107">Edit folder</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6643649862576733715">Sort by amount of data saved</translation> +<translation id="6648977384226967773">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}other{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}}</translation> +<translation id="6656545060687952787">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK" />Update permissions<ph name="END_LINK" /></translation> +<translation id="6657585470893396449">Password</translation> +<translation id="6659594942844771486">Tab</translation> +<translation id="666268767214822976">Use a prediction service to show related queries and popular websites as you type in the address bar</translation> +<translation id="666731172850799929">Open in <ph name="APP_NAME" /></translation> +<translation id="666981079809192359">Chrome Privacy Notice</translation> +<translation id="6697492270171225480">Show suggestions for similar pages when a page can't be found</translation> +<translation id="6697947395630195233">Chrome needs access to your location to share your location with this site.</translation> +<translation id="6698801883190606802">Manage synced data</translation> +<translation id="6710213216561001401">Previous</translation> +<translation id="6712388303105732168">See more like this from Google using the More Like This button</translation> +<translation id="6738867403308150051">Downloading…</translation> +<translation id="6746124502594467657">Move down</translation> +<translation id="6762156594045689028">To change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="6766622839693428701">Swipe down to close.</translation> +<translation id="6770414673596662518">Chrome’s Safe Browsing system will also be used to detect malicious pages and protect you from phishing, malware and harmful downloads.</translation> +<translation id="6776813977906306442">Download videos to watch later using the Download button</translation> +<translation id="6790428901817661496">Play</translation> +<translation id="679325081238418596">Get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="6820607729870073286">You have no saved website settings.</translation> +<translation id="6820686453637990663">CVC</translation> +<translation id="6831043979455480757">Translate</translation> +<translation id="6846298663435243399">Loading…</translation> +<translation id="685040365210406336">Make no changes</translation> +<translation id="6850409657436465440">Your download is still in progress</translation> +<translation id="6850830437481525139"><ph name="TAB_COUNT" /> tabs closed</translation> +<translation id="6864459304226931083">Download image</translation> +<translation id="6865313869410766144">Autofill form data</translation> +<translation id="6868088497967843822">Sign in to get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="688738109438487280">Add existing data to <ph name="TO_ACCOUNT" />.</translation> +<translation id="6891726759199484455">Unlock to copy your password</translation> +<translation id="6891858906296486776">{OPEN_TABS,plural, =1{%1$d open tab}other{%1$d open tabs}}</translation> +<translation id="6896758677409633944">Copy</translation> +<translation id="6910211073230771657">Deleted</translation> +<translation id="6912998170423641340">Block sites from reading text and images from the clipboard</translation> +<translation id="6914783257214138813">Your passwords will be visible to anyone who can see the exported file.</translation> +<translation id="6942665639005891494">Change the default download location at any time using the Settings menu option</translation> +<translation id="6945221475159498467">Select</translation> +<translation id="6963642900430330478">This page is dangerous. Site information</translation> +<translation id="6963766334940102469">Delete bookmarks</translation> +<translation id="6965382102122355670">OK</translation> +<translation id="6978479750597523876">Reset translate settings</translation> +<translation id="6979737339423435258">All time</translation> +<translation id="6981982820502123353">Accessibility</translation> +<translation id="6985347914332179298">No downloads here</translation> +<translation id="6990079615885386641">Get the app from the Google Play Store: <ph name="APP_ACTION" /></translation> +<translation id="699220179437400583">Automatically report details of possible security incidents to Google</translation> +<translation id="6992289844737586249">Ask first before allowing sites to use your microphone (recommended)</translation> +<translation id="7016516562562142042">Allowed for current search engine</translation> +<translation id="7021515813996758557"><ph name="FILE_NAME" /> downloaded</translation> +<translation id="7022756207310403729">Open in browser</translation> +<translation id="702463548815491781">Recommended when TalkBack or Switch Access are on</translation> +<translation id="7029809446516969842">Passwords</translation> +<translation id="7031882061095297553">Sync to</translation> +<translation id="7032663816368481562">When you tap More like this <ph name="ICON" /> in the address bar, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="7034608350006174882">Cards and addresses using Google Pay</translation> +<translation id="7053983685419859001">Block</translation> +<translation id="7055152154916055070">Redirect blocked:</translation> +<translation id="7062545763355031412">Accept and switch accounts</translation> +<translation id="7063006564040364415">Could not connect to the sync server.</translation> +<translation id="7066151586745993502">{NUM_SELECTED,plural, =1{1 selected}other{# selected}}</translation> +<translation id="7077143737582773186">SD Card</translation> +<translation id="7087918508125750058"><ph name="ITEM_COUNT" /> selected. Options available near top of the screen</translation> +<translation id="7108338896283013870">Hide</translation> +<translation id="7121362699166175603">Clears history and autocompletions in the address bar. 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="7128222689758636196">Allow for current search engine</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7139148793369023665">More like this closed</translation> +<translation id="7141896414559753902">Block sites from showing pop-ups and redirects (recommended)</translation> +<translation id="7149158118503947153"><ph name="BEGIN_LINK" />Load original page<ph name="END_LINK" /> from <ph name="DOMAIN_NAME" /></translation> +<translation id="7149893636342594995">Last 24 Hours</translation> +<translation id="7176368934862295254"><ph name="KILOBYTES" /> KB</translation> +<translation id="7177466738963138057">You can change this later in Settings</translation> +<translation id="7180611975245234373">Refresh</translation> +<translation id="7189372733857464326">Waiting for Google Play Services to finish updating</translation> +<translation id="7189598951263744875">Share...</translation> +<translation id="7191430249889272776">Tab opened in background.</translation> +<translation id="723171743924126238">Select images</translation> +<translation id="7243308994586599757">Options available near bottom of the screen</translation> +<translation id="7250468141469952378"><ph name="ITEM_COUNT" /> selected</translation> +<translation id="7251326866581677552">Blocked from some sites</translation> +<translation id="7253272406652746122">Add a Google account from the Accounts page in your device’s Settings app.</translation> +<translation id="7274013316676448362">Blocked site</translation> +<translation id="729975465115245577">Your device doesn’t have an app to store the passwords file.</translation> +<translation id="7302081693174882195">Details: Sorted by amount of data saved</translation> +<translation id="7333031090786104871">Still adding previous site</translation> +<translation id="7352939065658542140">VIDEO</translation> +<translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Share 1 selected item}other{Share # selected items}}</translation> +<translation id="7359002509206457351">Access payment methods</translation> +<translation id="7366340029385295517">Casting to <ph name="SCREEN_NAME" /></translation> +<translation id="7375125077091615385">Type:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> +<translation id="7400418766976504921">URL</translation> +<translation id="7403691278183511381">Chrome First Run Experience</translation> +<translation id="741204030948306876">Yes, I'm in</translation> +<translation id="7413229368719586778">Start date <ph name="DATE" /></translation> +<translation id="7423098979219808738">Ask first</translation> +<translation id="7423538860840206698">Blocked from reading clipboard</translation> +<translation id="7431991332293347422">Control how your browsing history is used to personalise Search and more</translation> +<translation id="7437998757836447326">Sign out of Chrome</translation> +<translation id="7444811645081526538">More categories</translation> +<translation id="7445411102860286510">Allow sites to automatically play muted videos (recommended)</translation> +<translation id="7454641608352164238">Not enough space</translation> +<translation id="7455923816558154057">Tap to view</translation> +<translation id="7465104139234185284">Close all private tabs</translation> +<translation id="7473891865547856676">No Thanks</translation> +<translation id="7475192538862203634">If you’re seeing this frequently, try these <ph name="BEGIN_LINK" />suggestions<ph name="END_LINK" />.</translation> +<translation id="7475688122056506577">SD card not found. Some of your files may be missing.</translation> +<translation id="748127970106343339">Confirm device credential deletion</translation> +<translation id="7481312909269577407">Forward</translation> +<translation id="7493994139787901920"><ph name="VERSION" /> (Updated <ph name="TIME_SINCE_UPDATE" />)</translation> +<translation id="7494879913343971937">Show passwords</translation> +<translation id="7494974237137038751">data saved</translation> +<translation id="7498271377022651285">Please wait…</translation> +<translation id="7514365320538308">Download</translation> +<translation id="751961395872307827">Can't connect to the site</translation> +<translation id="7521387064766892559">JavaScript</translation> +<translation id="7542481630195938534">Can’t get suggestions</translation> +<translation id="7562080006725997899">Clear browsing data</translation> +<translation id="756809126120519699">Cleared Chrome data</translation> +<translation id="757524316907819857">Block sites from playing protected content</translation> +<translation id="7589445247086920869">Block for current search engine</translation> +<translation id="7593557518625677601">Open Android settings and re-enable Android system sync to start Chrome sync</translation> +<translation id="7596558890252710462">Operating system</translation> +<translation id="7605594153474022051">Sync isn't working</translation> +<translation id="7612619742409846846">Signed in to Google as</translation> +<translation id="7619072057915878432"><ph name="FILE_NAME" /> download failed due to network failures.</translation> +<translation id="7624880197989616768"><ph name="BEGIN_LINK1" />Get help<ph name="END_LINK1" /> or <ph name="BEGIN_LINK2" />re-scan<ph name="END_LINK2" /></translation> +<translation id="7626032353295482388">Welcome to Chrome</translation> +<translation id="7638584964844754484">Incorrect passphrase</translation> +<translation id="7641339528570811325">Clear browsing data…</translation> +<translation id="7648422057306047504">Encrypt passwords with Google credentials</translation> +<translation id="7649070708921625228">Help</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7665369617277396874">Add account</translation> +<translation id="7682724950699840886">Try the following tips: make sure that there is enough space on your device; try to export again.</translation> +<translation id="7698359219371678927">Create email in <ph name="APP_NAME" /></translation> +<translation id="7704317875155739195">Auto-complete searches and URLs</translation> +<translation id="773466115871691567">Always translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> +<translation id="773905249182896430">Protects you and your device from dangerous sites</translation> +<translation id="7762668264895820836">SD Card <ph name="SD_CARD_NUMBER" /></translation> +<translation id="7764225426217299476">Add address</translation> +<translation id="7765158879357617694">Move</translation> +<translation id="7769602470925380267">Accept and sign out</translation> +<translation id="7772032839648071052">Confirm passphrase</translation> +<translation id="7774809984919390718">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}other{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}}</translation> +<translation id="7781829728241885113">Yesterday</translation> +<translation id="7791543448312431591">Add</translation> +<translation id="780301667611848630">No, thank you</translation> +<translation id="7810647596859435254">Open with…</translation> +<translation id="7821588508402923572">Your data savings will appear here</translation> +<translation id="7832327313660264358">The data that you sync to Google and the features that you use will not change</translation> +<translation id="7837721118676387834">Allow auto-play of muted videos for a specific site.</translation> +<translation id="7846076177841592234">Cancel selection</translation> +<translation id="784934925303690534">Time range</translation> +<translation id="7851858861565204677">Other Devices</translation> +<translation id="7854964836418414587">Close more like this</translation> +<translation id="7875915731392087153">Create email</translation> +<translation id="7876243839304621966">Remove all</translation> +<translation id="7882131421121961860">No history found</translation> +<translation id="7882806643839505685">Allow sound for a specific site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Downloading file.}other{Downloading # files.}}</translation> +<translation id="7929962904089429003">Opening the menu</translation> +<translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> is out of date.</translation> +<translation id="7947953824732555851">Accept and sign in</translation> +<translation id="7963646190083259054">Vendor:</translation> +<translation id="7981313251711023384">Preload pages for faster browsing and searching</translation> +<translation id="79859296434321399">To view augmented reality content, install ARCore</translation> +<translation id="7986741934819883144">Select a contact</translation> +<translation id="7987073022710626672">Chrome Terms of Service</translation> +<translation id="7987764905897278458">Get more Google smarts</translation> +<translation id="7998918019931843664">Re-open closed tab</translation> +<translation id="7999064672810608036">Are you sure that you want to clear all local data, including cookies, and reset all permissions for this website?</translation> +<translation id="8004582292198964060">Browser</translation> +<translation id="8007176423574883786">Turned off for this device</translation> +<translation id="8015452622527143194">Return everything on the page to default size</translation> +<translation id="802154636333426148">Download failed</translation> +<translation id="8026334261755873520">Clear browsing data</translation> +<translation id="8035133914807600019">New folder…</translation> +<translation id="8037411810184515274">VR</translation> +<translation id="8037686209485537503">More like this</translation> +<translation id="8037750541064988519"><ph name="DAYS" /> days left</translation> +<translation id="804335162455518893">SD card not found</translation> +<translation id="805047784848435650">Based on your browsing history</translation> +<translation id="8051695050440594747"><ph name="MEGABYTES" /> MB available</translation> +<translation id="8058746566562539958">Open in new Chrome tab</translation> +<translation id="8063895661287329888">Failed to add bookmark.</translation> +<translation id="806745655614357130">Keep my data separate</translation> +<translation id="8068648041423924542">Unable to select certificate.</translation> +<translation id="8073388330009372546">Open image in new tab</translation> +<translation id="8084114998886531721">Saved password</translation> +<translation id="8087000398470557479">This content is from <ph name="DOMAIN_NAME" />, delivered by Google.</translation> +<translation id="8103578431304235997">Incognito Tab</translation> +<translation id="8105951947646329362">Suggest related pages</translation> +<translation id="8109613176066109935">To get your bookmarks on all your devices, turn on sync</translation> +<translation id="8116925261070264013">Muted</translation> +<translation id="813082847718468539">View site information</translation> +<translation id="8156139159503939589">What languages do you read?</translation> +<translation id="8168435359814927499">Content</translation> +<translation id="8186512483418048923"><ph name="FILES" /> files left</translation> +<translation id="8190358571722158785">1 day left</translation> +<translation id="8200772114523450471">Resume</translation> +<translation id="8209050860603202033">Open image</translation> +<translation id="8220488350232498290"><ph name="GIGABYTES" /> GB downloaded</translation> +<translation id="8249310407154411074">Move to top</translation> +<translation id="8250920743982581267">Documents</translation> +<translation id="825412236959742607">This page uses too much memory, so Chrome removed some content.</translation> +<translation id="8260126382462817229">Try signing in again</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8266862848225348053">Download location</translation> +<translation id="8274165955039650276">See downloads</translation> +<translation id="8283853025636624853">Syncing to <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8310344678080805313">Standard tabs</translation> +<translation id="8313455859591948645">Edit startup page</translation> +<translation id="8316092324682955408"><ph name="DOMAIN_NAME" /> and more sites</translation> +<translation id="8339163506404995330">Pages in <ph name="LANGUAGE" /> will not be translated</translation> +<translation id="8349013245300336738">Sort by amount of data used</translation> +<translation id="8372893542064058268">Allow Background Sync for a specific site.</translation> +<translation id="8374821112118309944">You need to update TalkBack to a newer version.</translation> +<translation id="8393700583063109961">Send message</translation> +<translation id="8413126021676339697">Show full history</translation> +<translation id="8428213095426709021">Settings</translation> +<translation id="8438566539970814960">Make searches and browsing better</translation> +<translation id="8441146129660941386">Seek backward</translation> +<translation id="8445448999790540984">Can’t export passwords</translation> +<translation id="8447861592752582886">Revoke device permission</translation> +<translation id="8477071352266846533">Sync off for <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8487700953926739672">Available offline</translation> +<translation id="8489271220582375723">Open the history page</translation> +<translation id="8493948351860045254">Free up space</translation> +<translation id="8497726226069778601">Nothing to see here… yet</translation> +<translation id="8503559462189395349">Chrome Passwords</translation> +<translation id="8503813439785031346">Username</translation> +<translation id="8504988642345501642">When you scroll up, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="8507520749471379845">Passwords available</translation> +<translation id="8514477925623180633">Export passwords stored with Chrome</translation> +<translation id="8514577642972634246">Enter incognito mode</translation> +<translation id="851751545965956758">Block sites from connecting to devices</translation> +<translation id="8523928698583292556">Delete stored password</translation> +<translation id="854522910157234410">Open this page:</translation> +<translation id="8558485628462305855">To view augmented reality content, update ARCore</translation> +<translation id="8559990750235505898">Offer to translate pages in other languages</translation> +<translation id="8562452229998620586">Your saved passwords will appear here.</translation> +<translation id="8569404424186215731">since <ph name="DATE" /></translation> +<translation id="8571213806525832805">Last 4 weeks</translation> +<translation id="857509777403223202">More articles will appear soon. Enjoy your evening!</translation> +<translation id="857943718398505171">Allowed (recommended)</translation> +<translation id="8583805026567836021">Clearing account data</translation> +<translation id="8609465669617005112">Move up</translation> +<translation id="8616006591992756292">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="8617240290563765734">Open the suggested URL specified in the downloaded content?</translation> +<translation id="862875433388403934">Content (films, music, etc.) downloaded in other applications may no longer be playable until those applications re-acquire licences based on a new device credential. To obtain new licences, connect to the Internet and play your downloaded content.</translation> +<translation id="8636825310635137004">To get your tabs from your other devices, turn on sync.</translation> +<translation id="8641930654639604085">Try to block mature sites</translation> +<translation id="8662811608048051533">Signs you out of most sites.</translation> +<translation id="8664979001105139458">File name already exists</translation> +<translation id="8676374126336081632">Clear input</translation> +<translation id="8687353297350450808">{N_BARS,plural, =1{Signal Strength Level: # bar}other{Signal Strength Level: # bars}}</translation> +<translation id="868929229000858085">Search your contacts</translation> +<translation id="869891660844655955">Expiry date</translation> +<translation id="8719023831149562936">Can’t beam current tab</translation> +<translation id="8725066075913043281">Try again</translation> +<translation id="8728487861892616501">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8730621377337864115">Done</translation> +<translation id="8748850008226585750">Contents hidden</translation> +<translation id="8751914237388039244">Select an image</translation> +<translation id="8788968922598763114">Reopen the last closed tab</translation> +<translation id="8812260976093120287">On some websites, you can pay with above supported payment apps on your device.</translation> +<translation id="8816439037877937734"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome's <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8820817407110198400">Bookmarks</translation> +<translation id="8823704566850948458">Suggest password...</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> +<translation id="883806473910249246">An error occurred while downloading the content.</translation> +<translation id="8840953339110955557">This page may differ from the online version.</translation> +<translation id="8847988622838149491">USB</translation> +<translation id="8853345339104747198"><ph name="TAB_TITLE" />, tab</translation> +<translation id="885701979325669005">Storage</translation> +<translation id="8901170036886848654">No bookmarks found</translation> +<translation id="8909135823018751308">Share…</translation> +<translation id="8912362522468806198">Google Account</translation> +<translation id="8920114477895755567">Waiting for details of parents.</translation> +<translation id="8922289737868596582">Download pages from the More Options button to use them offline</translation> +<translation id="8941729603749328384">www.example.com</translation> +<translation id="8942627711005830162">Open in other window</translation> +<translation id="8951232171465285730">Chrome has saved you <ph name="MEGABYTES" /> MB</translation> +<translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> +<translation id="8972098258593396643">Download to default folder?</translation> +<translation id="8979405271719829084">Download videos to watch later</translation> +<translation id="8981454092730389528">Google Activity Controls</translation> +<translation id="8983677657449185470">Help improve Safe Browsing</translation> +<translation id="8986494364107987395">Automatically send usage statistics and crash reports to Google</translation> +<translation id="8993760627012879038">Open a new tab in Incognito mode</translation> +<translation id="8998729206196772491">You are signing in with an account managed by <ph name="MANAGED_DOMAIN" /> and giving its administrator control over your Chrome data. Your data will become permanently tied to this account. Signing out of Chrome will delete your data from this device, but it will remain stored in your Google account.</translation> +<translation id="9019902583201351841">Managed by your parents</translation> +<translation id="9040142327097499898">Notifications are allowed. Location is off for this device.</translation> +<translation id="9050666287014529139">Passphrase</translation> +<translation id="9060538597317784206">View app <ph name="APP_NAME" /> on the Play Store. Rating: <ph name="APP_RATING" />.</translation> +<translation id="9063523880881406963">Turn off Request desktop site</translation> +<translation id="9065203028668620118">Edit</translation> +<translation id="9070377983101773829">Start voice search</translation> +<translation id="9071742570345586758">To view virtual reality content, install Google VR Services</translation> +<translation id="9074336505530349563">To get personalised content suggested by Google, sign in and turn on sync</translation> +<translation id="9080642952018487277">Enter private mode</translation> +<translation id="9086455579313502267">Unable to access the network</translation> +<translation id="9099018167121903954"><ph name="KILOBYTES" /> KB downloaded</translation> +<translation id="9100505651305367705">Offer to show articles in simplified view, when supported</translation> +<translation id="9100610230175265781">Passphrase required</translation> +<translation id="9100939710791843300">Tap the home button to load the new tab page and view suggested articles</translation> +<translation id="9133515669113036225">Reset device credentials</translation> +<translation id="9133703968756164531"><ph name="ITEM_NAME" /> (<ph name="ITEM_ID" />)</translation> +<translation id="9137013805542155359">Show original</translation> +<translation id="9139068048179869749">Ask before allowing sites to send notifications (recommended)</translation> +<translation id="9155898266292537608">You can also search with a quick tap on a word</translation> +<translation id="9188680907066685419">Sign out of managed account</translation> +<translation id="9204836675896933765">1 file left</translation> +<translation id="9206873250291191720">A</translation> +<translation id="9218033835049520260">Suggest strong password...</translation> +<translation id="9219103736887031265">Images</translation> +<translation id="932327136139879170">Home</translation> +<translation id="932599481871055447">Save data and browse faster</translation> +<translation id="938850635132480979">Error: <ph name="ERROR_CODE" /></translation> +<translation id="945522503751344254">Send feedback</translation> +<translation id="945632385593298557">Access your microphone</translation> +<translation id="951339005376969845">Delete existing data. You can retrieve it by switching back to <ph name="FROM_ACCOUNT" />.</translation> +<translation id="95817756606698420">Chrome can use <ph name="BEGIN_BOLD" />Sogou<ph name="END_BOLD" /> for search in China. You can change this in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="970715775301869095"><ph name="MINUTES" /> mins left</translation> +<translation id="974555521953189084">Enter your passphrase to start sync</translation> +<translation id="981121421437150478">Offline</translation> +<translation id="982182592107339124">This will clear data for all sites, including:</translation> +<translation id="983192555821071799">Close all tabs</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ml.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ml.xtb new file mode 100644 index 0000000..14e1c38 --- /dev/null +++ b/chrome/android/java/strings/translations/android_chrome_strings_ml.xtb
@@ -0,0 +1,1056 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ml"> +<translation id="1006017844123154345">Open Online</translation> +<translation id="1036727731225946849">Adding <ph name="WEBAPK_NAME" />...</translation> +<translation id="1041308826830691739">From websites</translation> +<translation id="1049743911850919806">Incognito</translation> +<translation id="1054301162707478098">You’ve gone private.</translation> +<translation id="10614374240317010">Never saved</translation> +<translation id="1067922213147265141">Other Google services</translation> +<translation id="1068672505746868501">Never translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="10713315585330490"><ph name="FILE_SIZE" /> – <ph name="DESCRIPTION" /></translation> +<translation id="1080790410959514870">You are signing out of an account managed by <ph name="DOMAIN_NAME" />. This will delete the Chrome data stored on this device, but the data will remain in your Google Account.</translation> +<translation id="1105960400813249514">Screen Capture</translation> +<translation id="1111673857033749125">Bookmarks saved on your other devices will appear here.</translation> +<translation id="1113597929977215864">Show simplified view</translation> +<translation id="1121094540300013208">Usage and crash reports</translation> +<translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download pending.}other{# downloads pending.}}</translation> +<translation id="1145536944570833626">Delete existing data.</translation> +<translation id="1146678959555564648">Enter VR</translation> +<translation id="114721135501989771">Get Google smarts in Chrome</translation> +<translation id="1157102636231978136">Your browsing data and activity, synced to your Google account</translation> +<translation id="116280672541001035">Used</translation> +<translation id="1172593791219290334">Startup Page</translation> +<translation id="1175310183703641346">Your bookmarks, history, passwords and more will no longer be synced to your Google account</translation> +<translation id="1178581264944972037">Pause</translation> +<translation id="1181037720776840403">Remove</translation> +<translation id="1197267115302279827">Move bookmarks</translation> +<translation id="119944043368869598">Clear all</translation> +<translation id="1201402288615127009">Next</translation> +<translation id="1204037785786432551">Download link</translation> +<translation id="1206892813135768548">Copy link text</translation> +<translation id="1208340532756947324">To sync and personalise across devices, turn on sync</translation> +<translation id="1209206284964581585">Hide for now</translation> +<translation id="123724288017357924">Reload the current page, ignoring cached content</translation> +<translation id="124116460088058876">More languages</translation> +<translation id="124678866338384709">Close current tab</translation> +<translation id="1258753120186372309">Google doodle: <ph name="DOODLE_DESCRIPTION" /></translation> +<translation id="1259100630977430756">Pages that you view in private tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your private tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going private doesn’t hide your browsing from your employer, your Internet service provider or the websites that you visit.</translation> +<translation id="127138278192656016">Use sync and all services</translation> +<translation id="1272079795634619415">Stop</translation> +<translation id="1283039547216852943">Tap to expand</translation> +<translation id="1285320974508926690">Never translate this site</translation> +<translation id="1291207594882862231">Clear history, cookies, site data, cache…</translation> +<translation id="129553762522093515">Recently closed</translation> +<translation id="1326317727527857210">To get your tabs from your other devices, sign in to Chrome.</translation> +<translation id="1332501820983677155">Google Chrome feature shortcuts</translation> +<translation id="1360432990279830238">Sign out and turn off sync?</translation> +<translation id="136248372334525878">Preload pages for faster loading and offline reading</translation> +<translation id="1369915414381695676">Site <ph name="SITE_NAME" /> added</translation> +<translation id="1373696734384179344">Insufficient memory to download the selected content.</translation> +<translation id="1376578503827013741">Computing…</translation> +<translation id="138361230106469022">Hi, <ph name="FULL_NAME" /></translation> +<translation id="1383876407941801731">Search</translation> +<translation id="1384959399684842514">Download paused</translation> +<translation id="1389974829397082527">No bookmarks here</translation> +<translation id="1397811292916898096">Search with <ph name="PRODUCT_NAME" /></translation> +<translation id="1397854323885047133">Sync and personalisation</translation> +<translation id="1404122904123200417">Embedded in <ph name="WEBSITE_URL" /></translation> +<translation id="1406000523432664303">“Do Not Track”</translation> +<translation id="1407135791313364759">Open all</translation> +<translation id="1409426117486808224">Simplified view for open tabs</translation> +<translation id="1409879593029778104"><ph name="FILE_NAME" /> download prevented because file already exists.</translation> +<translation id="1414981605391750300">Contacting Google. This may take a minute…</translation> +<translation id="1416550906796893042">Application version</translation> +<translation id="1430915738399379752">Print</translation> +<translation id="1445680696957526815">Chrome’s components are incompatible with one another. Chrome may be upgrading, please try again in a few minutes. If the problem continues, try uninstalling and re-installing Chrome.</translation> +<translation id="1446450296470737166">Allow full control of MIDI devices</translation> +<translation id="145097072038377568">Turned off in Android Settings</translation> +<translation id="1477626028522505441"><ph name="FILE_NAME" /> download failed due to server issues.</translation> +<translation id="1506061864768559482">Search engine</translation> +<translation id="1513352483775369820">Bookmarks and web history</translation> +<translation id="1513858653616922153">Delete password</translation> +<translation id="1516229014686355813">Tap to Search sends the selected word and the current page as context to Google Search. You can turn it off in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="1539064842193522527">Link opened in Chrome</translation> +<translation id="1549000191223877751">Move to other window</translation> +<translation id="1553358976309200471">Update Chrome</translation> +<translation id="1566400915470565838">To use <ph name="APP_NAME" />, please connect to the Internet.</translation> +<translation id="1569387923882100876">Connected device</translation> +<translation id="1571304935088121812">Copy username</translation> +<translation id="1576370611341449972">Download occurs only on Wi-Fi</translation> +<translation id="1612196535745283361">Chrome needs location access to scan for devices. Location access is <ph name="BEGIN_LINK" />turned off for this device<ph name="END_LINK" />.</translation> +<translation id="162035744160882748">Turn on sync, personalisation and other Google services</translation> +<translation id="1620510694547887537">Camera</translation> +<translation id="1623104350909869708">Prevent this page from creating additional dialogues</translation> +<translation id="1628019612362412531">{NUM_SELECTED,plural, =1{Remove 1 selected item}other{Remove # selected items}}</translation> +<translation id="1641113438599504367">Safe Browsing</translation> +<translation id="164269334534774161">You are viewing an offline copy of this page from <ph name="CREATION_TIME" /></translation> +<translation id="1644574205037202324">History</translation> +<translation id="1647391597548383849">Access your camera</translation> +<translation id="1660204651932907780">Allow sites to play sound (recommended)</translation> +<translation id="1670399744444387456">Basic</translation> +<translation id="1671236975893690980">Download pending...</translation> +<translation id="1672586136351118594">Don‘t show again</translation> +<translation id="1709438864123551175">Data Saver</translation> +<translation id="1718835860248848330">Last hour</translation> +<translation id="1729516292547892356">To view virtual reality content, update Google VR Services</translation> +<translation id="1733116627827457509"><ph name="FILE_SIZE" /> – Updated <ph name="TIME_SINCE_UPDATE" /></translation> +<translation id="1736419249208073774">Explore</translation> +<translation id="1743802530341753419">Ask before allowing sites to connect to a device (recommended)</translation> +<translation id="1749561566933687563">Sync your bookmarks</translation> +<translation id="17513872634828108">Open tabs</translation> +<translation id="1756600373018374892">Tap this button for quick access to your tabs.</translation> +<translation id="1779089405699405702">Image decoder</translation> +<translation id="1782483593938241562">End date <ph name="DATE" /></translation> +<translation id="1792959175193046959">Change the default download location at any time</translation> +<translation id="1807246157184219062">Light</translation> +<translation id="1821253160463689938">Uses cookies to remember your preferences, even if you don't visit those pages</translation> +<translation id="1829244130665387512">Find in page</translation> +<translation id="1832521218263067499">Security incidents</translation> +<translation id="1853692000353488670">New incognito tab</translation> +<translation id="1868024384445905608">Chrome now downloads files faster</translation> +<translation id="1878302395768190018">You can customise this at any time in Chrome Settings</translation> +<translation id="1880072593381090678">Popular pages from Chrome</translation> +<translation id="1883903952484604915">My files</translation> +<translation id="1887786770086287077">Location access is off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1891331835972267886"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="189172778771606813">Close navigation drawer</translation> +<translation id="1919345977826869612">Ads</translation> +<translation id="1919950603503897840">Select contacts</translation> +<translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/<ph name="FILE_SIZE_WITH_UNITS" /></translation> +<translation id="1933845786846280168">Selected Tab</translation> +<translation id="1938981467853765413">Provide feedback</translation> +<translation id="194341124344773587">Turn on permission for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1943432128510653496">Save passwords</translation> +<translation id="1944384637046898011">Encrypt all with Google password as of <ph name="TIME" /></translation> +<translation id="1946005195648379376">Control how Google uses your browsing history to personalise Search and other Google services.</translation> +<translation id="1952172573699511566">Websites will show text in your preferred language, when possible.</translation> +<translation id="195283394249132567">Personalised Google services</translation> +<translation id="1966710179511230534">Please update your sign-in details.</translation> +<translation id="1974060860693918893">Advanced</translation> +<translation id="1984937141057606926">Allowed, except third-party</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> button</translation> +<translation id="1989112275319619282">Browse</translation> +<translation id="1993768208584545658"><ph name="SITE" /> wants to pair</translation> +<translation id="1994173015038366702">Site URL</translation> +<translation id="2000419248597011803">Sends some cookies and searches from the address bar and search box to your default search engine</translation> +<translation id="2002537628803770967">Credit cards and addresses using Google Pay</translation> +<translation id="200815880754187296"><ph name="KILOBYTES" /> KB other apps</translation> +<translation id="2017836877785168846">Clears history and autocompletions in the address bar.</translation> +<translation id="2021896219286479412">Full screen site controls</translation> +<translation id="2038563949887743358">Turn on Request desktop site</translation> +<translation id="2045104531052923016"><ph name="GIGABYTES" /> GB other apps</translation> +<translation id="2063713494490388661">Tap to Search</translation> +<translation id="2079545284768500474">Undo</translation> +<translation id="2082238445998314030">Result <ph name="RESULT_NUMBER" /> of <ph name="TOTAL_RESULTS" /></translation> +<translation id="2086652334978798447">To get personalised content suggested by Google, sign in to Chrome.</translation> +<translation id="2091887806945687916">Sound</translation> +<translation id="2095887075102408547">When this feature is turned on, Chrome will use Google servers to compress pages that you visit before downloading them. Pages accessed using private connections (HTTPS) or in Incognito tabs will not be optimised or seen by Google.</translation> +<translation id="2096012225669085171">Sync and personalise across devices</translation> +<translation id="2100273922101894616">Auto Sign-in</translation> +<translation id="2111511281910874386">Go to page</translation> +<translation id="2120297377148151361">Activity and interactions</translation> +<translation id="2122601567107267586">Could not open app</translation> +<translation id="2126426811489709554">Powered by Chrome</translation> +<translation id="2131665479022868825"><ph name="DATA" /> saved</translation> +<translation id="213279576345780926">Closed <ph name="TAB_TITLE" /></translation> +<translation id="2139186145475833000">Add to Home screen</translation> +<translation id="2142289305367051020">Your favourite pages are here</translation> +<translation id="2146738493024040262">Open Instant App</translation> +<translation id="2148716181193084225">Today</translation> +<translation id="2154484045852737596">Edit card</translation> +<translation id="2154710561487035718">Copy URL</translation> +<translation id="2156074688469523661">Remaining sites (<ph name="NUMBER_OF_SITES" />)</translation> +<translation id="2206488550163399966"><ph name="APP_NAME" />, web app. <ph name="APP_URL" /></translation> +<translation id="2227444325776770048">Continue as <ph name="USER_FULL_NAME" /></translation> +<translation id="2232379019872353004">Sends some system information and page content to Google</translation> +<translation id="2234876718134438132">Sync and Google services</translation> +<translation id="2259659629660284697">Export passwords…</translation> +<translation id="2268044343513325586">Refine</translation> +<translation id="2280910239864711607">Open a new tab in private mode</translation> +<translation id="2286841657746966508">Billing address</translation> +<translation id="230115972905494466">No compatible devices found</translation> +<translation id="2315043854645842844">Client side certificate selection is not supported by the operating system.</translation> +<translation id="2321086116217818302">Preparing passwords…</translation> +<translation id="2321958826496381788">Drag the slider until you can read this comfortably. Text should look at least this big after double-tapping on a paragraph.</translation> +<translation id="2323763861024343754">Site storage</translation> +<translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised by you or your parents at any time. Google may use content on sites that you visit, as well as browsing activity and interactions, to personalise Chrome and Google services such as Translate, Search and ads.</translation> +<translation id="2328985652426384049">Can’t sign in</translation> +<translation id="2342981853652716282">Sign in to Chrome to get your bookmarks, passwords and more on all your devices.</translation> +<translation id="2343328333327081434">Installing…</translation> +<translation id="2346253980530904022">Google servers will optimise the pages that you visit, except for HTTPS and Incognito.</translation> +<translation id="2349710944427398404">Total data used by Chrome, including accounts, bookmarks and saved settings</translation> +<translation id="2351097562818989364">Your translate settings have been reset.</translation> +<translation id="2359808026110333948">Continue</translation> +<translation id="2369533728426058518">open tabs</translation> +<translation id="2387895666653383613">Text scaling</translation> +<translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> +<translation id="2410754283952462441">Choose an account</translation> +<translation id="2414672073755873541">No content here</translation> +<translation id="2414886740292270097">Dark</translation> +<translation id="2416359993254398973">Chrome needs permission to access your camera for this site.</translation> +<translation id="2426805022920575512">Choose another account</translation> +<translation id="2433507940547922241">Appearance</translation> +<translation id="2434158240863470628">Download complete <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2436117022029368436">Communicates with Google to improve browsing and Chrome</translation> +<translation id="2440823041667407902">Location access</translation> +<translation id="2450083983707403292">Do you want to start downloading <ph name="FILE_NAME" /> again?</translation> +<translation id="2476578072172137802">Site Settings</translation> +<translation id="2482878487686419369">Notifications</translation> +<translation id="2496180316473517155">Browsing history</translation> +<translation id="2498359688066513246">Help & feedback</translation> +<translation id="2501278716633472235">Go back</translation> +<translation id="2513403576141822879">For more settings that relate to privacy, security and data collection, see <ph name="BEGIN_LINK" />Sync and Google services<ph name="END_LINK" /></translation> +<translation id="2523184218357549926">Sends URLs of pages that you visit to Google</translation> +<translation id="2526148617758225454">Data Saver is on. Manage it in Settings.</translation> +<translation id="2532336938189706096">Web View</translation> +<translation id="2536728043171574184">Viewing an offline copy of this page</translation> +<translation id="2546283357679194313">Cookies and site data</translation> +<translation id="2567385386134582609">IMAGE</translation> +<translation id="2570922361219980984">Location access is also off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="257931822824936280">Expanded – click to collapse.</translation> +<translation id="2581165646603367611">This will clear cookies, cache and other data of sites Chrome doesn't think is important.</translation> +<translation id="2586657967955657006">Clipboard</translation> +<translation id="2587052924345400782">Newer version is available</translation> +<translation id="2593272815202181319">Monospace</translation> +<translation id="2612676031748830579">Card number</translation> +<translation id="2621115761605608342">Allow JavaScript for a specific site.</translation> +<translation id="2625189173221582860">Password copied</translation> +<translation id="2631006050119455616">Saved</translation> +<translation id="2633278372998075009">Private tabs</translation> +<translation id="2647434099613338025">Add language</translation> +<translation id="2650751991977523696">Download file again?</translation> +<translation id="2653659639078652383">Submit</translation> +<translation id="2677748264148917807">Leave</translation> +<translation id="2704606927547763573">Copied</translation> +<translation id="2707726405694321444">Refresh page</translation> +<translation id="2709516037105925701">Auto-fill</translation> +<translation id="271033894570825754">New</translation> +<translation id="2728754400939377704">Sort by site</translation> +<translation id="2744248271121720757">Tap a word to search instantly or see related actions</translation> +<translation id="2762000892062317888">just now</translation> +<translation id="2777555524387840389"><ph name="SECONDS" /> secs left</translation> +<translation id="2781151931089541271">1 sec left</translation> +<translation id="2803478378562657435">Showing saved passwords and password options</translation> +<translation id="2810645512293415242">Simplified page to save data and load faster.</translation> +<translation id="281504910091592009">View and manage saved passwords in your <ph name="BEGIN_LINK" />Google account<ph name="END_LINK" /></translation> +<translation id="2818669890320396765">To get your bookmarks on all your devices, sign in and turn on sync</translation> +<translation id="2836148919159985482">Touch the back button to exit full screen.</translation> +<translation id="2842985007712546952">Parent folder</translation> +<translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Previous track</translation> +<translation id="2876764156902388290">Chrome is using less data to show you this page</translation> +<translation id="2888126860611144412">About Chrome</translation> +<translation id="2891154217021530873">Stop page loading</translation> +<translation id="2900528713135656174">Create event</translation> +<translation id="2902702728133930130">Chrome failed during start-up with an unexpected error.</translation> +<translation id="290376772003165898">Page is not in <ph name="LANGUAGE" />?</translation> +<translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> +<translation id="2913331724188855103">Allow sites to save and read cookie data (recommended)</translation> +<translation id="2932150158123903946">Google <ph name="APP_NAME" /> storage</translation> +<translation id="2943166482989655199">Improve Chrome and its security by sending system and usage data to Google</translation> +<translation id="2956410042958133412">This account is managed by <ph name="PARENT_NAME_1" /> and <ph name="PARENT_NAME_2" />.</translation> +<translation id="2960796085439532066">Copyright <ph name="YEAR" /> Google Inc. All rights reserved.</translation> +<translation id="2962095958535813455">Switched to incognito tabs</translation> +<translation id="2968755619301702150">Certificate viewer</translation> +<translation id="2979025552038692506">Selected Incognito Tab</translation> +<translation id="2989523299700148168">Recently Visited</translation> +<translation id="2996291259634659425">Create passphrase</translation> +<translation id="2996809686854298943">URL required</translation> +<translation id="300526633675317032">This will clear all <ph name="SIZE_IN_KB" /> of website storage.</translation> +<translation id="3029613699374795922">Downloaded <ph name="KBS" /> KB</translation> +<translation id="3029704984691124060">Passphrases do not match</translation> +<translation id="3036750288708366620"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /></translation> +<translation id="3045654778214005718">See more like this from Google</translation> +<translation id="305593374596241526">Location is off; turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="307908932405420782">More articles will appear soon. Enjoy your morning!</translation> +<translation id="3089395242580810162">Open in incognito tab</translation> +<translation id="311456632243022227">Multiple links opened in Chrome</translation> +<translation id="3115898365077584848">Show info</translation> +<translation id="3137521801621304719">Leave incognito mode</translation> +<translation id="3148434565183091099">To get your bookmarks on all your devices, sign in to Chrome.</translation> +<translation id="3157842584138209013">See how much data you've saved from the More Options button</translation> +<translation id="3166827708714933426">Tab and window shortcuts</translation> +<translation id="3190152372525844641">Turn on permissions for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> stored data</translation> +<translation id="3207960819495026254">Bookmarked</translation> +<translation id="321773570071367578">If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="3227137524299004712">Microphone</translation> +<translation id="3232754137068452469">Web App</translation> +<translation id="3234355010754616171">New private tab</translation> +<translation id="3236059992281584593">1 min left</translation> +<translation id="3244271242291266297">MM</translation> +<translation id="3254409185687681395">Bookmark this page</translation> +<translation id="3259831549858767975">Make everything on the page smaller</translation> +<translation id="3269093882174072735">Load image</translation> +<translation id="3269956123044984603">To get your tabs from your other devices, turn on “Auto-sync data” in Android account settings.</translation> +<translation id="3282568296779691940">Sign in to Chrome</translation> +<translation id="32895400574683172">Notifications are allowed</translation> +<translation id="3295602654194328831">Hide info</translation> +<translation id="3298243779924642547">Lite</translation> +<translation id="3303414029551471755">Proceed to download the content?</translation> +<translation id="3328801116991980348">Site information</translation> +<translation id="3341058695485821946">See how much data you've saved</translation> +<translation id="3350687908700087792">Close all incognito tabs</translation> +<translation id="3365671512111106261">Unavailable when Data Saver is turned on</translation> +<translation id="3367813778245106622">Sign in again to start sync</translation> +<translation id="3377025655491224618">Private tab</translation> +<translation id="3384347053049321195">Share image</translation> +<translation id="3386292677130313581">Ask before allowing sites to know your location (recommended)</translation> +<translation id="3387650086002190359"><ph name="FILE_NAME" /> download failed due to file system errors.</translation> +<translation id="339329030417445648">This site tends to show intrusive ads</translation> +<translation id="3398320232533725830">Open the bookmarks manager</translation> +<translation id="3414952576877147120">Size:</translation> +<translation id="3443221991560634068">Reload the current page</translation> +<translation id="3452612588551937789">Sign in with your Google Account to get your bookmarks, history, passwords and other settings on all your devices.</translation> +<translation id="3485359633434254965">{FILES,plural, =1{%1$d file downloaded}other{%1$d files downloaded}}</translation> +<translation id="3492207499832628349">New incognito tab</translation> +<translation id="3493531032208478708"><ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /> about suggested content</translation> +<translation id="3518985090088779359">Accept & continue</translation> +<translation id="3522247891732774234">Update available. More options</translation> +<translation id="3527085408025491307">Folder</translation> +<translation id="3542235761944717775"><ph name="KILOBYTES" /> KB available</translation> +<translation id="3549644494707163724">Encrypt all synced data with your own sync passphrase</translation> +<translation id="3549657413697417275">Search your history</translation> +<translation id="3552151358455404883">Manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="3557336313807607643">Add to contacts</translation> +<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="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="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="3600792891314830896">Mute sites that play sound</translation> +<translation id="360207483134687714">Help improve the VR experience in Chrome</translation> +<translation id="3616113530831147358">Audio</translation> +<translation id="3620176948598597475">Resetting erases Data Saver history, including the list of visited sites.</translation> +<translation id="3630011985153972676">Allow Chrome to download articles for you when on Wi-Fi under settings.</translation> +<translation id="3632295766818638029">Unmask password</translation> +<translation id="363596933471559332">Automatically sign in to websites using stored credentials. When the feature is off, you’ll be asked for verification every time before signing in to a website.</translation> +<translation id="3661699943263275414">Third-party websites can save and read cookie data</translation> +<translation id="3662546969139119822">No history here</translation> +<translation id="3672452749423051839">Navigation error suggestions</translation> +<translation id="3692944402865947621"><ph name="FILE_NAME" /> download failed because storage location is not reachable.</translation> +<translation id="3712575778697986964">Reset Data Saver?</translation> +<translation id="3714981814255182093">Open the Find Bar</translation> +<translation id="3716182511346448902">This page uses too much memory, so Chrome paused it.</translation> +<translation id="3739899004075612870">Bookmarked in <ph name="PRODUCT_NAME" /></translation> +<translation id="3744111309925758534"><ph name="MEGABYTES" /> MB other apps</translation> +<translation id="3744111561329211289">Background sync</translation> +<translation id="3773755127849930740"><ph name="BEGIN_LINK" />Turn on Bluetooth<ph name="END_LINK" /> to allow pairing</translation> +<translation id="3778956594442850293">Added to Home screen</translation> +<translation id="3781011235031427080">More like this opened at half height</translation> +<translation id="3789841737615482174">Install</translation> +<translation id="3810838688059735925">Video</translation> +<translation id="3810973564298564668">Manage</translation> +<translation id="3819178904835489326"><ph name="NUMBER_OF_DOWNLOADS" /> downloads deleted</translation> +<translation id="3819562311292413223">Download articles for you</translation> +<translation id="3822502789641063741">Clear site storage?</translation> +<translation id="385051799172605136">Back</translation> +<translation id="3859306556332390985">Seek forward</translation> +<translation id="3868004864571585162">Cookies, media licences and site data</translation> +<translation id="3894427358181296146">Add folder</translation> +<translation id="3895926599014793903">Force enable zoom</translation> +<translation id="3927692899758076493">Sans Serif</translation> +<translation id="3928666092801078803">Combine my data</translation> +<translation id="393697183122708255">No enabled voice search available</translation> +<translation id="3950820424414687140">Sign in</translation> +<translation id="395206256282351086">Search and site suggestions disabled</translation> +<translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> +<translation id="3967822245660637423">Download complete</translation> +<translation id="397583555483684758">Sync has stopped working</translation> +<translation id="3976396876660209797">Remove and recreate this shortcut</translation> +<translation id="3985215325736559418">Do you want to download <ph name="FILE_NAME" /> again?</translation> +<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="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> +<translation id="3997476611815694295">Unimportant storage</translation> +<translation id="4002066346123236978">Title</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# hr}other{# hrs}}</translation> +<translation id="4042870126885713738">Show suggestions when a web address does not resolve or a connection cannot be made</translation> +<translation id="4046123991198612571">Next track</translation> +<translation id="4048707525896921369">Learn about topics on websites without leaving the page. Tap to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results and other details. + +To adjust your search term, long press to select. To refine your search, slide the panel all the way up and tap the search box.</translation> +<translation id="4056223980640387499">Sepia</translation> +<translation id="4060598801229743805">Options available near the top of the screen</translation> +<translation id="4062305924942672200">Legal information</translation> +<translation id="4084682180776658562">Bookmark</translation> +<translation id="4084712963632273211">From <ph name="PUBLISHER_ORIGIN" /> – <ph name="BEGIN_DEEMPHASIZED" />delivered by Google<ph name="END_DEEMPHASIZED" /></translation> +<translation id="4084836577264234537"><ph name="MEGABYTES" /> MB downloaded</translation> +<translation id="4089831646916293264">This feature may interfere with access to premium data services provided by your operator.</translation> +<translation id="4095146165863963773">Delete app data?</translation> +<translation id="4097739989936358050">This app is running in Chrome.</translation> +<translation id="4099578267706723511">Help make Chrome better by sending usage statistics and crash reports to Google.</translation> +<translation id="410351446219883937">Autoplay</translation> +<translation id="4113030288477039509">Managed by your administrator</translation> +<translation id="4116038641877404294">Download pages to use them offline</translation> +<translation id="4127069705158143605">{BOOKMARKS_COUNT,plural, =1{%1$d bookmark}other{%1$d bookmarks}}</translation> +<translation id="4149994727733219643">Simplified view for web pages</translation> +<translation id="4159800535322890630">Block sites from accessing your sensors</translation> +<translation id="4165986682804962316">Site settings</translation> +<translation id="4170011742729630528">The service is not available; try again later.</translation> +<translation id="4179980317383591987"><ph name="AMOUNT" /> used</translation> +<translation id="4181841719683918333">Languages</translation> +<translation id="4192273449750167573">Review your settings on the next screen</translation> +<translation id="4195643157523330669">Open in new tab</translation> +<translation id="4198423547019359126">No available download locations</translation> +<translation id="4209895695669353772">To get personalised content suggested by Google, turn on sync</translation> +<translation id="4226663524361240545">Notifications may vibrate the device</translation> +<translation id="4242533952199664413">Open settings</translation> +<translation id="4243710787042215766">Open in private tab</translation> +<translation id="424864128008805179">Sign out of Chrome?</translation> +<translation id="4256782883801055595">Open-source licences</translation> +<translation id="4259722352634471385">Navigation is blocked: <ph name="URL" /></translation> +<translation id="4262028915562328938">Sync error occurred, tap to get details.</translation> +<translation id="4269820728363426813">Copy link address</translation> +<translation id="4275663329226226506">Media</translation> +<translation id="4278390842282768270">Allowed</translation> +<translation id="4307992518367153382">Basics</translation> +<translation id="4351244548802238354">Close dialogue</translation> +<translation id="4378154925671717803">Phone</translation> +<translation id="4384468725000734951">Using Sogou for search</translation> +<translation id="4398088515904522762">To use this feature, turn on <ph name="BEGIN_LINK" />Activity and interactions<ph name="END_LINK" />.</translation> +<translation id="4404568932422911380">No bookmarks</translation> +<translation id="4409723563706114196">Use page predictions</translation> +<translation id="4412992751769744546">Allow third-party cookies</translation> +<translation id="4419556793104466535">Control sync, personalisation and more</translation> +<translation id="4432792777822557199">Pages in <ph name="SOURCE_LANGUAGE" /> will be translated to <ph name="TARGET_LANGUAGE" /> from now on</translation> +<translation id="4434045419905280838">Pop-ups and redirects</translation> +<translation id="4452411734226507615">Close <ph name="TAB_TITLE" /> tab</translation> +<translation id="4452548195519783679">Bookmarked to <ph name="FOLDER_NAME" /></translation> +<translation id="4453340223357552416"><ph name="FILE_NAME" /> downloaded in <ph name="PRODUCT_NAME" /></translation> +<translation id="4468959413250150279">Mute sound for a specific site.</translation> +<translation id="4472118726404937099">To sync and personalise across devices, sign in and turn on sync</translation> +<translation id="447252321002412580">Help improve Chrome's features and performance</translation> +<translation id="4479647676395637221">Ask first before allowing sites to use your camera (recommended)</translation> +<translation id="4487967297491345095">All Chrome’s app data will be deleted permanently. This includes all files, settings, accounts, databases, etc.</translation> +<translation id="4508440807153586353">Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting you'll need to reset sync. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation> +<translation id="4513387527876475750">{DAYS,plural, =1{# day ago}other{# days ago}}</translation> +<translation id="451872707440238414">Search your bookmarks</translation> +<translation id="4521489764227272523">The selected data has been removed from Chrome and your synced devices. + +Your Google Account may have other forms of browsing history such as searches and activity from other Google services at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="4532845899244822526">Choose folder</translation> +<translation id="4550003330909367850">To view or copy your password here, set screen lock on this device.</translation> +<translation id="4558311620361989323">Web page shortcuts</translation> +<translation id="4561979708150884304">No connection</translation> +<translation id="4565377596337484307">Hide password</translation> +<translation id="4570913071927164677">Details</translation> +<translation id="4572422548854449519">Sign in to managed account</translation> +<translation id="4581964774250883625">You’ve gone incognito.</translation> +<translation id="4583164079174244168">{MINUTES,plural, =1{# minute ago}other{# minutes ago}}</translation> +<translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">This offline page is from <ph name="CREATION_TIME" /> and may differ from the online version.</translation> +<translation id="4605958867780575332">Item removed: <ph name="ITEM_TITLE" /></translation> +<translation id="4616150815774728855">Open <ph name="WEBAPK_NAME" /></translation> +<translation id="4634124774493850572">Use password</translation> +<translation id="4645575059429386691">Managed by your parent</translation> +<translation id="4660011489602794167">Show keyboard</translation> +<translation id="4663756553811254707"><ph name="NUMBER_OF_BOOKMARKS" /> bookmarks deleted</translation> +<translation id="4665282149850138822"><ph name="NAME" /> was added to your Home screen</translation> +<translation id="4684427112815847243">Sync everything</translation> +<translation id="4695891336199304370">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}other{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}}</translation> +<translation id="4698034686595694889">View offline in <ph name="APP_NAME" /></translation> +<translation id="4698413471314543145">Critical functionality required to run Chrome is missing; either your Chrome installation is incomplete or not compatible with this version of Android.</translation> +<translation id="4699172675775169585">Cached images and files</translation> +<translation id="4714588616299687897">Save up to 60% of your data</translation> +<translation id="4719927025381752090">Offer to translate</translation> +<translation id="4720023427747327413">Open in <ph name="PRODUCT_NAME" /></translation> +<translation id="4720982865791209136">Help improve Chrome. <ph name="BEGIN_LINK" />Take survey<ph name="END_LINK" /></translation> +<translation id="4730876730346568982">You are switching sync accounts from <ph name="ACCOUNT_EMAIL_OLD" /> to <ph name="ACCOUNT_EMAIL_NEW" />. Your existing Chrome data is managed by <ph name="MANAGED_DOMAIN" />. This will delete your data from this device, but your data will remain in <ph name="ACCOUNT_EMAIL_OLD" />.</translation> +<translation id="473775607612524610">Update</translation> +<translation id="4738836084190194332">Last synced: <ph name="WHEN" /></translation> +<translation id="4749960740855309258">Open a new tab</translation> +<translation id="4751476147751820511">Motion or light sensors</translation> +<translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download complete.}other{# downloads complete.}}</translation> +<translation id="4766369052440583386">Data Saver is on</translation> +<translation id="4797039098279997504">Touch to return to <ph name="URL_OF_THE_CURRENT_TAB" /></translation> +<translation id="4807098396393229769">Name on card</translation> +<translation id="4807963036345170158">Data Saver is off</translation> +<translation id="4816465935029283692">Data types</translation> +<translation id="4837753911714442426">Open options to print page</translation> +<translation id="4842092870884894799">Showing password generation pop-up</translation> +<translation id="4850886885716139402">View</translation> +<translation id="4860895144060829044">Call</translation> +<translation id="4874967477260347223">Media Licenses</translation> +<translation id="4875775213178255010">Content Suggestions</translation> +<translation id="4878404682131129617">Establishing a tunnel via proxy server failed</translation> +<translation id="4881695831933465202">Open</translation> +<translation id="488187801263602086">Rename file</translation> +<translation id="4882831918239250449">Control how your browsing history is used to personalise Search, ads and more</translation> +<translation id="4883379392681899581">Leave private mode</translation> +<translation id="4885273946141277891">Unsupported number of Chrome instances.</translation> +<translation id="4910889077668685004">Payment apps</translation> +<translation id="4913161338056004800">Reset statistics</translation> +<translation id="4913169188695071480">Stop refreshing</translation> +<translation id="4915549754973153784"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /> while scanning for devices…</translation> +<translation id="4943872375798546930">No results</translation> +<translation id="4956460920135325549">Lite page delivered by Google.</translation> +<translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> is sharing your screen</translation> +<translation id="4961334780091921942">Your passwords, history & more on all devices</translation> +<translation id="4961700429721424617">You are signing out of an account managed by <ph name="MANAGED_DOMAIN" />. This will delete your Chrome data from this device, but your data will remain in your Google account.</translation> +<translation id="497421865427891073">go forward</translation> +<translation id="4988210275050210843">Downloading file (<ph name="MEGABYTES" />).</translation> +<translation id="4988526792673242964">Pages</translation> +<translation id="4996978546172906250">Share via</translation> +<translation id="5004339818306944878">Use up to 60% less data and speed up the web. Google servers will optimise the pages you visit.</translation> +<translation id="5004416275253351869">Google activity controls</translation> +<translation id="5005498671520578047">Copy password</translation> +<translation id="5011311129201317034"><ph name="SITE" /> wants to connect</translation> +<translation id="5013696553129441713">No new suggestions</translation> +<translation id="5016205925109358554">Serif</translation> +<translation id="5039804452771397117">Allow</translation> +<translation id="5040262127954254034">Privacy</translation> +<translation id="5063480226653192405">Usage</translation> +<translation id="5087580092889165836">Add card</translation> +<translation id="5100237604440890931">Collapsed – click to expand.</translation> +<translation id="510275257476243843">1 hour left</translation> +<translation id="5123685120097942451">Incognito tab</translation> +<translation id="5127805178023152808">Sync is off</translation> +<translation id="5129038482087801250">Install web app</translation> +<translation id="5139940364318403933">Learn how to use Google Drive</translation> +<translation id="515227803646670480">Clear stored data</translation> +<translation id="5152843274749979095">No supported apps installed</translation> +<translation id="5161254044473106830">Title required</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download failed.}other{# downloads failed.}}</translation> +<translation id="5168917394043976756">Open navigation drawer</translation> +<translation id="5171365962177408781">Tap to load the new tab page and view suggested articles</translation> +<translation id="5184329579814168207">Open in Chrome</translation> +<translation id="5199929503336119739">Work profile</translation> +<translation id="5210286577605176222">Jump to the previous tab</translation> +<translation id="5210365745912300556">Close tab</translation> +<translation id="5222676887888702881">Sign out</translation> +<translation id="5224771365102442243">With video</translation> +<translation id="5233638681132016545">New tab</translation> +<translation id="5240817131241497236">The settings that control sync, personalisation and other Google services in Chrome have changed. This may affect your current settings.</translation> +<translation id="5264003212305142034"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised at any time. Google may use content on sites that you visit, plus browser activity and interactions, to personalise Chrome and other Google services such as Translate, Search and ads.</translation> +<translation id="5271967389191913893">Device cannot open the content to be downloaded.</translation> +<translation id="528192093759286357">Drag from top and touch the back button to exit full screen.</translation> +<translation id="5284584623296338184">Changes to your bookmarks, history, passwords and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google account.</translation> +<translation id="5300589172476337783">Show</translation> +<translation id="5301954838959518834">OK, got it</translation> +<translation id="5304593522240415983">This field cannot be blank</translation> +<translation id="5308380583665731573">Connect</translation> +<translation id="5308603654685598744">When this feature is turned on, Chrome will offer to translate pages written in other languages using Google Translate.</translation> +<translation id="5313967007315987356">Add site</translation> +<translation id="5317780077021120954">Save</translation> +<translation id="5324858694974489420">Parental Settings</translation> +<translation id="5327248766486351172">Name</translation> +<translation id="5335288049665977812">Allow sites to run JavaScript (recommended)</translation> +<translation id="5345040418939504969">Deleted <ph name="BOOKMARK_TITLE" /></translation> +<translation id="5372829067651257087">URL copied.</translation> +<translation id="5391532827096253100">Your connection to this site is not secure. Site information</translation> +<translation id="5400569084694353794">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="5403644198645076998">Only allow certain sites</translation> +<translation id="5414836363063783498">Verifying…</translation> +<translation id="5423934151118863508">Your most visited pages will appear here</translation> +<translation id="5424588387303617268"><ph name="GIGABYTES" /> GB available</translation> +<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="5447765697759493033">This site will not be translated</translation> +<translation id="545042621069398927">Speeding up your download.</translation> +<translation id="5456381639095306749">Download page</translation> +<translation id="5466407412363861127">This feature uses <ph name="BEGIN_LINK" />sync<ph name="END_LINK" />.</translation> +<translation id="548278423535722844">Open in maps app</translation> +<translation id="5487521232677179737">Clear data</translation> +<translation id="5487729733663684359">Chrome updates are no longer supported for this version of Android.</translation> +<translation id="5494920125229734069">Select all</translation> +<translation id="550684401320795253">Updating Chrome...</translation> +<translation id="5512137114520586844">This account is managed by <ph name="PARENT_NAME" />.</translation> +<translation id="5514904542973294328">Disabled by the administrator of this device</translation> +<translation id="5515439363601853141">Unlock to view your password</translation> +<translation id="5515716148775388141">Your icons have moved to the bottom of the screen</translation> +<translation id="5517095782334947753">You have bookmarks, history, passwords and other settings from <ph name="FROM_ACCOUNT" />.</translation> +<translation id="5524843473235508879">Redirect blocked.</translation> +<translation id="5527082711130173040">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK1" />Update permissions<ph name="END_LINK1" />. Location access is also <ph name="BEGIN_LINK2" />turned off for this device<ph name="END_LINK2" />.</translation> +<translation id="5527111080432883924">Ask before allowing sites to read text and images from the clipboard (recommended)</translation> +<translation id="5530766185686772672">Close incognito tabs</translation> +<translation id="5534640966246046842">Site copied</translation> +<translation id="5537099431952529648">You and your parents can manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="5556459405103347317">Reload</translation> +<translation id="5561549206367097665">Waiting for network…</translation> +<translation id="557283862590186398">Chrome needs permission to access your microphone for this site.</translation> +<translation id="55737423895878184">Location and notifications are allowed</translation> +<translation id="5578795271662203820">Search <ph name="SEARCH_ENGINE" /> for this image</translation> +<translation id="5595485650161345191">Edit address</translation> +<translation id="5596627076506792578">More options</translation> +<translation id="5620299005957670886">Allow sites to access your sensors (recommended)</translation> +<translation id="5620928963363755975">Find your files and pages in Downloads from the More Options button</translation> +<translation id="5626134646977739690">Name:</translation> +<translation id="5639724618331995626">Allow all sites</translation> +<translation id="5648166631817621825">Last 7 days</translation> +<translation id="5655963694829536461">Search your downloads</translation> +<translation id="5659593005791499971">Email</translation> +<translation id="5665379678064389456">Create event in <ph name="APP_NAME" /></translation> +<translation id="5668404140385795438">Override a website’s request to prevent zooming in</translation> +<translation id="5676636989614905379">Cannot play video on <ph name="SCREEN_NAME" />.</translation> +<translation id="5677928146339483299">Blocked</translation> +<translation id="5684874026226664614">Oops. This page could not be translated.</translation> +<translation id="5686790454216892815">File name too long</translation> +<translation id="5689516760719285838">Location</translation> +<translation id="5719837394786370183">Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your incognito tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your Internet service provider or the websites you visit.</translation> +<translation id="572328651809341494">Recent tabs</translation> +<translation id="5726692708398506830">Make everything on the page bigger</translation> +<translation id="5738816946784116349">Chrome Downloads</translation> +<translation id="5748802427693696783">Switched to standard tabs</translation> +<translation id="5749068826913805084">Chrome needs storage access to download files.</translation> +<translation id="5763382633136178763">Incognito tabs</translation> +<translation id="5763514718066511291">Tap to copy the URL for this app</translation> +<translation id="5765780083710877561">Description:</translation> +<translation id="5777170031995031090">Control how Google uses your browsing history to personalise Search, ads and other Google services.</translation> +<translation id="5793665092639000975">Using <ph name="SPACE_USED" /> of <ph name="SPACE_AVAILABLE" /></translation> +<translation id="5804241973901381774">Permissions</translation> +<translation id="5809361687334836369">{HOURS,plural, =1{# hour ago}other{# hours ago}}</translation> +<translation id="5817918615728894473">Pair</translation> +<translation id="583281660410589416">Unknown</translation> +<translation id="5833397272224757657">Uses content on sites that you visit, plus browser activity and interactions, for personalisation</translation> +<translation id="5833984609253377421">Share link</translation> +<translation id="584427517463557805">Selected private tab</translation> +<translation id="5854790677617711513">Older than 30 days</translation> +<translation id="5858741533101922242">Chrome is unable to turn on Bluetooth adaptor</translation> +<translation id="5860033963881614850">Off</translation> +<translation id="5862731021271217234">To get your tabs from your other devices, turn on sync</translation> +<translation id="5864174910718532887">Details: Sorted by site name</translation> +<translation id="5864419784173784555">Waiting for another download…</translation> +<translation id="5865733239029070421">Automatically sends usage statistics and crash reports to Google</translation> +<translation id="5869522115854928033">Saved passwords</translation> +<translation id="5878455346526065919">Block ads from sites that tend to show intrusive ads</translation> +<translation id="5902828464777634901">All local data stored by this website, including cookies, will be deleted.</translation> +<translation id="5911030830365207728">Google Translate</translation> +<translation id="5916664084637901428">On</translation> +<translation id="5919204609460789179">Update <ph name="PRODUCT_NAME" /> to start sync</translation> +<translation id="5937580074298050696"><ph name="AMOUNT" /> saved</translation> +<translation id="5939518447894949180">Reset</translation> +<translation id="5942872142862698679">Using Google for search</translation> +<translation id="5952764234151283551">Sends the URL of a page that you're trying to reach to Google</translation> +<translation id="5956665950594638604">Open the Chrome Help Centre in a new tab</translation> +<translation id="5958275228015807058">Find your files and pages in Downloads</translation> +<translation id="5962718611393537961">Tap to collapse</translation> +<translation id="5990142338020175451">More personal Google services, such as better page suggestions</translation> +<translation id="6000066717592683814">Keep Google</translation> +<translation id="6005538289190791541">Suggested password</translation> +<translation id="6039379616847168523">Jump to the next tab</translation> +<translation id="6040143037577758943">Close</translation> +<translation id="6042308850641462728">More</translation> +<translation id="604996488070107836"><ph name="FILE_NAME" /> download failed due to an unknown error.</translation> +<translation id="605721222689873409">YY</translation> +<translation id="6075798973483050474">Edit home page</translation> +<translation id="60923314841986378"><ph name="HOURS" /> hours left</translation> +<translation id="60924377787140961">More articles will appear soon. Enjoy your afternoon!</translation> +<translation id="6099151465289169210">Switched to private tabs</translation> +<translation id="6108923351542677676">Setup in progress…</translation> +<translation id="6111020039983847643">data used</translation> +<translation id="6112702117600201073">Refreshing page</translation> +<translation id="6127379762771434464">Item removed</translation> +<translation id="6140912465461743537">Country/Region</translation> +<translation id="6154478581116148741">Turn on screen lock in Settings to export your passwords from this device</translation> +<translation id="6159335304067198720"><ph name="PERCENT" /> data savings</translation> +<translation id="6165508094623778733">Learn more</translation> +<translation id="6177111841848151710">Blocked for current search engine</translation> +<translation id="6177390657002841081">Turn on Data Saver</translation> +<translation id="6181444274883918285">Add site exception</translation> +<translation id="618993374665929060">More like this opened at full height</translation> +<translation id="6192333916571137726">Download File</translation> +<translation id="6192792657125177640">Exceptions</translation> +<translation id="6206551242102657620">Connection is secure. Site information</translation> +<translation id="6210748933810148297">Not <ph name="EMAIL" />?</translation> +<translation id="6216432067784365534"><ph name="NAME_OF_LIST_ITEM" /> Options</translation> +<translation id="6221633008163990886">Unlock to export your passwords</translation> +<translation id="6232535412751077445">Enabling “Do Not Track” means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request and how the request is interpreted. + +For example, some websites may respond to this request by showing you ads that aren’t based on other websites that you’ve visited. Many websites will still collect and use your browsing data – for example to improve security, to provide content, ads and recommendations and to generate reporting statistics.</translation> +<translation id="6255999984061454636">Content suggestions</translation> +<translation id="6277522088822131679">There was a problem printing the page. Please try again.</translation> +<translation id="6295158916970320988">All sites</translation> +<translation id="629730747756840877">Account</translation> +<translation id="6303969859164067831">Sign out and turn off sync</translation> +<translation id="6320088164292336938">Vibrate</translation> +<translation id="6324034347079777476">Android system sync disabled</translation> +<translation id="6333140779060797560">Share via <ph name="APPLICATION" /></translation> +<translation id="6336451774241870485">New private tab</translation> +<translation id="6337234675334993532">Encryption</translation> +<translation id="6341580099087024258">Ask where to save files</translation> +<translation id="6343192674172527289">No downloads found</translation> +<translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}}</translation> +<translation id="6364438453358674297">Remove suggestion from history?</translation> +<translation id="6378173571450987352">Details: Sorted by amount of data used</translation> +<translation id="6383961787135158834">Clear Site Storage…</translation> +<translation id="6388207532828177975">Clear & reset</translation> +<translation id="6393863479814692971">Chrome needs permission to access your camera and microphone for this site.</translation> +<translation id="6395288395575013217">LINK</translation> +<translation id="6404511346730675251">Edit bookmark</translation> +<translation id="6406506848690869874">Sync</translation> +<translation id="641643625718530986">Print…</translation> +<translation id="6416782512398055893">Downloaded <ph name="MBS" /> MB</translation> +<translation id="6433501201775827830">Choose your search engine</translation> +<translation id="6437478888915024427">Page info</translation> +<translation id="6447842834002726250">Cookies</translation> +<translation id="6448273550210938826">Search and URL suggestions</translation> +<translation id="6461962085415701688">Can’t open file</translation> +<translation id="6475951671322991020">Download video</translation> +<translation id="6482749332252372425"><ph name="FILE_NAME" /> download failed due to lack of storage space.</translation> +<translation id="6496823230996795692">To use <ph name="APP_NAME" /> for the first time, please connect to the Internet.</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6534565668554028783">Google took too long to respond</translation> +<translation id="6538442820324228105">Downloaded <ph name="GBS" /> GB</translation> +<translation id="654446541061731451">Select a tab to beam</translation> +<translation id="6545017243486555795">Clear All Data</translation> +<translation id="6556716549745717622">Block if site tends to show intrusive ads (recommended)</translation> +<translation id="6560414384669816528">Search with Sogou</translation> +<translation id="6566259936974865419">Chrome has saved you <ph name="GIGABYTES" /> GB</translation> +<translation id="6573096386450695060">Always allow</translation> +<translation id="6573431926118603307">Tabs that you've opened in Chrome on your other devices will appear here.</translation> +<translation id="6575643671698722332">Reset failed. Ensure that your device is online and try again.</translation> +<translation id="6583199322650523874">Bookmark the current page</translation> +<translation id="6584721918629302382">AR</translation> +<translation id="6593061639179217415">Desktop site</translation> +<translation id="6600954340915313787">Copied to Chrome</translation> +<translation id="6608650720463149374"><ph name="GIGABYTES" /> GB</translation> +<translation id="6610147964972079463">Close private tabs</translation> +<translation id="6612358246767739896">Protected content</translation> +<translation id="6627583120233659107">Edit folder</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6643649862576733715">Sort by amount of data saved</translation> +<translation id="6648977384226967773">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}other{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}}</translation> +<translation id="6656545060687952787">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK" />Update permissions<ph name="END_LINK" /></translation> +<translation id="6657585470893396449">Password</translation> +<translation id="6659594942844771486">Tab</translation> +<translation id="666268767214822976">Use a prediction service to show related queries and popular websites as you type in the address bar</translation> +<translation id="666731172850799929">Open in <ph name="APP_NAME" /></translation> +<translation id="666981079809192359">Chrome Privacy Notice</translation> +<translation id="6697492270171225480">Show suggestions for similar pages when a page can't be found</translation> +<translation id="6697947395630195233">Chrome needs access to your location to share your location with this site.</translation> +<translation id="6698801883190606802">Manage synced data</translation> +<translation id="6710213216561001401">Previous</translation> +<translation id="6712388303105732168">See more like this from Google using the More Like This button</translation> +<translation id="6738867403308150051">Downloading…</translation> +<translation id="6746124502594467657">Move down</translation> +<translation id="6762156594045689028">To change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="6766622839693428701">Swipe down to close.</translation> +<translation id="6770414673596662518">Chrome’s Safe Browsing system will also be used to detect malicious pages and protect you from phishing, malware and harmful downloads.</translation> +<translation id="6776813977906306442">Download videos to watch later using the Download button</translation> +<translation id="6790428901817661496">Play</translation> +<translation id="679325081238418596">Get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="6820607729870073286">You have no saved website settings.</translation> +<translation id="6820686453637990663">CVC</translation> +<translation id="6831043979455480757">Translate</translation> +<translation id="6846298663435243399">Loading…</translation> +<translation id="685040365210406336">Make no changes</translation> +<translation id="6850409657436465440">Your download is still in progress</translation> +<translation id="6850830437481525139"><ph name="TAB_COUNT" /> tabs closed</translation> +<translation id="6864459304226931083">Download image</translation> +<translation id="6865313869410766144">Autofill form data</translation> +<translation id="6868088497967843822">Sign in to get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="688738109438487280">Add existing data to <ph name="TO_ACCOUNT" />.</translation> +<translation id="6891726759199484455">Unlock to copy your password</translation> +<translation id="6891858906296486776">{OPEN_TABS,plural, =1{%1$d open tab}other{%1$d open tabs}}</translation> +<translation id="6896758677409633944">Copy</translation> +<translation id="6910211073230771657">Deleted</translation> +<translation id="6912998170423641340">Block sites from reading text and images from the clipboard</translation> +<translation id="6914783257214138813">Your passwords will be visible to anyone who can see the exported file.</translation> +<translation id="6942665639005891494">Change the default download location at any time using the Settings menu option</translation> +<translation id="6945221475159498467">Select</translation> +<translation id="6963642900430330478">This page is dangerous. Site information</translation> +<translation id="6963766334940102469">Delete bookmarks</translation> +<translation id="6965382102122355670">OK</translation> +<translation id="6978479750597523876">Reset translate settings</translation> +<translation id="6979737339423435258">All time</translation> +<translation id="6981982820502123353">Accessibility</translation> +<translation id="6985347914332179298">No downloads here</translation> +<translation id="6990079615885386641">Get the app from the Google Play Store: <ph name="APP_ACTION" /></translation> +<translation id="699220179437400583">Automatically report details of possible security incidents to Google</translation> +<translation id="6992289844737586249">Ask first before allowing sites to use your microphone (recommended)</translation> +<translation id="7016516562562142042">Allowed for current search engine</translation> +<translation id="7021515813996758557"><ph name="FILE_NAME" /> downloaded</translation> +<translation id="7022756207310403729">Open in browser</translation> +<translation id="702463548815491781">Recommended when TalkBack or Switch Access are on</translation> +<translation id="7029809446516969842">Passwords</translation> +<translation id="7031882061095297553">Sync to</translation> +<translation id="7032663816368481562">When you tap More like this <ph name="ICON" /> in the address bar, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="7034608350006174882">Cards and addresses using Google Pay</translation> +<translation id="7053983685419859001">Block</translation> +<translation id="7055152154916055070">Redirect blocked:</translation> +<translation id="7062545763355031412">Accept and switch accounts</translation> +<translation id="7063006564040364415">Could not connect to the sync server.</translation> +<translation id="7066151586745993502">{NUM_SELECTED,plural, =1{1 selected}other{# selected}}</translation> +<translation id="7077143737582773186">SD Card</translation> +<translation id="7087918508125750058"><ph name="ITEM_COUNT" /> selected. Options available near top of the screen</translation> +<translation id="7108338896283013870">Hide</translation> +<translation id="7121362699166175603">Clears history and autocompletions in the address bar. 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="7128222689758636196">Allow for current search engine</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7139148793369023665">More like this closed</translation> +<translation id="7141896414559753902">Block sites from showing pop-ups and redirects (recommended)</translation> +<translation id="7149158118503947153"><ph name="BEGIN_LINK" />Load original page<ph name="END_LINK" /> from <ph name="DOMAIN_NAME" /></translation> +<translation id="7149893636342594995">Last 24 Hours</translation> +<translation id="7176368934862295254"><ph name="KILOBYTES" /> KB</translation> +<translation id="7177466738963138057">You can change this later in Settings</translation> +<translation id="7180611975245234373">Refresh</translation> +<translation id="7189372733857464326">Waiting for Google Play Services to finish updating</translation> +<translation id="7189598951263744875">Share...</translation> +<translation id="7191430249889272776">Tab opened in background.</translation> +<translation id="723171743924126238">Select images</translation> +<translation id="7243308994586599757">Options available near bottom of the screen</translation> +<translation id="7250468141469952378"><ph name="ITEM_COUNT" /> selected</translation> +<translation id="7251326866581677552">Blocked from some sites</translation> +<translation id="7253272406652746122">Add a Google account from the Accounts page in your device’s Settings app.</translation> +<translation id="7274013316676448362">Blocked site</translation> +<translation id="729975465115245577">Your device doesn’t have an app to store the passwords file.</translation> +<translation id="7302081693174882195">Details: Sorted by amount of data saved</translation> +<translation id="7333031090786104871">Still adding previous site</translation> +<translation id="7352939065658542140">VIDEO</translation> +<translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Share 1 selected item}other{Share # selected items}}</translation> +<translation id="7359002509206457351">Access payment methods</translation> +<translation id="7366340029385295517">Casting to <ph name="SCREEN_NAME" /></translation> +<translation id="7375125077091615385">Type:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> +<translation id="7400418766976504921">URL</translation> +<translation id="7403691278183511381">Chrome First Run Experience</translation> +<translation id="741204030948306876">Yes, I'm in</translation> +<translation id="7413229368719586778">Start date <ph name="DATE" /></translation> +<translation id="7423098979219808738">Ask first</translation> +<translation id="7423538860840206698">Blocked from reading clipboard</translation> +<translation id="7431991332293347422">Control how your browsing history is used to personalise Search and more</translation> +<translation id="7437998757836447326">Sign out of Chrome</translation> +<translation id="7444811645081526538">More categories</translation> +<translation id="7445411102860286510">Allow sites to automatically play muted videos (recommended)</translation> +<translation id="7454641608352164238">Not enough space</translation> +<translation id="7455923816558154057">Tap to view</translation> +<translation id="7465104139234185284">Close all private tabs</translation> +<translation id="7473891865547856676">No Thanks</translation> +<translation id="7475192538862203634">If you’re seeing this frequently, try these <ph name="BEGIN_LINK" />suggestions<ph name="END_LINK" />.</translation> +<translation id="7475688122056506577">SD card not found. Some of your files may be missing.</translation> +<translation id="748127970106343339">Confirm device credential deletion</translation> +<translation id="7481312909269577407">Forward</translation> +<translation id="7493994139787901920"><ph name="VERSION" /> (Updated <ph name="TIME_SINCE_UPDATE" />)</translation> +<translation id="7494879913343971937">Show passwords</translation> +<translation id="7494974237137038751">data saved</translation> +<translation id="7498271377022651285">Please wait…</translation> +<translation id="7514365320538308">Download</translation> +<translation id="751961395872307827">Can't connect to the site</translation> +<translation id="7521387064766892559">JavaScript</translation> +<translation id="7542481630195938534">Can’t get suggestions</translation> +<translation id="7562080006725997899">Clear browsing data</translation> +<translation id="756809126120519699">Cleared Chrome data</translation> +<translation id="757524316907819857">Block sites from playing protected content</translation> +<translation id="7589445247086920869">Block for current search engine</translation> +<translation id="7593557518625677601">Open Android settings and re-enable Android system sync to start Chrome sync</translation> +<translation id="7596558890252710462">Operating system</translation> +<translation id="7605594153474022051">Sync isn't working</translation> +<translation id="7612619742409846846">Signed in to Google as</translation> +<translation id="7619072057915878432"><ph name="FILE_NAME" /> download failed due to network failures.</translation> +<translation id="7624880197989616768"><ph name="BEGIN_LINK1" />Get help<ph name="END_LINK1" /> or <ph name="BEGIN_LINK2" />re-scan<ph name="END_LINK2" /></translation> +<translation id="7626032353295482388">Welcome to Chrome</translation> +<translation id="7638584964844754484">Incorrect passphrase</translation> +<translation id="7641339528570811325">Clear browsing data…</translation> +<translation id="7648422057306047504">Encrypt passwords with Google credentials</translation> +<translation id="7649070708921625228">Help</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7665369617277396874">Add account</translation> +<translation id="7682724950699840886">Try the following tips: make sure that there is enough space on your device; try to export again.</translation> +<translation id="7698359219371678927">Create email in <ph name="APP_NAME" /></translation> +<translation id="7704317875155739195">Auto-complete searches and URLs</translation> +<translation id="773466115871691567">Always translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> +<translation id="773905249182896430">Protects you and your device from dangerous sites</translation> +<translation id="7762668264895820836">SD Card <ph name="SD_CARD_NUMBER" /></translation> +<translation id="7764225426217299476">Add address</translation> +<translation id="7765158879357617694">Move</translation> +<translation id="7769602470925380267">Accept and sign out</translation> +<translation id="7772032839648071052">Confirm passphrase</translation> +<translation id="7774809984919390718">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}other{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}}</translation> +<translation id="7781829728241885113">Yesterday</translation> +<translation id="7791543448312431591">Add</translation> +<translation id="780301667611848630">No, thank you</translation> +<translation id="7810647596859435254">Open with…</translation> +<translation id="7821588508402923572">Your data savings will appear here</translation> +<translation id="7832327313660264358">The data that you sync to Google and the features that you use will not change</translation> +<translation id="7837721118676387834">Allow auto-play of muted videos for a specific site.</translation> +<translation id="7846076177841592234">Cancel selection</translation> +<translation id="784934925303690534">Time range</translation> +<translation id="7851858861565204677">Other Devices</translation> +<translation id="7854964836418414587">Close more like this</translation> +<translation id="7875915731392087153">Create email</translation> +<translation id="7876243839304621966">Remove all</translation> +<translation id="7882131421121961860">No history found</translation> +<translation id="7882806643839505685">Allow sound for a specific site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Downloading file.}other{Downloading # files.}}</translation> +<translation id="7929962904089429003">Opening the menu</translation> +<translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> is out of date.</translation> +<translation id="7947953824732555851">Accept and sign in</translation> +<translation id="7963646190083259054">Vendor:</translation> +<translation id="7981313251711023384">Preload pages for faster browsing and searching</translation> +<translation id="79859296434321399">To view augmented reality content, install ARCore</translation> +<translation id="7986741934819883144">Select a contact</translation> +<translation id="7987073022710626672">Chrome Terms of Service</translation> +<translation id="7987764905897278458">Get more Google smarts</translation> +<translation id="7998918019931843664">Re-open closed tab</translation> +<translation id="7999064672810608036">Are you sure that you want to clear all local data, including cookies, and reset all permissions for this website?</translation> +<translation id="8004582292198964060">Browser</translation> +<translation id="8007176423574883786">Turned off for this device</translation> +<translation id="8015452622527143194">Return everything on the page to default size</translation> +<translation id="802154636333426148">Download failed</translation> +<translation id="8026334261755873520">Clear browsing data</translation> +<translation id="8035133914807600019">New folder…</translation> +<translation id="8037411810184515274">VR</translation> +<translation id="8037686209485537503">More like this</translation> +<translation id="8037750541064988519"><ph name="DAYS" /> days left</translation> +<translation id="804335162455518893">SD card not found</translation> +<translation id="805047784848435650">Based on your browsing history</translation> +<translation id="8051695050440594747"><ph name="MEGABYTES" /> MB available</translation> +<translation id="8058746566562539958">Open in new Chrome tab</translation> +<translation id="8063895661287329888">Failed to add bookmark.</translation> +<translation id="806745655614357130">Keep my data separate</translation> +<translation id="8068648041423924542">Unable to select certificate.</translation> +<translation id="8073388330009372546">Open image in new tab</translation> +<translation id="8084114998886531721">Saved password</translation> +<translation id="8087000398470557479">This content is from <ph name="DOMAIN_NAME" />, delivered by Google.</translation> +<translation id="8103578431304235997">Incognito Tab</translation> +<translation id="8105951947646329362">Suggest related pages</translation> +<translation id="8109613176066109935">To get your bookmarks on all your devices, turn on sync</translation> +<translation id="8116925261070264013">Muted</translation> +<translation id="813082847718468539">View site information</translation> +<translation id="8156139159503939589">What languages do you read?</translation> +<translation id="8168435359814927499">Content</translation> +<translation id="8186512483418048923"><ph name="FILES" /> files left</translation> +<translation id="8190358571722158785">1 day left</translation> +<translation id="8200772114523450471">Resume</translation> +<translation id="8209050860603202033">Open image</translation> +<translation id="8220488350232498290"><ph name="GIGABYTES" /> GB downloaded</translation> +<translation id="8249310407154411074">Move to top</translation> +<translation id="8250920743982581267">Documents</translation> +<translation id="825412236959742607">This page uses too much memory, so Chrome removed some content.</translation> +<translation id="8260126382462817229">Try signing in again</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8266862848225348053">Download location</translation> +<translation id="8274165955039650276">See downloads</translation> +<translation id="8283853025636624853">Syncing to <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8310344678080805313">Standard tabs</translation> +<translation id="8313455859591948645">Edit startup page</translation> +<translation id="8316092324682955408"><ph name="DOMAIN_NAME" /> and more sites</translation> +<translation id="8339163506404995330">Pages in <ph name="LANGUAGE" /> will not be translated</translation> +<translation id="8349013245300336738">Sort by amount of data used</translation> +<translation id="8372893542064058268">Allow Background Sync for a specific site.</translation> +<translation id="8374821112118309944">You need to update TalkBack to a newer version.</translation> +<translation id="8393700583063109961">Send message</translation> +<translation id="8413126021676339697">Show full history</translation> +<translation id="8428213095426709021">Settings</translation> +<translation id="8438566539970814960">Make searches and browsing better</translation> +<translation id="8441146129660941386">Seek backward</translation> +<translation id="8445448999790540984">Can’t export passwords</translation> +<translation id="8447861592752582886">Revoke device permission</translation> +<translation id="8477071352266846533">Sync off for <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8487700953926739672">Available offline</translation> +<translation id="8489271220582375723">Open the history page</translation> +<translation id="8493948351860045254">Free up space</translation> +<translation id="8497726226069778601">Nothing to see here… yet</translation> +<translation id="8503559462189395349">Chrome Passwords</translation> +<translation id="8503813439785031346">Username</translation> +<translation id="8504988642345501642">When you scroll up, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="8507520749471379845">Passwords available</translation> +<translation id="8514477925623180633">Export passwords stored with Chrome</translation> +<translation id="8514577642972634246">Enter incognito mode</translation> +<translation id="851751545965956758">Block sites from connecting to devices</translation> +<translation id="8523928698583292556">Delete stored password</translation> +<translation id="854522910157234410">Open this page:</translation> +<translation id="8558485628462305855">To view augmented reality content, update ARCore</translation> +<translation id="8559990750235505898">Offer to translate pages in other languages</translation> +<translation id="8562452229998620586">Your saved passwords will appear here.</translation> +<translation id="8569404424186215731">since <ph name="DATE" /></translation> +<translation id="8571213806525832805">Last 4 weeks</translation> +<translation id="857509777403223202">More articles will appear soon. Enjoy your evening!</translation> +<translation id="857943718398505171">Allowed (recommended)</translation> +<translation id="8583805026567836021">Clearing account data</translation> +<translation id="8609465669617005112">Move up</translation> +<translation id="8616006591992756292">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="8617240290563765734">Open the suggested URL specified in the downloaded content?</translation> +<translation id="862875433388403934">Content (films, music, etc.) downloaded in other applications may no longer be playable until those applications re-acquire licences based on a new device credential. To obtain new licences, connect to the Internet and play your downloaded content.</translation> +<translation id="8636825310635137004">To get your tabs from your other devices, turn on sync.</translation> +<translation id="8641930654639604085">Try to block mature sites</translation> +<translation id="8662811608048051533">Signs you out of most sites.</translation> +<translation id="8664979001105139458">File name already exists</translation> +<translation id="8676374126336081632">Clear input</translation> +<translation id="8687353297350450808">{N_BARS,plural, =1{Signal Strength Level: # bar}other{Signal Strength Level: # bars}}</translation> +<translation id="868929229000858085">Search your contacts</translation> +<translation id="869891660844655955">Expiry date</translation> +<translation id="8719023831149562936">Can’t beam current tab</translation> +<translation id="8725066075913043281">Try again</translation> +<translation id="8728487861892616501">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8730621377337864115">Done</translation> +<translation id="8748850008226585750">Contents hidden</translation> +<translation id="8751914237388039244">Select an image</translation> +<translation id="8788968922598763114">Reopen the last closed tab</translation> +<translation id="8812260976093120287">On some websites, you can pay with above supported payment apps on your device.</translation> +<translation id="8816439037877937734"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome's <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8820817407110198400">Bookmarks</translation> +<translation id="8823704566850948458">Suggest password...</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> +<translation id="883806473910249246">An error occurred while downloading the content.</translation> +<translation id="8840953339110955557">This page may differ from the online version.</translation> +<translation id="8847988622838149491">USB</translation> +<translation id="8853345339104747198"><ph name="TAB_TITLE" />, tab</translation> +<translation id="885701979325669005">Storage</translation> +<translation id="8901170036886848654">No bookmarks found</translation> +<translation id="8909135823018751308">Share…</translation> +<translation id="8912362522468806198">Google Account</translation> +<translation id="8920114477895755567">Waiting for details of parents.</translation> +<translation id="8922289737868596582">Download pages from the More Options button to use them offline</translation> +<translation id="8941729603749328384">www.example.com</translation> +<translation id="8942627711005830162">Open in other window</translation> +<translation id="8951232171465285730">Chrome has saved you <ph name="MEGABYTES" /> MB</translation> +<translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> +<translation id="8972098258593396643">Download to default folder?</translation> +<translation id="8979405271719829084">Download videos to watch later</translation> +<translation id="8981454092730389528">Google Activity Controls</translation> +<translation id="8983677657449185470">Help improve Safe Browsing</translation> +<translation id="8986494364107987395">Automatically send usage statistics and crash reports to Google</translation> +<translation id="8993760627012879038">Open a new tab in Incognito mode</translation> +<translation id="8998729206196772491">You are signing in with an account managed by <ph name="MANAGED_DOMAIN" /> and giving its administrator control over your Chrome data. Your data will become permanently tied to this account. Signing out of Chrome will delete your data from this device, but it will remain stored in your Google account.</translation> +<translation id="9019902583201351841">Managed by your parents</translation> +<translation id="9040142327097499898">Notifications are allowed. Location is off for this device.</translation> +<translation id="9050666287014529139">Passphrase</translation> +<translation id="9060538597317784206">View app <ph name="APP_NAME" /> on the Play Store. Rating: <ph name="APP_RATING" />.</translation> +<translation id="9063523880881406963">Turn off Request desktop site</translation> +<translation id="9065203028668620118">Edit</translation> +<translation id="9070377983101773829">Start voice search</translation> +<translation id="9071742570345586758">To view virtual reality content, install Google VR Services</translation> +<translation id="9074336505530349563">To get personalised content suggested by Google, sign in and turn on sync</translation> +<translation id="9080642952018487277">Enter private mode</translation> +<translation id="9086455579313502267">Unable to access the network</translation> +<translation id="9099018167121903954"><ph name="KILOBYTES" /> KB downloaded</translation> +<translation id="9100505651305367705">Offer to show articles in simplified view, when supported</translation> +<translation id="9100610230175265781">Passphrase required</translation> +<translation id="9100939710791843300">Tap the home button to load the new tab page and view suggested articles</translation> +<translation id="9133515669113036225">Reset device credentials</translation> +<translation id="9133703968756164531"><ph name="ITEM_NAME" /> (<ph name="ITEM_ID" />)</translation> +<translation id="9137013805542155359">Show original</translation> +<translation id="9139068048179869749">Ask before allowing sites to send notifications (recommended)</translation> +<translation id="9155898266292537608">You can also search with a quick tap on a word</translation> +<translation id="9188680907066685419">Sign out of managed account</translation> +<translation id="9204836675896933765">1 file left</translation> +<translation id="9206873250291191720">A</translation> +<translation id="9218033835049520260">Suggest strong password...</translation> +<translation id="9219103736887031265">Images</translation> +<translation id="932327136139879170">Home</translation> +<translation id="932599481871055447">Save data and browse faster</translation> +<translation id="938850635132480979">Error: <ph name="ERROR_CODE" /></translation> +<translation id="945522503751344254">Send feedback</translation> +<translation id="945632385593298557">Access your microphone</translation> +<translation id="951339005376969845">Delete existing data. You can retrieve it by switching back to <ph name="FROM_ACCOUNT" />.</translation> +<translation id="95817756606698420">Chrome can use <ph name="BEGIN_BOLD" />Sogou<ph name="END_BOLD" /> for search in China. You can change this in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="970715775301869095"><ph name="MINUTES" /> mins left</translation> +<translation id="974555521953189084">Enter your passphrase to start sync</translation> +<translation id="981121421437150478">Offline</translation> +<translation id="982182592107339124">This will clear data for all sites, including:</translation> +<translation id="983192555821071799">Close all tabs</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_mr.xtb b/chrome/android/java/strings/translations/android_chrome_strings_mr.xtb new file mode 100644 index 0000000..7627fc9 --- /dev/null +++ b/chrome/android/java/strings/translations/android_chrome_strings_mr.xtb
@@ -0,0 +1,1056 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="mr"> +<translation id="1006017844123154345">Open Online</translation> +<translation id="1036727731225946849">Adding <ph name="WEBAPK_NAME" />...</translation> +<translation id="1041308826830691739">From websites</translation> +<translation id="1049743911850919806">Incognito</translation> +<translation id="1054301162707478098">You’ve gone private.</translation> +<translation id="10614374240317010">Never saved</translation> +<translation id="1067922213147265141">Other Google services</translation> +<translation id="1068672505746868501">Never translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="10713315585330490"><ph name="FILE_SIZE" /> – <ph name="DESCRIPTION" /></translation> +<translation id="1080790410959514870">You are signing out of an account managed by <ph name="DOMAIN_NAME" />. This will delete the Chrome data stored on this device, but the data will remain in your Google Account.</translation> +<translation id="1105960400813249514">Screen Capture</translation> +<translation id="1111673857033749125">Bookmarks saved on your other devices will appear here.</translation> +<translation id="1113597929977215864">Show simplified view</translation> +<translation id="1121094540300013208">Usage and crash reports</translation> +<translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download pending.}other{# downloads pending.}}</translation> +<translation id="1145536944570833626">Delete existing data.</translation> +<translation id="1146678959555564648">Enter VR</translation> +<translation id="114721135501989771">Get Google smarts in Chrome</translation> +<translation id="1157102636231978136">Your browsing data and activity, synced to your Google account</translation> +<translation id="116280672541001035">Used</translation> +<translation id="1172593791219290334">Startup Page</translation> +<translation id="1175310183703641346">Your bookmarks, history, passwords and more will no longer be synced to your Google account</translation> +<translation id="1178581264944972037">Pause</translation> +<translation id="1181037720776840403">Remove</translation> +<translation id="1197267115302279827">Move bookmarks</translation> +<translation id="119944043368869598">Clear all</translation> +<translation id="1201402288615127009">Next</translation> +<translation id="1204037785786432551">Download link</translation> +<translation id="1206892813135768548">Copy link text</translation> +<translation id="1208340532756947324">To sync and personalise across devices, turn on sync</translation> +<translation id="1209206284964581585">Hide for now</translation> +<translation id="123724288017357924">Reload the current page, ignoring cached content</translation> +<translation id="124116460088058876">More languages</translation> +<translation id="124678866338384709">Close current tab</translation> +<translation id="1258753120186372309">Google doodle: <ph name="DOODLE_DESCRIPTION" /></translation> +<translation id="1259100630977430756">Pages that you view in private tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your private tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going private doesn’t hide your browsing from your employer, your Internet service provider or the websites that you visit.</translation> +<translation id="127138278192656016">Use sync and all services</translation> +<translation id="1272079795634619415">Stop</translation> +<translation id="1283039547216852943">Tap to expand</translation> +<translation id="1285320974508926690">Never translate this site</translation> +<translation id="1291207594882862231">Clear history, cookies, site data, cache…</translation> +<translation id="129553762522093515">Recently closed</translation> +<translation id="1326317727527857210">To get your tabs from your other devices, sign in to Chrome.</translation> +<translation id="1332501820983677155">Google Chrome feature shortcuts</translation> +<translation id="1360432990279830238">Sign out and turn off sync?</translation> +<translation id="136248372334525878">Preload pages for faster loading and offline reading</translation> +<translation id="1369915414381695676">Site <ph name="SITE_NAME" /> added</translation> +<translation id="1373696734384179344">Insufficient memory to download the selected content.</translation> +<translation id="1376578503827013741">Computing…</translation> +<translation id="138361230106469022">Hi, <ph name="FULL_NAME" /></translation> +<translation id="1383876407941801731">Search</translation> +<translation id="1384959399684842514">Download paused</translation> +<translation id="1389974829397082527">No bookmarks here</translation> +<translation id="1397811292916898096">Search with <ph name="PRODUCT_NAME" /></translation> +<translation id="1397854323885047133">Sync and personalisation</translation> +<translation id="1404122904123200417">Embedded in <ph name="WEBSITE_URL" /></translation> +<translation id="1406000523432664303">“Do Not Track”</translation> +<translation id="1407135791313364759">Open all</translation> +<translation id="1409426117486808224">Simplified view for open tabs</translation> +<translation id="1409879593029778104"><ph name="FILE_NAME" /> download prevented because file already exists.</translation> +<translation id="1414981605391750300">Contacting Google. This may take a minute…</translation> +<translation id="1416550906796893042">Application version</translation> +<translation id="1430915738399379752">Print</translation> +<translation id="1445680696957526815">Chrome’s components are incompatible with one another. Chrome may be upgrading, please try again in a few minutes. If the problem continues, try uninstalling and re-installing Chrome.</translation> +<translation id="1446450296470737166">Allow full control of MIDI devices</translation> +<translation id="145097072038377568">Turned off in Android Settings</translation> +<translation id="1477626028522505441"><ph name="FILE_NAME" /> download failed due to server issues.</translation> +<translation id="1506061864768559482">Search engine</translation> +<translation id="1513352483775369820">Bookmarks and web history</translation> +<translation id="1513858653616922153">Delete password</translation> +<translation id="1516229014686355813">Tap to Search sends the selected word and the current page as context to Google Search. You can turn it off in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="1539064842193522527">Link opened in Chrome</translation> +<translation id="1549000191223877751">Move to other window</translation> +<translation id="1553358976309200471">Update Chrome</translation> +<translation id="1566400915470565838">To use <ph name="APP_NAME" />, please connect to the Internet.</translation> +<translation id="1569387923882100876">Connected device</translation> +<translation id="1571304935088121812">Copy username</translation> +<translation id="1576370611341449972">Download occurs only on Wi-Fi</translation> +<translation id="1612196535745283361">Chrome needs location access to scan for devices. Location access is <ph name="BEGIN_LINK" />turned off for this device<ph name="END_LINK" />.</translation> +<translation id="162035744160882748">Turn on sync, personalisation and other Google services</translation> +<translation id="1620510694547887537">Camera</translation> +<translation id="1623104350909869708">Prevent this page from creating additional dialogues</translation> +<translation id="1628019612362412531">{NUM_SELECTED,plural, =1{Remove 1 selected item}other{Remove # selected items}}</translation> +<translation id="1641113438599504367">Safe Browsing</translation> +<translation id="164269334534774161">You are viewing an offline copy of this page from <ph name="CREATION_TIME" /></translation> +<translation id="1644574205037202324">History</translation> +<translation id="1647391597548383849">Access your camera</translation> +<translation id="1660204651932907780">Allow sites to play sound (recommended)</translation> +<translation id="1670399744444387456">Basic</translation> +<translation id="1671236975893690980">Download pending...</translation> +<translation id="1672586136351118594">Don‘t show again</translation> +<translation id="1709438864123551175">Data Saver</translation> +<translation id="1718835860248848330">Last hour</translation> +<translation id="1729516292547892356">To view virtual reality content, update Google VR Services</translation> +<translation id="1733116627827457509"><ph name="FILE_SIZE" /> – Updated <ph name="TIME_SINCE_UPDATE" /></translation> +<translation id="1736419249208073774">Explore</translation> +<translation id="1743802530341753419">Ask before allowing sites to connect to a device (recommended)</translation> +<translation id="1749561566933687563">Sync your bookmarks</translation> +<translation id="17513872634828108">Open tabs</translation> +<translation id="1756600373018374892">Tap this button for quick access to your tabs.</translation> +<translation id="1779089405699405702">Image decoder</translation> +<translation id="1782483593938241562">End date <ph name="DATE" /></translation> +<translation id="1792959175193046959">Change the default download location at any time</translation> +<translation id="1807246157184219062">Light</translation> +<translation id="1821253160463689938">Uses cookies to remember your preferences, even if you don't visit those pages</translation> +<translation id="1829244130665387512">Find in page</translation> +<translation id="1832521218263067499">Security incidents</translation> +<translation id="1853692000353488670">New incognito tab</translation> +<translation id="1868024384445905608">Chrome now downloads files faster</translation> +<translation id="1878302395768190018">You can customise this at any time in Chrome Settings</translation> +<translation id="1880072593381090678">Popular pages from Chrome</translation> +<translation id="1883903952484604915">My files</translation> +<translation id="1887786770086287077">Location access is off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1891331835972267886"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="189172778771606813">Close navigation drawer</translation> +<translation id="1919345977826869612">Ads</translation> +<translation id="1919950603503897840">Select contacts</translation> +<translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/<ph name="FILE_SIZE_WITH_UNITS" /></translation> +<translation id="1933845786846280168">Selected Tab</translation> +<translation id="1938981467853765413">Provide feedback</translation> +<translation id="194341124344773587">Turn on permission for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1943432128510653496">Save passwords</translation> +<translation id="1944384637046898011">Encrypt all with Google password as of <ph name="TIME" /></translation> +<translation id="1946005195648379376">Control how Google uses your browsing history to personalise Search and other Google services.</translation> +<translation id="1952172573699511566">Websites will show text in your preferred language, when possible.</translation> +<translation id="195283394249132567">Personalised Google services</translation> +<translation id="1966710179511230534">Please update your sign-in details.</translation> +<translation id="1974060860693918893">Advanced</translation> +<translation id="1984937141057606926">Allowed, except third-party</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> button</translation> +<translation id="1989112275319619282">Browse</translation> +<translation id="1993768208584545658"><ph name="SITE" /> wants to pair</translation> +<translation id="1994173015038366702">Site URL</translation> +<translation id="2000419248597011803">Sends some cookies and searches from the address bar and search box to your default search engine</translation> +<translation id="2002537628803770967">Credit cards and addresses using Google Pay</translation> +<translation id="200815880754187296"><ph name="KILOBYTES" /> KB other apps</translation> +<translation id="2017836877785168846">Clears history and autocompletions in the address bar.</translation> +<translation id="2021896219286479412">Full screen site controls</translation> +<translation id="2038563949887743358">Turn on Request desktop site</translation> +<translation id="2045104531052923016"><ph name="GIGABYTES" /> GB other apps</translation> +<translation id="2063713494490388661">Tap to Search</translation> +<translation id="2079545284768500474">Undo</translation> +<translation id="2082238445998314030">Result <ph name="RESULT_NUMBER" /> of <ph name="TOTAL_RESULTS" /></translation> +<translation id="2086652334978798447">To get personalised content suggested by Google, sign in to Chrome.</translation> +<translation id="2091887806945687916">Sound</translation> +<translation id="2095887075102408547">When this feature is turned on, Chrome will use Google servers to compress pages that you visit before downloading them. Pages accessed using private connections (HTTPS) or in Incognito tabs will not be optimised or seen by Google.</translation> +<translation id="2096012225669085171">Sync and personalise across devices</translation> +<translation id="2100273922101894616">Auto Sign-in</translation> +<translation id="2111511281910874386">Go to page</translation> +<translation id="2120297377148151361">Activity and interactions</translation> +<translation id="2122601567107267586">Could not open app</translation> +<translation id="2126426811489709554">Powered by Chrome</translation> +<translation id="2131665479022868825"><ph name="DATA" /> saved</translation> +<translation id="213279576345780926">Closed <ph name="TAB_TITLE" /></translation> +<translation id="2139186145475833000">Add to Home screen</translation> +<translation id="2142289305367051020">Your favourite pages are here</translation> +<translation id="2146738493024040262">Open Instant App</translation> +<translation id="2148716181193084225">Today</translation> +<translation id="2154484045852737596">Edit card</translation> +<translation id="2154710561487035718">Copy URL</translation> +<translation id="2156074688469523661">Remaining sites (<ph name="NUMBER_OF_SITES" />)</translation> +<translation id="2206488550163399966"><ph name="APP_NAME" />, web app. <ph name="APP_URL" /></translation> +<translation id="2227444325776770048">Continue as <ph name="USER_FULL_NAME" /></translation> +<translation id="2232379019872353004">Sends some system information and page content to Google</translation> +<translation id="2234876718134438132">Sync and Google services</translation> +<translation id="2259659629660284697">Export passwords…</translation> +<translation id="2268044343513325586">Refine</translation> +<translation id="2280910239864711607">Open a new tab in private mode</translation> +<translation id="2286841657746966508">Billing address</translation> +<translation id="230115972905494466">No compatible devices found</translation> +<translation id="2315043854645842844">Client side certificate selection is not supported by the operating system.</translation> +<translation id="2321086116217818302">Preparing passwords…</translation> +<translation id="2321958826496381788">Drag the slider until you can read this comfortably. Text should look at least this big after double-tapping on a paragraph.</translation> +<translation id="2323763861024343754">Site storage</translation> +<translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised by you or your parents at any time. Google may use content on sites that you visit, as well as browsing activity and interactions, to personalise Chrome and Google services such as Translate, Search and ads.</translation> +<translation id="2328985652426384049">Can’t sign in</translation> +<translation id="2342981853652716282">Sign in to Chrome to get your bookmarks, passwords and more on all your devices.</translation> +<translation id="2343328333327081434">Installing…</translation> +<translation id="2346253980530904022">Google servers will optimise the pages that you visit, except for HTTPS and Incognito.</translation> +<translation id="2349710944427398404">Total data used by Chrome, including accounts, bookmarks and saved settings</translation> +<translation id="2351097562818989364">Your translate settings have been reset.</translation> +<translation id="2359808026110333948">Continue</translation> +<translation id="2369533728426058518">open tabs</translation> +<translation id="2387895666653383613">Text scaling</translation> +<translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> +<translation id="2410754283952462441">Choose an account</translation> +<translation id="2414672073755873541">No content here</translation> +<translation id="2414886740292270097">Dark</translation> +<translation id="2416359993254398973">Chrome needs permission to access your camera for this site.</translation> +<translation id="2426805022920575512">Choose another account</translation> +<translation id="2433507940547922241">Appearance</translation> +<translation id="2434158240863470628">Download complete <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2436117022029368436">Communicates with Google to improve browsing and Chrome</translation> +<translation id="2440823041667407902">Location access</translation> +<translation id="2450083983707403292">Do you want to start downloading <ph name="FILE_NAME" /> again?</translation> +<translation id="2476578072172137802">Site Settings</translation> +<translation id="2482878487686419369">Notifications</translation> +<translation id="2496180316473517155">Browsing history</translation> +<translation id="2498359688066513246">Help & feedback</translation> +<translation id="2501278716633472235">Go back</translation> +<translation id="2513403576141822879">For more settings that relate to privacy, security and data collection, see <ph name="BEGIN_LINK" />Sync and Google services<ph name="END_LINK" /></translation> +<translation id="2523184218357549926">Sends URLs of pages that you visit to Google</translation> +<translation id="2526148617758225454">Data Saver is on. Manage it in Settings.</translation> +<translation id="2532336938189706096">Web View</translation> +<translation id="2536728043171574184">Viewing an offline copy of this page</translation> +<translation id="2546283357679194313">Cookies and site data</translation> +<translation id="2567385386134582609">IMAGE</translation> +<translation id="2570922361219980984">Location access is also off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="257931822824936280">Expanded – click to collapse.</translation> +<translation id="2581165646603367611">This will clear cookies, cache and other data of sites Chrome doesn't think is important.</translation> +<translation id="2586657967955657006">Clipboard</translation> +<translation id="2587052924345400782">Newer version is available</translation> +<translation id="2593272815202181319">Monospace</translation> +<translation id="2612676031748830579">Card number</translation> +<translation id="2621115761605608342">Allow JavaScript for a specific site.</translation> +<translation id="2625189173221582860">Password copied</translation> +<translation id="2631006050119455616">Saved</translation> +<translation id="2633278372998075009">Private tabs</translation> +<translation id="2647434099613338025">Add language</translation> +<translation id="2650751991977523696">Download file again?</translation> +<translation id="2653659639078652383">Submit</translation> +<translation id="2677748264148917807">Leave</translation> +<translation id="2704606927547763573">Copied</translation> +<translation id="2707726405694321444">Refresh page</translation> +<translation id="2709516037105925701">Auto-fill</translation> +<translation id="271033894570825754">New</translation> +<translation id="2728754400939377704">Sort by site</translation> +<translation id="2744248271121720757">Tap a word to search instantly or see related actions</translation> +<translation id="2762000892062317888">just now</translation> +<translation id="2777555524387840389"><ph name="SECONDS" /> secs left</translation> +<translation id="2781151931089541271">1 sec left</translation> +<translation id="2803478378562657435">Showing saved passwords and password options</translation> +<translation id="2810645512293415242">Simplified page to save data and load faster.</translation> +<translation id="281504910091592009">View and manage saved passwords in your <ph name="BEGIN_LINK" />Google account<ph name="END_LINK" /></translation> +<translation id="2818669890320396765">To get your bookmarks on all your devices, sign in and turn on sync</translation> +<translation id="2836148919159985482">Touch the back button to exit full screen.</translation> +<translation id="2842985007712546952">Parent folder</translation> +<translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Previous track</translation> +<translation id="2876764156902388290">Chrome is using less data to show you this page</translation> +<translation id="2888126860611144412">About Chrome</translation> +<translation id="2891154217021530873">Stop page loading</translation> +<translation id="2900528713135656174">Create event</translation> +<translation id="2902702728133930130">Chrome failed during start-up with an unexpected error.</translation> +<translation id="290376772003165898">Page is not in <ph name="LANGUAGE" />?</translation> +<translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> +<translation id="2913331724188855103">Allow sites to save and read cookie data (recommended)</translation> +<translation id="2932150158123903946">Google <ph name="APP_NAME" /> storage</translation> +<translation id="2943166482989655199">Improve Chrome and its security by sending system and usage data to Google</translation> +<translation id="2956410042958133412">This account is managed by <ph name="PARENT_NAME_1" /> and <ph name="PARENT_NAME_2" />.</translation> +<translation id="2960796085439532066">Copyright <ph name="YEAR" /> Google Inc. All rights reserved.</translation> +<translation id="2962095958535813455">Switched to incognito tabs</translation> +<translation id="2968755619301702150">Certificate viewer</translation> +<translation id="2979025552038692506">Selected Incognito Tab</translation> +<translation id="2989523299700148168">Recently Visited</translation> +<translation id="2996291259634659425">Create passphrase</translation> +<translation id="2996809686854298943">URL required</translation> +<translation id="300526633675317032">This will clear all <ph name="SIZE_IN_KB" /> of website storage.</translation> +<translation id="3029613699374795922">Downloaded <ph name="KBS" /> KB</translation> +<translation id="3029704984691124060">Passphrases do not match</translation> +<translation id="3036750288708366620"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /></translation> +<translation id="3045654778214005718">See more like this from Google</translation> +<translation id="305593374596241526">Location is off; turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="307908932405420782">More articles will appear soon. Enjoy your morning!</translation> +<translation id="3089395242580810162">Open in incognito tab</translation> +<translation id="311456632243022227">Multiple links opened in Chrome</translation> +<translation id="3115898365077584848">Show info</translation> +<translation id="3137521801621304719">Leave incognito mode</translation> +<translation id="3148434565183091099">To get your bookmarks on all your devices, sign in to Chrome.</translation> +<translation id="3157842584138209013">See how much data you've saved from the More Options button</translation> +<translation id="3166827708714933426">Tab and window shortcuts</translation> +<translation id="3190152372525844641">Turn on permissions for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> stored data</translation> +<translation id="3207960819495026254">Bookmarked</translation> +<translation id="321773570071367578">If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="3227137524299004712">Microphone</translation> +<translation id="3232754137068452469">Web App</translation> +<translation id="3234355010754616171">New private tab</translation> +<translation id="3236059992281584593">1 min left</translation> +<translation id="3244271242291266297">MM</translation> +<translation id="3254409185687681395">Bookmark this page</translation> +<translation id="3259831549858767975">Make everything on the page smaller</translation> +<translation id="3269093882174072735">Load image</translation> +<translation id="3269956123044984603">To get your tabs from your other devices, turn on “Auto-sync data” in Android account settings.</translation> +<translation id="3282568296779691940">Sign in to Chrome</translation> +<translation id="32895400574683172">Notifications are allowed</translation> +<translation id="3295602654194328831">Hide info</translation> +<translation id="3298243779924642547">Lite</translation> +<translation id="3303414029551471755">Proceed to download the content?</translation> +<translation id="3328801116991980348">Site information</translation> +<translation id="3341058695485821946">See how much data you've saved</translation> +<translation id="3350687908700087792">Close all incognito tabs</translation> +<translation id="3365671512111106261">Unavailable when Data Saver is turned on</translation> +<translation id="3367813778245106622">Sign in again to start sync</translation> +<translation id="3377025655491224618">Private tab</translation> +<translation id="3384347053049321195">Share image</translation> +<translation id="3386292677130313581">Ask before allowing sites to know your location (recommended)</translation> +<translation id="3387650086002190359"><ph name="FILE_NAME" /> download failed due to file system errors.</translation> +<translation id="339329030417445648">This site tends to show intrusive ads</translation> +<translation id="3398320232533725830">Open the bookmarks manager</translation> +<translation id="3414952576877147120">Size:</translation> +<translation id="3443221991560634068">Reload the current page</translation> +<translation id="3452612588551937789">Sign in with your Google Account to get your bookmarks, history, passwords and other settings on all your devices.</translation> +<translation id="3485359633434254965">{FILES,plural, =1{%1$d file downloaded}other{%1$d files downloaded}}</translation> +<translation id="3492207499832628349">New incognito tab</translation> +<translation id="3493531032208478708"><ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /> about suggested content</translation> +<translation id="3518985090088779359">Accept & continue</translation> +<translation id="3522247891732774234">Update available. More options</translation> +<translation id="3527085408025491307">Folder</translation> +<translation id="3542235761944717775"><ph name="KILOBYTES" /> KB available</translation> +<translation id="3549644494707163724">Encrypt all synced data with your own sync passphrase</translation> +<translation id="3549657413697417275">Search your history</translation> +<translation id="3552151358455404883">Manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="3557336313807607643">Add to contacts</translation> +<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="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="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="3600792891314830896">Mute sites that play sound</translation> +<translation id="360207483134687714">Help improve the VR experience in Chrome</translation> +<translation id="3616113530831147358">Audio</translation> +<translation id="3620176948598597475">Resetting erases Data Saver history, including the list of visited sites.</translation> +<translation id="3630011985153972676">Allow Chrome to download articles for you when on Wi-Fi under settings.</translation> +<translation id="3632295766818638029">Unmask password</translation> +<translation id="363596933471559332">Automatically sign in to websites using stored credentials. When the feature is off, you’ll be asked for verification every time before signing in to a website.</translation> +<translation id="3661699943263275414">Third-party websites can save and read cookie data</translation> +<translation id="3662546969139119822">No history here</translation> +<translation id="3672452749423051839">Navigation error suggestions</translation> +<translation id="3692944402865947621"><ph name="FILE_NAME" /> download failed because storage location is not reachable.</translation> +<translation id="3712575778697986964">Reset Data Saver?</translation> +<translation id="3714981814255182093">Open the Find Bar</translation> +<translation id="3716182511346448902">This page uses too much memory, so Chrome paused it.</translation> +<translation id="3739899004075612870">Bookmarked in <ph name="PRODUCT_NAME" /></translation> +<translation id="3744111309925758534"><ph name="MEGABYTES" /> MB other apps</translation> +<translation id="3744111561329211289">Background sync</translation> +<translation id="3773755127849930740"><ph name="BEGIN_LINK" />Turn on Bluetooth<ph name="END_LINK" /> to allow pairing</translation> +<translation id="3778956594442850293">Added to Home screen</translation> +<translation id="3781011235031427080">More like this opened at half height</translation> +<translation id="3789841737615482174">Install</translation> +<translation id="3810838688059735925">Video</translation> +<translation id="3810973564298564668">Manage</translation> +<translation id="3819178904835489326"><ph name="NUMBER_OF_DOWNLOADS" /> downloads deleted</translation> +<translation id="3819562311292413223">Download articles for you</translation> +<translation id="3822502789641063741">Clear site storage?</translation> +<translation id="385051799172605136">Back</translation> +<translation id="3859306556332390985">Seek forward</translation> +<translation id="3868004864571585162">Cookies, media licences and site data</translation> +<translation id="3894427358181296146">Add folder</translation> +<translation id="3895926599014793903">Force enable zoom</translation> +<translation id="3927692899758076493">Sans Serif</translation> +<translation id="3928666092801078803">Combine my data</translation> +<translation id="393697183122708255">No enabled voice search available</translation> +<translation id="3950820424414687140">Sign in</translation> +<translation id="395206256282351086">Search and site suggestions disabled</translation> +<translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> +<translation id="3967822245660637423">Download complete</translation> +<translation id="397583555483684758">Sync has stopped working</translation> +<translation id="3976396876660209797">Remove and recreate this shortcut</translation> +<translation id="3985215325736559418">Do you want to download <ph name="FILE_NAME" /> again?</translation> +<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="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> +<translation id="3997476611815694295">Unimportant storage</translation> +<translation id="4002066346123236978">Title</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# hr}other{# hrs}}</translation> +<translation id="4042870126885713738">Show suggestions when a web address does not resolve or a connection cannot be made</translation> +<translation id="4046123991198612571">Next track</translation> +<translation id="4048707525896921369">Learn about topics on websites without leaving the page. Tap to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results and other details. + +To adjust your search term, long press to select. To refine your search, slide the panel all the way up and tap the search box.</translation> +<translation id="4056223980640387499">Sepia</translation> +<translation id="4060598801229743805">Options available near the top of the screen</translation> +<translation id="4062305924942672200">Legal information</translation> +<translation id="4084682180776658562">Bookmark</translation> +<translation id="4084712963632273211">From <ph name="PUBLISHER_ORIGIN" /> – <ph name="BEGIN_DEEMPHASIZED" />delivered by Google<ph name="END_DEEMPHASIZED" /></translation> +<translation id="4084836577264234537"><ph name="MEGABYTES" /> MB downloaded</translation> +<translation id="4089831646916293264">This feature may interfere with access to premium data services provided by your operator.</translation> +<translation id="4095146165863963773">Delete app data?</translation> +<translation id="4097739989936358050">This app is running in Chrome.</translation> +<translation id="4099578267706723511">Help make Chrome better by sending usage statistics and crash reports to Google.</translation> +<translation id="410351446219883937">Autoplay</translation> +<translation id="4113030288477039509">Managed by your administrator</translation> +<translation id="4116038641877404294">Download pages to use them offline</translation> +<translation id="4127069705158143605">{BOOKMARKS_COUNT,plural, =1{%1$d bookmark}other{%1$d bookmarks}}</translation> +<translation id="4149994727733219643">Simplified view for web pages</translation> +<translation id="4159800535322890630">Block sites from accessing your sensors</translation> +<translation id="4165986682804962316">Site settings</translation> +<translation id="4170011742729630528">The service is not available; try again later.</translation> +<translation id="4179980317383591987"><ph name="AMOUNT" /> used</translation> +<translation id="4181841719683918333">Languages</translation> +<translation id="4192273449750167573">Review your settings on the next screen</translation> +<translation id="4195643157523330669">Open in new tab</translation> +<translation id="4198423547019359126">No available download locations</translation> +<translation id="4209895695669353772">To get personalised content suggested by Google, turn on sync</translation> +<translation id="4226663524361240545">Notifications may vibrate the device</translation> +<translation id="4242533952199664413">Open settings</translation> +<translation id="4243710787042215766">Open in private tab</translation> +<translation id="424864128008805179">Sign out of Chrome?</translation> +<translation id="4256782883801055595">Open-source licences</translation> +<translation id="4259722352634471385">Navigation is blocked: <ph name="URL" /></translation> +<translation id="4262028915562328938">Sync error occurred, tap to get details.</translation> +<translation id="4269820728363426813">Copy link address</translation> +<translation id="4275663329226226506">Media</translation> +<translation id="4278390842282768270">Allowed</translation> +<translation id="4307992518367153382">Basics</translation> +<translation id="4351244548802238354">Close dialogue</translation> +<translation id="4378154925671717803">Phone</translation> +<translation id="4384468725000734951">Using Sogou for search</translation> +<translation id="4398088515904522762">To use this feature, turn on <ph name="BEGIN_LINK" />Activity and interactions<ph name="END_LINK" />.</translation> +<translation id="4404568932422911380">No bookmarks</translation> +<translation id="4409723563706114196">Use page predictions</translation> +<translation id="4412992751769744546">Allow third-party cookies</translation> +<translation id="4419556793104466535">Control sync, personalisation and more</translation> +<translation id="4432792777822557199">Pages in <ph name="SOURCE_LANGUAGE" /> will be translated to <ph name="TARGET_LANGUAGE" /> from now on</translation> +<translation id="4434045419905280838">Pop-ups and redirects</translation> +<translation id="4452411734226507615">Close <ph name="TAB_TITLE" /> tab</translation> +<translation id="4452548195519783679">Bookmarked to <ph name="FOLDER_NAME" /></translation> +<translation id="4453340223357552416"><ph name="FILE_NAME" /> downloaded in <ph name="PRODUCT_NAME" /></translation> +<translation id="4468959413250150279">Mute sound for a specific site.</translation> +<translation id="4472118726404937099">To sync and personalise across devices, sign in and turn on sync</translation> +<translation id="447252321002412580">Help improve Chrome's features and performance</translation> +<translation id="4479647676395637221">Ask first before allowing sites to use your camera (recommended)</translation> +<translation id="4487967297491345095">All Chrome’s app data will be deleted permanently. This includes all files, settings, accounts, databases, etc.</translation> +<translation id="4508440807153586353">Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting you'll need to reset sync. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation> +<translation id="4513387527876475750">{DAYS,plural, =1{# day ago}other{# days ago}}</translation> +<translation id="451872707440238414">Search your bookmarks</translation> +<translation id="4521489764227272523">The selected data has been removed from Chrome and your synced devices. + +Your Google Account may have other forms of browsing history such as searches and activity from other Google services at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="4532845899244822526">Choose folder</translation> +<translation id="4550003330909367850">To view or copy your password here, set screen lock on this device.</translation> +<translation id="4558311620361989323">Web page shortcuts</translation> +<translation id="4561979708150884304">No connection</translation> +<translation id="4565377596337484307">Hide password</translation> +<translation id="4570913071927164677">Details</translation> +<translation id="4572422548854449519">Sign in to managed account</translation> +<translation id="4581964774250883625">You’ve gone incognito.</translation> +<translation id="4583164079174244168">{MINUTES,plural, =1{# minute ago}other{# minutes ago}}</translation> +<translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">This offline page is from <ph name="CREATION_TIME" /> and may differ from the online version.</translation> +<translation id="4605958867780575332">Item removed: <ph name="ITEM_TITLE" /></translation> +<translation id="4616150815774728855">Open <ph name="WEBAPK_NAME" /></translation> +<translation id="4634124774493850572">Use password</translation> +<translation id="4645575059429386691">Managed by your parent</translation> +<translation id="4660011489602794167">Show keyboard</translation> +<translation id="4663756553811254707"><ph name="NUMBER_OF_BOOKMARKS" /> bookmarks deleted</translation> +<translation id="4665282149850138822"><ph name="NAME" /> was added to your Home screen</translation> +<translation id="4684427112815847243">Sync everything</translation> +<translation id="4695891336199304370">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}other{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}}</translation> +<translation id="4698034686595694889">View offline in <ph name="APP_NAME" /></translation> +<translation id="4698413471314543145">Critical functionality required to run Chrome is missing; either your Chrome installation is incomplete or not compatible with this version of Android.</translation> +<translation id="4699172675775169585">Cached images and files</translation> +<translation id="4714588616299687897">Save up to 60% of your data</translation> +<translation id="4719927025381752090">Offer to translate</translation> +<translation id="4720023427747327413">Open in <ph name="PRODUCT_NAME" /></translation> +<translation id="4720982865791209136">Help improve Chrome. <ph name="BEGIN_LINK" />Take survey<ph name="END_LINK" /></translation> +<translation id="4730876730346568982">You are switching sync accounts from <ph name="ACCOUNT_EMAIL_OLD" /> to <ph name="ACCOUNT_EMAIL_NEW" />. Your existing Chrome data is managed by <ph name="MANAGED_DOMAIN" />. This will delete your data from this device, but your data will remain in <ph name="ACCOUNT_EMAIL_OLD" />.</translation> +<translation id="473775607612524610">Update</translation> +<translation id="4738836084190194332">Last synced: <ph name="WHEN" /></translation> +<translation id="4749960740855309258">Open a new tab</translation> +<translation id="4751476147751820511">Motion or light sensors</translation> +<translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download complete.}other{# downloads complete.}}</translation> +<translation id="4766369052440583386">Data Saver is on</translation> +<translation id="4797039098279997504">Touch to return to <ph name="URL_OF_THE_CURRENT_TAB" /></translation> +<translation id="4807098396393229769">Name on card</translation> +<translation id="4807963036345170158">Data Saver is off</translation> +<translation id="4816465935029283692">Data types</translation> +<translation id="4837753911714442426">Open options to print page</translation> +<translation id="4842092870884894799">Showing password generation pop-up</translation> +<translation id="4850886885716139402">View</translation> +<translation id="4860895144060829044">Call</translation> +<translation id="4874967477260347223">Media Licenses</translation> +<translation id="4875775213178255010">Content Suggestions</translation> +<translation id="4878404682131129617">Establishing a tunnel via proxy server failed</translation> +<translation id="4881695831933465202">Open</translation> +<translation id="488187801263602086">Rename file</translation> +<translation id="4882831918239250449">Control how your browsing history is used to personalise Search, ads and more</translation> +<translation id="4883379392681899581">Leave private mode</translation> +<translation id="4885273946141277891">Unsupported number of Chrome instances.</translation> +<translation id="4910889077668685004">Payment apps</translation> +<translation id="4913161338056004800">Reset statistics</translation> +<translation id="4913169188695071480">Stop refreshing</translation> +<translation id="4915549754973153784"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /> while scanning for devices…</translation> +<translation id="4943872375798546930">No results</translation> +<translation id="4956460920135325549">Lite page delivered by Google.</translation> +<translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> is sharing your screen</translation> +<translation id="4961334780091921942">Your passwords, history & more on all devices</translation> +<translation id="4961700429721424617">You are signing out of an account managed by <ph name="MANAGED_DOMAIN" />. This will delete your Chrome data from this device, but your data will remain in your Google account.</translation> +<translation id="497421865427891073">go forward</translation> +<translation id="4988210275050210843">Downloading file (<ph name="MEGABYTES" />).</translation> +<translation id="4988526792673242964">Pages</translation> +<translation id="4996978546172906250">Share via</translation> +<translation id="5004339818306944878">Use up to 60% less data and speed up the web. Google servers will optimise the pages you visit.</translation> +<translation id="5004416275253351869">Google activity controls</translation> +<translation id="5005498671520578047">Copy password</translation> +<translation id="5011311129201317034"><ph name="SITE" /> wants to connect</translation> +<translation id="5013696553129441713">No new suggestions</translation> +<translation id="5016205925109358554">Serif</translation> +<translation id="5039804452771397117">Allow</translation> +<translation id="5040262127954254034">Privacy</translation> +<translation id="5063480226653192405">Usage</translation> +<translation id="5087580092889165836">Add card</translation> +<translation id="5100237604440890931">Collapsed – click to expand.</translation> +<translation id="510275257476243843">1 hour left</translation> +<translation id="5123685120097942451">Incognito tab</translation> +<translation id="5127805178023152808">Sync is off</translation> +<translation id="5129038482087801250">Install web app</translation> +<translation id="5139940364318403933">Learn how to use Google Drive</translation> +<translation id="515227803646670480">Clear stored data</translation> +<translation id="5152843274749979095">No supported apps installed</translation> +<translation id="5161254044473106830">Title required</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download failed.}other{# downloads failed.}}</translation> +<translation id="5168917394043976756">Open navigation drawer</translation> +<translation id="5171365962177408781">Tap to load the new tab page and view suggested articles</translation> +<translation id="5184329579814168207">Open in Chrome</translation> +<translation id="5199929503336119739">Work profile</translation> +<translation id="5210286577605176222">Jump to the previous tab</translation> +<translation id="5210365745912300556">Close tab</translation> +<translation id="5222676887888702881">Sign out</translation> +<translation id="5224771365102442243">With video</translation> +<translation id="5233638681132016545">New tab</translation> +<translation id="5240817131241497236">The settings that control sync, personalisation and other Google services in Chrome have changed. This may affect your current settings.</translation> +<translation id="5264003212305142034"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised at any time. Google may use content on sites that you visit, plus browser activity and interactions, to personalise Chrome and other Google services such as Translate, Search and ads.</translation> +<translation id="5271967389191913893">Device cannot open the content to be downloaded.</translation> +<translation id="528192093759286357">Drag from top and touch the back button to exit full screen.</translation> +<translation id="5284584623296338184">Changes to your bookmarks, history, passwords and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google account.</translation> +<translation id="5300589172476337783">Show</translation> +<translation id="5301954838959518834">OK, got it</translation> +<translation id="5304593522240415983">This field cannot be blank</translation> +<translation id="5308380583665731573">Connect</translation> +<translation id="5308603654685598744">When this feature is turned on, Chrome will offer to translate pages written in other languages using Google Translate.</translation> +<translation id="5313967007315987356">Add site</translation> +<translation id="5317780077021120954">Save</translation> +<translation id="5324858694974489420">Parental Settings</translation> +<translation id="5327248766486351172">Name</translation> +<translation id="5335288049665977812">Allow sites to run JavaScript (recommended)</translation> +<translation id="5345040418939504969">Deleted <ph name="BOOKMARK_TITLE" /></translation> +<translation id="5372829067651257087">URL copied.</translation> +<translation id="5391532827096253100">Your connection to this site is not secure. Site information</translation> +<translation id="5400569084694353794">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="5403644198645076998">Only allow certain sites</translation> +<translation id="5414836363063783498">Verifying…</translation> +<translation id="5423934151118863508">Your most visited pages will appear here</translation> +<translation id="5424588387303617268"><ph name="GIGABYTES" /> GB available</translation> +<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="5447765697759493033">This site will not be translated</translation> +<translation id="545042621069398927">Speeding up your download.</translation> +<translation id="5456381639095306749">Download page</translation> +<translation id="5466407412363861127">This feature uses <ph name="BEGIN_LINK" />sync<ph name="END_LINK" />.</translation> +<translation id="548278423535722844">Open in maps app</translation> +<translation id="5487521232677179737">Clear data</translation> +<translation id="5487729733663684359">Chrome updates are no longer supported for this version of Android.</translation> +<translation id="5494920125229734069">Select all</translation> +<translation id="550684401320795253">Updating Chrome...</translation> +<translation id="5512137114520586844">This account is managed by <ph name="PARENT_NAME" />.</translation> +<translation id="5514904542973294328">Disabled by the administrator of this device</translation> +<translation id="5515439363601853141">Unlock to view your password</translation> +<translation id="5515716148775388141">Your icons have moved to the bottom of the screen</translation> +<translation id="5517095782334947753">You have bookmarks, history, passwords and other settings from <ph name="FROM_ACCOUNT" />.</translation> +<translation id="5524843473235508879">Redirect blocked.</translation> +<translation id="5527082711130173040">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK1" />Update permissions<ph name="END_LINK1" />. Location access is also <ph name="BEGIN_LINK2" />turned off for this device<ph name="END_LINK2" />.</translation> +<translation id="5527111080432883924">Ask before allowing sites to read text and images from the clipboard (recommended)</translation> +<translation id="5530766185686772672">Close incognito tabs</translation> +<translation id="5534640966246046842">Site copied</translation> +<translation id="5537099431952529648">You and your parents can manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="5556459405103347317">Reload</translation> +<translation id="5561549206367097665">Waiting for network…</translation> +<translation id="557283862590186398">Chrome needs permission to access your microphone for this site.</translation> +<translation id="55737423895878184">Location and notifications are allowed</translation> +<translation id="5578795271662203820">Search <ph name="SEARCH_ENGINE" /> for this image</translation> +<translation id="5595485650161345191">Edit address</translation> +<translation id="5596627076506792578">More options</translation> +<translation id="5620299005957670886">Allow sites to access your sensors (recommended)</translation> +<translation id="5620928963363755975">Find your files and pages in Downloads from the More Options button</translation> +<translation id="5626134646977739690">Name:</translation> +<translation id="5639724618331995626">Allow all sites</translation> +<translation id="5648166631817621825">Last 7 days</translation> +<translation id="5655963694829536461">Search your downloads</translation> +<translation id="5659593005791499971">Email</translation> +<translation id="5665379678064389456">Create event in <ph name="APP_NAME" /></translation> +<translation id="5668404140385795438">Override a website’s request to prevent zooming in</translation> +<translation id="5676636989614905379">Cannot play video on <ph name="SCREEN_NAME" />.</translation> +<translation id="5677928146339483299">Blocked</translation> +<translation id="5684874026226664614">Oops. This page could not be translated.</translation> +<translation id="5686790454216892815">File name too long</translation> +<translation id="5689516760719285838">Location</translation> +<translation id="5719837394786370183">Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your incognito tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your Internet service provider or the websites you visit.</translation> +<translation id="572328651809341494">Recent tabs</translation> +<translation id="5726692708398506830">Make everything on the page bigger</translation> +<translation id="5738816946784116349">Chrome Downloads</translation> +<translation id="5748802427693696783">Switched to standard tabs</translation> +<translation id="5749068826913805084">Chrome needs storage access to download files.</translation> +<translation id="5763382633136178763">Incognito tabs</translation> +<translation id="5763514718066511291">Tap to copy the URL for this app</translation> +<translation id="5765780083710877561">Description:</translation> +<translation id="5777170031995031090">Control how Google uses your browsing history to personalise Search, ads and other Google services.</translation> +<translation id="5793665092639000975">Using <ph name="SPACE_USED" /> of <ph name="SPACE_AVAILABLE" /></translation> +<translation id="5804241973901381774">Permissions</translation> +<translation id="5809361687334836369">{HOURS,plural, =1{# hour ago}other{# hours ago}}</translation> +<translation id="5817918615728894473">Pair</translation> +<translation id="583281660410589416">Unknown</translation> +<translation id="5833397272224757657">Uses content on sites that you visit, plus browser activity and interactions, for personalisation</translation> +<translation id="5833984609253377421">Share link</translation> +<translation id="584427517463557805">Selected private tab</translation> +<translation id="5854790677617711513">Older than 30 days</translation> +<translation id="5858741533101922242">Chrome is unable to turn on Bluetooth adaptor</translation> +<translation id="5860033963881614850">Off</translation> +<translation id="5862731021271217234">To get your tabs from your other devices, turn on sync</translation> +<translation id="5864174910718532887">Details: Sorted by site name</translation> +<translation id="5864419784173784555">Waiting for another download…</translation> +<translation id="5865733239029070421">Automatically sends usage statistics and crash reports to Google</translation> +<translation id="5869522115854928033">Saved passwords</translation> +<translation id="5878455346526065919">Block ads from sites that tend to show intrusive ads</translation> +<translation id="5902828464777634901">All local data stored by this website, including cookies, will be deleted.</translation> +<translation id="5911030830365207728">Google Translate</translation> +<translation id="5916664084637901428">On</translation> +<translation id="5919204609460789179">Update <ph name="PRODUCT_NAME" /> to start sync</translation> +<translation id="5937580074298050696"><ph name="AMOUNT" /> saved</translation> +<translation id="5939518447894949180">Reset</translation> +<translation id="5942872142862698679">Using Google for search</translation> +<translation id="5952764234151283551">Sends the URL of a page that you're trying to reach to Google</translation> +<translation id="5956665950594638604">Open the Chrome Help Centre in a new tab</translation> +<translation id="5958275228015807058">Find your files and pages in Downloads</translation> +<translation id="5962718611393537961">Tap to collapse</translation> +<translation id="5990142338020175451">More personal Google services, such as better page suggestions</translation> +<translation id="6000066717592683814">Keep Google</translation> +<translation id="6005538289190791541">Suggested password</translation> +<translation id="6039379616847168523">Jump to the next tab</translation> +<translation id="6040143037577758943">Close</translation> +<translation id="6042308850641462728">More</translation> +<translation id="604996488070107836"><ph name="FILE_NAME" /> download failed due to an unknown error.</translation> +<translation id="605721222689873409">YY</translation> +<translation id="6075798973483050474">Edit home page</translation> +<translation id="60923314841986378"><ph name="HOURS" /> hours left</translation> +<translation id="60924377787140961">More articles will appear soon. Enjoy your afternoon!</translation> +<translation id="6099151465289169210">Switched to private tabs</translation> +<translation id="6108923351542677676">Setup in progress…</translation> +<translation id="6111020039983847643">data used</translation> +<translation id="6112702117600201073">Refreshing page</translation> +<translation id="6127379762771434464">Item removed</translation> +<translation id="6140912465461743537">Country/Region</translation> +<translation id="6154478581116148741">Turn on screen lock in Settings to export your passwords from this device</translation> +<translation id="6159335304067198720"><ph name="PERCENT" /> data savings</translation> +<translation id="6165508094623778733">Learn more</translation> +<translation id="6177111841848151710">Blocked for current search engine</translation> +<translation id="6177390657002841081">Turn on Data Saver</translation> +<translation id="6181444274883918285">Add site exception</translation> +<translation id="618993374665929060">More like this opened at full height</translation> +<translation id="6192333916571137726">Download File</translation> +<translation id="6192792657125177640">Exceptions</translation> +<translation id="6206551242102657620">Connection is secure. Site information</translation> +<translation id="6210748933810148297">Not <ph name="EMAIL" />?</translation> +<translation id="6216432067784365534"><ph name="NAME_OF_LIST_ITEM" /> Options</translation> +<translation id="6221633008163990886">Unlock to export your passwords</translation> +<translation id="6232535412751077445">Enabling “Do Not Track” means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request and how the request is interpreted. + +For example, some websites may respond to this request by showing you ads that aren’t based on other websites that you’ve visited. Many websites will still collect and use your browsing data – for example to improve security, to provide content, ads and recommendations and to generate reporting statistics.</translation> +<translation id="6255999984061454636">Content suggestions</translation> +<translation id="6277522088822131679">There was a problem printing the page. Please try again.</translation> +<translation id="6295158916970320988">All sites</translation> +<translation id="629730747756840877">Account</translation> +<translation id="6303969859164067831">Sign out and turn off sync</translation> +<translation id="6320088164292336938">Vibrate</translation> +<translation id="6324034347079777476">Android system sync disabled</translation> +<translation id="6333140779060797560">Share via <ph name="APPLICATION" /></translation> +<translation id="6336451774241870485">New private tab</translation> +<translation id="6337234675334993532">Encryption</translation> +<translation id="6341580099087024258">Ask where to save files</translation> +<translation id="6343192674172527289">No downloads found</translation> +<translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}}</translation> +<translation id="6364438453358674297">Remove suggestion from history?</translation> +<translation id="6378173571450987352">Details: Sorted by amount of data used</translation> +<translation id="6383961787135158834">Clear Site Storage…</translation> +<translation id="6388207532828177975">Clear & reset</translation> +<translation id="6393863479814692971">Chrome needs permission to access your camera and microphone for this site.</translation> +<translation id="6395288395575013217">LINK</translation> +<translation id="6404511346730675251">Edit bookmark</translation> +<translation id="6406506848690869874">Sync</translation> +<translation id="641643625718530986">Print…</translation> +<translation id="6416782512398055893">Downloaded <ph name="MBS" /> MB</translation> +<translation id="6433501201775827830">Choose your search engine</translation> +<translation id="6437478888915024427">Page info</translation> +<translation id="6447842834002726250">Cookies</translation> +<translation id="6448273550210938826">Search and URL suggestions</translation> +<translation id="6461962085415701688">Can’t open file</translation> +<translation id="6475951671322991020">Download video</translation> +<translation id="6482749332252372425"><ph name="FILE_NAME" /> download failed due to lack of storage space.</translation> +<translation id="6496823230996795692">To use <ph name="APP_NAME" /> for the first time, please connect to the Internet.</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6534565668554028783">Google took too long to respond</translation> +<translation id="6538442820324228105">Downloaded <ph name="GBS" /> GB</translation> +<translation id="654446541061731451">Select a tab to beam</translation> +<translation id="6545017243486555795">Clear All Data</translation> +<translation id="6556716549745717622">Block if site tends to show intrusive ads (recommended)</translation> +<translation id="6560414384669816528">Search with Sogou</translation> +<translation id="6566259936974865419">Chrome has saved you <ph name="GIGABYTES" /> GB</translation> +<translation id="6573096386450695060">Always allow</translation> +<translation id="6573431926118603307">Tabs that you've opened in Chrome on your other devices will appear here.</translation> +<translation id="6575643671698722332">Reset failed. Ensure that your device is online and try again.</translation> +<translation id="6583199322650523874">Bookmark the current page</translation> +<translation id="6584721918629302382">AR</translation> +<translation id="6593061639179217415">Desktop site</translation> +<translation id="6600954340915313787">Copied to Chrome</translation> +<translation id="6608650720463149374"><ph name="GIGABYTES" /> GB</translation> +<translation id="6610147964972079463">Close private tabs</translation> +<translation id="6612358246767739896">Protected content</translation> +<translation id="6627583120233659107">Edit folder</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6643649862576733715">Sort by amount of data saved</translation> +<translation id="6648977384226967773">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}other{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}}</translation> +<translation id="6656545060687952787">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK" />Update permissions<ph name="END_LINK" /></translation> +<translation id="6657585470893396449">Password</translation> +<translation id="6659594942844771486">Tab</translation> +<translation id="666268767214822976">Use a prediction service to show related queries and popular websites as you type in the address bar</translation> +<translation id="666731172850799929">Open in <ph name="APP_NAME" /></translation> +<translation id="666981079809192359">Chrome Privacy Notice</translation> +<translation id="6697492270171225480">Show suggestions for similar pages when a page can't be found</translation> +<translation id="6697947395630195233">Chrome needs access to your location to share your location with this site.</translation> +<translation id="6698801883190606802">Manage synced data</translation> +<translation id="6710213216561001401">Previous</translation> +<translation id="6712388303105732168">See more like this from Google using the More Like This button</translation> +<translation id="6738867403308150051">Downloading…</translation> +<translation id="6746124502594467657">Move down</translation> +<translation id="6762156594045689028">To change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="6766622839693428701">Swipe down to close.</translation> +<translation id="6770414673596662518">Chrome’s Safe Browsing system will also be used to detect malicious pages and protect you from phishing, malware and harmful downloads.</translation> +<translation id="6776813977906306442">Download videos to watch later using the Download button</translation> +<translation id="6790428901817661496">Play</translation> +<translation id="679325081238418596">Get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="6820607729870073286">You have no saved website settings.</translation> +<translation id="6820686453637990663">CVC</translation> +<translation id="6831043979455480757">Translate</translation> +<translation id="6846298663435243399">Loading…</translation> +<translation id="685040365210406336">Make no changes</translation> +<translation id="6850409657436465440">Your download is still in progress</translation> +<translation id="6850830437481525139"><ph name="TAB_COUNT" /> tabs closed</translation> +<translation id="6864459304226931083">Download image</translation> +<translation id="6865313869410766144">Autofill form data</translation> +<translation id="6868088497967843822">Sign in to get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="688738109438487280">Add existing data to <ph name="TO_ACCOUNT" />.</translation> +<translation id="6891726759199484455">Unlock to copy your password</translation> +<translation id="6891858906296486776">{OPEN_TABS,plural, =1{%1$d open tab}other{%1$d open tabs}}</translation> +<translation id="6896758677409633944">Copy</translation> +<translation id="6910211073230771657">Deleted</translation> +<translation id="6912998170423641340">Block sites from reading text and images from the clipboard</translation> +<translation id="6914783257214138813">Your passwords will be visible to anyone who can see the exported file.</translation> +<translation id="6942665639005891494">Change the default download location at any time using the Settings menu option</translation> +<translation id="6945221475159498467">Select</translation> +<translation id="6963642900430330478">This page is dangerous. Site information</translation> +<translation id="6963766334940102469">Delete bookmarks</translation> +<translation id="6965382102122355670">OK</translation> +<translation id="6978479750597523876">Reset translate settings</translation> +<translation id="6979737339423435258">All time</translation> +<translation id="6981982820502123353">Accessibility</translation> +<translation id="6985347914332179298">No downloads here</translation> +<translation id="6990079615885386641">Get the app from the Google Play Store: <ph name="APP_ACTION" /></translation> +<translation id="699220179437400583">Automatically report details of possible security incidents to Google</translation> +<translation id="6992289844737586249">Ask first before allowing sites to use your microphone (recommended)</translation> +<translation id="7016516562562142042">Allowed for current search engine</translation> +<translation id="7021515813996758557"><ph name="FILE_NAME" /> downloaded</translation> +<translation id="7022756207310403729">Open in browser</translation> +<translation id="702463548815491781">Recommended when TalkBack or Switch Access are on</translation> +<translation id="7029809446516969842">Passwords</translation> +<translation id="7031882061095297553">Sync to</translation> +<translation id="7032663816368481562">When you tap More like this <ph name="ICON" /> in the address bar, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="7034608350006174882">Cards and addresses using Google Pay</translation> +<translation id="7053983685419859001">Block</translation> +<translation id="7055152154916055070">Redirect blocked:</translation> +<translation id="7062545763355031412">Accept and switch accounts</translation> +<translation id="7063006564040364415">Could not connect to the sync server.</translation> +<translation id="7066151586745993502">{NUM_SELECTED,plural, =1{1 selected}other{# selected}}</translation> +<translation id="7077143737582773186">SD Card</translation> +<translation id="7087918508125750058"><ph name="ITEM_COUNT" /> selected. Options available near top of the screen</translation> +<translation id="7108338896283013870">Hide</translation> +<translation id="7121362699166175603">Clears history and autocompletions in the address bar. 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="7128222689758636196">Allow for current search engine</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7139148793369023665">More like this closed</translation> +<translation id="7141896414559753902">Block sites from showing pop-ups and redirects (recommended)</translation> +<translation id="7149158118503947153"><ph name="BEGIN_LINK" />Load original page<ph name="END_LINK" /> from <ph name="DOMAIN_NAME" /></translation> +<translation id="7149893636342594995">Last 24 Hours</translation> +<translation id="7176368934862295254"><ph name="KILOBYTES" /> KB</translation> +<translation id="7177466738963138057">You can change this later in Settings</translation> +<translation id="7180611975245234373">Refresh</translation> +<translation id="7189372733857464326">Waiting for Google Play Services to finish updating</translation> +<translation id="7189598951263744875">Share...</translation> +<translation id="7191430249889272776">Tab opened in background.</translation> +<translation id="723171743924126238">Select images</translation> +<translation id="7243308994586599757">Options available near bottom of the screen</translation> +<translation id="7250468141469952378"><ph name="ITEM_COUNT" /> selected</translation> +<translation id="7251326866581677552">Blocked from some sites</translation> +<translation id="7253272406652746122">Add a Google account from the Accounts page in your device’s Settings app.</translation> +<translation id="7274013316676448362">Blocked site</translation> +<translation id="729975465115245577">Your device doesn’t have an app to store the passwords file.</translation> +<translation id="7302081693174882195">Details: Sorted by amount of data saved</translation> +<translation id="7333031090786104871">Still adding previous site</translation> +<translation id="7352939065658542140">VIDEO</translation> +<translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Share 1 selected item}other{Share # selected items}}</translation> +<translation id="7359002509206457351">Access payment methods</translation> +<translation id="7366340029385295517">Casting to <ph name="SCREEN_NAME" /></translation> +<translation id="7375125077091615385">Type:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> +<translation id="7400418766976504921">URL</translation> +<translation id="7403691278183511381">Chrome First Run Experience</translation> +<translation id="741204030948306876">Yes, I'm in</translation> +<translation id="7413229368719586778">Start date <ph name="DATE" /></translation> +<translation id="7423098979219808738">Ask first</translation> +<translation id="7423538860840206698">Blocked from reading clipboard</translation> +<translation id="7431991332293347422">Control how your browsing history is used to personalise Search and more</translation> +<translation id="7437998757836447326">Sign out of Chrome</translation> +<translation id="7444811645081526538">More categories</translation> +<translation id="7445411102860286510">Allow sites to automatically play muted videos (recommended)</translation> +<translation id="7454641608352164238">Not enough space</translation> +<translation id="7455923816558154057">Tap to view</translation> +<translation id="7465104139234185284">Close all private tabs</translation> +<translation id="7473891865547856676">No Thanks</translation> +<translation id="7475192538862203634">If you’re seeing this frequently, try these <ph name="BEGIN_LINK" />suggestions<ph name="END_LINK" />.</translation> +<translation id="7475688122056506577">SD card not found. Some of your files may be missing.</translation> +<translation id="748127970106343339">Confirm device credential deletion</translation> +<translation id="7481312909269577407">Forward</translation> +<translation id="7493994139787901920"><ph name="VERSION" /> (Updated <ph name="TIME_SINCE_UPDATE" />)</translation> +<translation id="7494879913343971937">Show passwords</translation> +<translation id="7494974237137038751">data saved</translation> +<translation id="7498271377022651285">Please wait…</translation> +<translation id="7514365320538308">Download</translation> +<translation id="751961395872307827">Can't connect to the site</translation> +<translation id="7521387064766892559">JavaScript</translation> +<translation id="7542481630195938534">Can’t get suggestions</translation> +<translation id="7562080006725997899">Clear browsing data</translation> +<translation id="756809126120519699">Cleared Chrome data</translation> +<translation id="757524316907819857">Block sites from playing protected content</translation> +<translation id="7589445247086920869">Block for current search engine</translation> +<translation id="7593557518625677601">Open Android settings and re-enable Android system sync to start Chrome sync</translation> +<translation id="7596558890252710462">Operating system</translation> +<translation id="7605594153474022051">Sync isn't working</translation> +<translation id="7612619742409846846">Signed in to Google as</translation> +<translation id="7619072057915878432"><ph name="FILE_NAME" /> download failed due to network failures.</translation> +<translation id="7624880197989616768"><ph name="BEGIN_LINK1" />Get help<ph name="END_LINK1" /> or <ph name="BEGIN_LINK2" />re-scan<ph name="END_LINK2" /></translation> +<translation id="7626032353295482388">Welcome to Chrome</translation> +<translation id="7638584964844754484">Incorrect passphrase</translation> +<translation id="7641339528570811325">Clear browsing data…</translation> +<translation id="7648422057306047504">Encrypt passwords with Google credentials</translation> +<translation id="7649070708921625228">Help</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7665369617277396874">Add account</translation> +<translation id="7682724950699840886">Try the following tips: make sure that there is enough space on your device; try to export again.</translation> +<translation id="7698359219371678927">Create email in <ph name="APP_NAME" /></translation> +<translation id="7704317875155739195">Auto-complete searches and URLs</translation> +<translation id="773466115871691567">Always translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> +<translation id="773905249182896430">Protects you and your device from dangerous sites</translation> +<translation id="7762668264895820836">SD Card <ph name="SD_CARD_NUMBER" /></translation> +<translation id="7764225426217299476">Add address</translation> +<translation id="7765158879357617694">Move</translation> +<translation id="7769602470925380267">Accept and sign out</translation> +<translation id="7772032839648071052">Confirm passphrase</translation> +<translation id="7774809984919390718">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}other{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}}</translation> +<translation id="7781829728241885113">Yesterday</translation> +<translation id="7791543448312431591">Add</translation> +<translation id="780301667611848630">No, thank you</translation> +<translation id="7810647596859435254">Open with…</translation> +<translation id="7821588508402923572">Your data savings will appear here</translation> +<translation id="7832327313660264358">The data that you sync to Google and the features that you use will not change</translation> +<translation id="7837721118676387834">Allow auto-play of muted videos for a specific site.</translation> +<translation id="7846076177841592234">Cancel selection</translation> +<translation id="784934925303690534">Time range</translation> +<translation id="7851858861565204677">Other Devices</translation> +<translation id="7854964836418414587">Close more like this</translation> +<translation id="7875915731392087153">Create email</translation> +<translation id="7876243839304621966">Remove all</translation> +<translation id="7882131421121961860">No history found</translation> +<translation id="7882806643839505685">Allow sound for a specific site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Downloading file.}other{Downloading # files.}}</translation> +<translation id="7929962904089429003">Opening the menu</translation> +<translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> is out of date.</translation> +<translation id="7947953824732555851">Accept and sign in</translation> +<translation id="7963646190083259054">Vendor:</translation> +<translation id="7981313251711023384">Preload pages for faster browsing and searching</translation> +<translation id="79859296434321399">To view augmented reality content, install ARCore</translation> +<translation id="7986741934819883144">Select a contact</translation> +<translation id="7987073022710626672">Chrome Terms of Service</translation> +<translation id="7987764905897278458">Get more Google smarts</translation> +<translation id="7998918019931843664">Re-open closed tab</translation> +<translation id="7999064672810608036">Are you sure that you want to clear all local data, including cookies, and reset all permissions for this website?</translation> +<translation id="8004582292198964060">Browser</translation> +<translation id="8007176423574883786">Turned off for this device</translation> +<translation id="8015452622527143194">Return everything on the page to default size</translation> +<translation id="802154636333426148">Download failed</translation> +<translation id="8026334261755873520">Clear browsing data</translation> +<translation id="8035133914807600019">New folder…</translation> +<translation id="8037411810184515274">VR</translation> +<translation id="8037686209485537503">More like this</translation> +<translation id="8037750541064988519"><ph name="DAYS" /> days left</translation> +<translation id="804335162455518893">SD card not found</translation> +<translation id="805047784848435650">Based on your browsing history</translation> +<translation id="8051695050440594747"><ph name="MEGABYTES" /> MB available</translation> +<translation id="8058746566562539958">Open in new Chrome tab</translation> +<translation id="8063895661287329888">Failed to add bookmark.</translation> +<translation id="806745655614357130">Keep my data separate</translation> +<translation id="8068648041423924542">Unable to select certificate.</translation> +<translation id="8073388330009372546">Open image in new tab</translation> +<translation id="8084114998886531721">Saved password</translation> +<translation id="8087000398470557479">This content is from <ph name="DOMAIN_NAME" />, delivered by Google.</translation> +<translation id="8103578431304235997">Incognito Tab</translation> +<translation id="8105951947646329362">Suggest related pages</translation> +<translation id="8109613176066109935">To get your bookmarks on all your devices, turn on sync</translation> +<translation id="8116925261070264013">Muted</translation> +<translation id="813082847718468539">View site information</translation> +<translation id="8156139159503939589">What languages do you read?</translation> +<translation id="8168435359814927499">Content</translation> +<translation id="8186512483418048923"><ph name="FILES" /> files left</translation> +<translation id="8190358571722158785">1 day left</translation> +<translation id="8200772114523450471">Resume</translation> +<translation id="8209050860603202033">Open image</translation> +<translation id="8220488350232498290"><ph name="GIGABYTES" /> GB downloaded</translation> +<translation id="8249310407154411074">Move to top</translation> +<translation id="8250920743982581267">Documents</translation> +<translation id="825412236959742607">This page uses too much memory, so Chrome removed some content.</translation> +<translation id="8260126382462817229">Try signing in again</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8266862848225348053">Download location</translation> +<translation id="8274165955039650276">See downloads</translation> +<translation id="8283853025636624853">Syncing to <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8310344678080805313">Standard tabs</translation> +<translation id="8313455859591948645">Edit startup page</translation> +<translation id="8316092324682955408"><ph name="DOMAIN_NAME" /> and more sites</translation> +<translation id="8339163506404995330">Pages in <ph name="LANGUAGE" /> will not be translated</translation> +<translation id="8349013245300336738">Sort by amount of data used</translation> +<translation id="8372893542064058268">Allow Background Sync for a specific site.</translation> +<translation id="8374821112118309944">You need to update TalkBack to a newer version.</translation> +<translation id="8393700583063109961">Send message</translation> +<translation id="8413126021676339697">Show full history</translation> +<translation id="8428213095426709021">Settings</translation> +<translation id="8438566539970814960">Make searches and browsing better</translation> +<translation id="8441146129660941386">Seek backward</translation> +<translation id="8445448999790540984">Can’t export passwords</translation> +<translation id="8447861592752582886">Revoke device permission</translation> +<translation id="8477071352266846533">Sync off for <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8487700953926739672">Available offline</translation> +<translation id="8489271220582375723">Open the history page</translation> +<translation id="8493948351860045254">Free up space</translation> +<translation id="8497726226069778601">Nothing to see here… yet</translation> +<translation id="8503559462189395349">Chrome Passwords</translation> +<translation id="8503813439785031346">Username</translation> +<translation id="8504988642345501642">When you scroll up, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="8507520749471379845">Passwords available</translation> +<translation id="8514477925623180633">Export passwords stored with Chrome</translation> +<translation id="8514577642972634246">Enter incognito mode</translation> +<translation id="851751545965956758">Block sites from connecting to devices</translation> +<translation id="8523928698583292556">Delete stored password</translation> +<translation id="854522910157234410">Open this page:</translation> +<translation id="8558485628462305855">To view augmented reality content, update ARCore</translation> +<translation id="8559990750235505898">Offer to translate pages in other languages</translation> +<translation id="8562452229998620586">Your saved passwords will appear here.</translation> +<translation id="8569404424186215731">since <ph name="DATE" /></translation> +<translation id="8571213806525832805">Last 4 weeks</translation> +<translation id="857509777403223202">More articles will appear soon. Enjoy your evening!</translation> +<translation id="857943718398505171">Allowed (recommended)</translation> +<translation id="8583805026567836021">Clearing account data</translation> +<translation id="8609465669617005112">Move up</translation> +<translation id="8616006591992756292">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="8617240290563765734">Open the suggested URL specified in the downloaded content?</translation> +<translation id="862875433388403934">Content (films, music, etc.) downloaded in other applications may no longer be playable until those applications re-acquire licences based on a new device credential. To obtain new licences, connect to the Internet and play your downloaded content.</translation> +<translation id="8636825310635137004">To get your tabs from your other devices, turn on sync.</translation> +<translation id="8641930654639604085">Try to block mature sites</translation> +<translation id="8662811608048051533">Signs you out of most sites.</translation> +<translation id="8664979001105139458">File name already exists</translation> +<translation id="8676374126336081632">Clear input</translation> +<translation id="8687353297350450808">{N_BARS,plural, =1{Signal Strength Level: # bar}other{Signal Strength Level: # bars}}</translation> +<translation id="868929229000858085">Search your contacts</translation> +<translation id="869891660844655955">Expiry date</translation> +<translation id="8719023831149562936">Can’t beam current tab</translation> +<translation id="8725066075913043281">Try again</translation> +<translation id="8728487861892616501">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8730621377337864115">Done</translation> +<translation id="8748850008226585750">Contents hidden</translation> +<translation id="8751914237388039244">Select an image</translation> +<translation id="8788968922598763114">Reopen the last closed tab</translation> +<translation id="8812260976093120287">On some websites, you can pay with above supported payment apps on your device.</translation> +<translation id="8816439037877937734"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome's <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8820817407110198400">Bookmarks</translation> +<translation id="8823704566850948458">Suggest password...</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> +<translation id="883806473910249246">An error occurred while downloading the content.</translation> +<translation id="8840953339110955557">This page may differ from the online version.</translation> +<translation id="8847988622838149491">USB</translation> +<translation id="8853345339104747198"><ph name="TAB_TITLE" />, tab</translation> +<translation id="885701979325669005">Storage</translation> +<translation id="8901170036886848654">No bookmarks found</translation> +<translation id="8909135823018751308">Share…</translation> +<translation id="8912362522468806198">Google Account</translation> +<translation id="8920114477895755567">Waiting for details of parents.</translation> +<translation id="8922289737868596582">Download pages from the More Options button to use them offline</translation> +<translation id="8941729603749328384">www.example.com</translation> +<translation id="8942627711005830162">Open in other window</translation> +<translation id="8951232171465285730">Chrome has saved you <ph name="MEGABYTES" /> MB</translation> +<translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> +<translation id="8972098258593396643">Download to default folder?</translation> +<translation id="8979405271719829084">Download videos to watch later</translation> +<translation id="8981454092730389528">Google Activity Controls</translation> +<translation id="8983677657449185470">Help improve Safe Browsing</translation> +<translation id="8986494364107987395">Automatically send usage statistics and crash reports to Google</translation> +<translation id="8993760627012879038">Open a new tab in Incognito mode</translation> +<translation id="8998729206196772491">You are signing in with an account managed by <ph name="MANAGED_DOMAIN" /> and giving its administrator control over your Chrome data. Your data will become permanently tied to this account. Signing out of Chrome will delete your data from this device, but it will remain stored in your Google account.</translation> +<translation id="9019902583201351841">Managed by your parents</translation> +<translation id="9040142327097499898">Notifications are allowed. Location is off for this device.</translation> +<translation id="9050666287014529139">Passphrase</translation> +<translation id="9060538597317784206">View app <ph name="APP_NAME" /> on the Play Store. Rating: <ph name="APP_RATING" />.</translation> +<translation id="9063523880881406963">Turn off Request desktop site</translation> +<translation id="9065203028668620118">Edit</translation> +<translation id="9070377983101773829">Start voice search</translation> +<translation id="9071742570345586758">To view virtual reality content, install Google VR Services</translation> +<translation id="9074336505530349563">To get personalised content suggested by Google, sign in and turn on sync</translation> +<translation id="9080642952018487277">Enter private mode</translation> +<translation id="9086455579313502267">Unable to access the network</translation> +<translation id="9099018167121903954"><ph name="KILOBYTES" /> KB downloaded</translation> +<translation id="9100505651305367705">Offer to show articles in simplified view, when supported</translation> +<translation id="9100610230175265781">Passphrase required</translation> +<translation id="9100939710791843300">Tap the home button to load the new tab page and view suggested articles</translation> +<translation id="9133515669113036225">Reset device credentials</translation> +<translation id="9133703968756164531"><ph name="ITEM_NAME" /> (<ph name="ITEM_ID" />)</translation> +<translation id="9137013805542155359">Show original</translation> +<translation id="9139068048179869749">Ask before allowing sites to send notifications (recommended)</translation> +<translation id="9155898266292537608">You can also search with a quick tap on a word</translation> +<translation id="9188680907066685419">Sign out of managed account</translation> +<translation id="9204836675896933765">1 file left</translation> +<translation id="9206873250291191720">A</translation> +<translation id="9218033835049520260">Suggest strong password...</translation> +<translation id="9219103736887031265">Images</translation> +<translation id="932327136139879170">Home</translation> +<translation id="932599481871055447">Save data and browse faster</translation> +<translation id="938850635132480979">Error: <ph name="ERROR_CODE" /></translation> +<translation id="945522503751344254">Send feedback</translation> +<translation id="945632385593298557">Access your microphone</translation> +<translation id="951339005376969845">Delete existing data. You can retrieve it by switching back to <ph name="FROM_ACCOUNT" />.</translation> +<translation id="95817756606698420">Chrome can use <ph name="BEGIN_BOLD" />Sogou<ph name="END_BOLD" /> for search in China. You can change this in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="970715775301869095"><ph name="MINUTES" /> mins left</translation> +<translation id="974555521953189084">Enter your passphrase to start sync</translation> +<translation id="981121421437150478">Offline</translation> +<translation id="982182592107339124">This will clear data for all sites, including:</translation> +<translation id="983192555821071799">Close all tabs</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ms.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ms.xtb new file mode 100644 index 0000000..e5eadf2 --- /dev/null +++ b/chrome/android/java/strings/translations/android_chrome_strings_ms.xtb
@@ -0,0 +1,1056 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ms"> +<translation id="1006017844123154345">Open Online</translation> +<translation id="1036727731225946849">Adding <ph name="WEBAPK_NAME" />...</translation> +<translation id="1041308826830691739">From websites</translation> +<translation id="1049743911850919806">Incognito</translation> +<translation id="1054301162707478098">You’ve gone private.</translation> +<translation id="10614374240317010">Never saved</translation> +<translation id="1067922213147265141">Other Google services</translation> +<translation id="1068672505746868501">Never translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="10713315585330490"><ph name="FILE_SIZE" /> – <ph name="DESCRIPTION" /></translation> +<translation id="1080790410959514870">You are signing out of an account managed by <ph name="DOMAIN_NAME" />. This will delete the Chrome data stored on this device, but the data will remain in your Google Account.</translation> +<translation id="1105960400813249514">Screen Capture</translation> +<translation id="1111673857033749125">Bookmarks saved on your other devices will appear here.</translation> +<translation id="1113597929977215864">Show simplified view</translation> +<translation id="1121094540300013208">Usage and crash reports</translation> +<translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download pending.}other{# downloads pending.}}</translation> +<translation id="1145536944570833626">Delete existing data.</translation> +<translation id="1146678959555564648">Enter VR</translation> +<translation id="114721135501989771">Get Google smarts in Chrome</translation> +<translation id="1157102636231978136">Your browsing data and activity, synced to your Google account</translation> +<translation id="116280672541001035">Used</translation> +<translation id="1172593791219290334">Startup Page</translation> +<translation id="1175310183703641346">Your bookmarks, history, passwords and more will no longer be synced to your Google account</translation> +<translation id="1178581264944972037">Pause</translation> +<translation id="1181037720776840403">Remove</translation> +<translation id="1197267115302279827">Move bookmarks</translation> +<translation id="119944043368869598">Clear all</translation> +<translation id="1201402288615127009">Next</translation> +<translation id="1204037785786432551">Download link</translation> +<translation id="1206892813135768548">Copy link text</translation> +<translation id="1208340532756947324">To sync and personalise across devices, turn on sync</translation> +<translation id="1209206284964581585">Hide for now</translation> +<translation id="123724288017357924">Reload the current page, ignoring cached content</translation> +<translation id="124116460088058876">More languages</translation> +<translation id="124678866338384709">Close current tab</translation> +<translation id="1258753120186372309">Google doodle: <ph name="DOODLE_DESCRIPTION" /></translation> +<translation id="1259100630977430756">Pages that you view in private tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your private tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going private doesn’t hide your browsing from your employer, your Internet service provider or the websites that you visit.</translation> +<translation id="127138278192656016">Use sync and all services</translation> +<translation id="1272079795634619415">Stop</translation> +<translation id="1283039547216852943">Tap to expand</translation> +<translation id="1285320974508926690">Never translate this site</translation> +<translation id="1291207594882862231">Clear history, cookies, site data, cache…</translation> +<translation id="129553762522093515">Recently closed</translation> +<translation id="1326317727527857210">To get your tabs from your other devices, sign in to Chrome.</translation> +<translation id="1332501820983677155">Google Chrome feature shortcuts</translation> +<translation id="1360432990279830238">Sign out and turn off sync?</translation> +<translation id="136248372334525878">Preload pages for faster loading and offline reading</translation> +<translation id="1369915414381695676">Site <ph name="SITE_NAME" /> added</translation> +<translation id="1373696734384179344">Insufficient memory to download the selected content.</translation> +<translation id="1376578503827013741">Computing…</translation> +<translation id="138361230106469022">Hi, <ph name="FULL_NAME" /></translation> +<translation id="1383876407941801731">Search</translation> +<translation id="1384959399684842514">Download paused</translation> +<translation id="1389974829397082527">No bookmarks here</translation> +<translation id="1397811292916898096">Search with <ph name="PRODUCT_NAME" /></translation> +<translation id="1397854323885047133">Sync and personalisation</translation> +<translation id="1404122904123200417">Embedded in <ph name="WEBSITE_URL" /></translation> +<translation id="1406000523432664303">“Do Not Track”</translation> +<translation id="1407135791313364759">Open all</translation> +<translation id="1409426117486808224">Simplified view for open tabs</translation> +<translation id="1409879593029778104"><ph name="FILE_NAME" /> download prevented because file already exists.</translation> +<translation id="1414981605391750300">Contacting Google. This may take a minute…</translation> +<translation id="1416550906796893042">Application version</translation> +<translation id="1430915738399379752">Print</translation> +<translation id="1445680696957526815">Chrome’s components are incompatible with one another. Chrome may be upgrading, please try again in a few minutes. If the problem continues, try uninstalling and re-installing Chrome.</translation> +<translation id="1446450296470737166">Allow full control of MIDI devices</translation> +<translation id="145097072038377568">Turned off in Android Settings</translation> +<translation id="1477626028522505441"><ph name="FILE_NAME" /> download failed due to server issues.</translation> +<translation id="1506061864768559482">Search engine</translation> +<translation id="1513352483775369820">Bookmarks and web history</translation> +<translation id="1513858653616922153">Delete password</translation> +<translation id="1516229014686355813">Tap to Search sends the selected word and the current page as context to Google Search. You can turn it off in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="1539064842193522527">Link opened in Chrome</translation> +<translation id="1549000191223877751">Move to other window</translation> +<translation id="1553358976309200471">Update Chrome</translation> +<translation id="1566400915470565838">To use <ph name="APP_NAME" />, please connect to the Internet.</translation> +<translation id="1569387923882100876">Connected device</translation> +<translation id="1571304935088121812">Copy username</translation> +<translation id="1576370611341449972">Download occurs only on Wi-Fi</translation> +<translation id="1612196535745283361">Chrome needs location access to scan for devices. Location access is <ph name="BEGIN_LINK" />turned off for this device<ph name="END_LINK" />.</translation> +<translation id="162035744160882748">Turn on sync, personalisation and other Google services</translation> +<translation id="1620510694547887537">Camera</translation> +<translation id="1623104350909869708">Prevent this page from creating additional dialogues</translation> +<translation id="1628019612362412531">{NUM_SELECTED,plural, =1{Remove 1 selected item}other{Remove # selected items}}</translation> +<translation id="1641113438599504367">Safe Browsing</translation> +<translation id="164269334534774161">You are viewing an offline copy of this page from <ph name="CREATION_TIME" /></translation> +<translation id="1644574205037202324">History</translation> +<translation id="1647391597548383849">Access your camera</translation> +<translation id="1660204651932907780">Allow sites to play sound (recommended)</translation> +<translation id="1670399744444387456">Basic</translation> +<translation id="1671236975893690980">Download pending...</translation> +<translation id="1672586136351118594">Don‘t show again</translation> +<translation id="1709438864123551175">Data Saver</translation> +<translation id="1718835860248848330">Last hour</translation> +<translation id="1729516292547892356">To view virtual reality content, update Google VR Services</translation> +<translation id="1733116627827457509"><ph name="FILE_SIZE" /> – Updated <ph name="TIME_SINCE_UPDATE" /></translation> +<translation id="1736419249208073774">Explore</translation> +<translation id="1743802530341753419">Ask before allowing sites to connect to a device (recommended)</translation> +<translation id="1749561566933687563">Sync your bookmarks</translation> +<translation id="17513872634828108">Open tabs</translation> +<translation id="1756600373018374892">Tap this button for quick access to your tabs.</translation> +<translation id="1779089405699405702">Image decoder</translation> +<translation id="1782483593938241562">End date <ph name="DATE" /></translation> +<translation id="1792959175193046959">Change the default download location at any time</translation> +<translation id="1807246157184219062">Light</translation> +<translation id="1821253160463689938">Uses cookies to remember your preferences, even if you don't visit those pages</translation> +<translation id="1829244130665387512">Find in page</translation> +<translation id="1832521218263067499">Security incidents</translation> +<translation id="1853692000353488670">New incognito tab</translation> +<translation id="1868024384445905608">Chrome now downloads files faster</translation> +<translation id="1878302395768190018">You can customise this at any time in Chrome Settings</translation> +<translation id="1880072593381090678">Popular pages from Chrome</translation> +<translation id="1883903952484604915">My files</translation> +<translation id="1887786770086287077">Location access is off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1891331835972267886"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="189172778771606813">Close navigation drawer</translation> +<translation id="1919345977826869612">Ads</translation> +<translation id="1919950603503897840">Select contacts</translation> +<translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/<ph name="FILE_SIZE_WITH_UNITS" /></translation> +<translation id="1933845786846280168">Selected Tab</translation> +<translation id="1938981467853765413">Provide feedback</translation> +<translation id="194341124344773587">Turn on permission for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1943432128510653496">Save passwords</translation> +<translation id="1944384637046898011">Encrypt all with Google password as of <ph name="TIME" /></translation> +<translation id="1946005195648379376">Control how Google uses your browsing history to personalise Search and other Google services.</translation> +<translation id="1952172573699511566">Websites will show text in your preferred language, when possible.</translation> +<translation id="195283394249132567">Personalised Google services</translation> +<translation id="1966710179511230534">Please update your sign-in details.</translation> +<translation id="1974060860693918893">Advanced</translation> +<translation id="1984937141057606926">Allowed, except third-party</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> button</translation> +<translation id="1989112275319619282">Browse</translation> +<translation id="1993768208584545658"><ph name="SITE" /> wants to pair</translation> +<translation id="1994173015038366702">Site URL</translation> +<translation id="2000419248597011803">Sends some cookies and searches from the address bar and search box to your default search engine</translation> +<translation id="2002537628803770967">Credit cards and addresses using Google Pay</translation> +<translation id="200815880754187296"><ph name="KILOBYTES" /> KB other apps</translation> +<translation id="2017836877785168846">Clears history and autocompletions in the address bar.</translation> +<translation id="2021896219286479412">Full screen site controls</translation> +<translation id="2038563949887743358">Turn on Request desktop site</translation> +<translation id="2045104531052923016"><ph name="GIGABYTES" /> GB other apps</translation> +<translation id="2063713494490388661">Tap to Search</translation> +<translation id="2079545284768500474">Undo</translation> +<translation id="2082238445998314030">Result <ph name="RESULT_NUMBER" /> of <ph name="TOTAL_RESULTS" /></translation> +<translation id="2086652334978798447">To get personalised content suggested by Google, sign in to Chrome.</translation> +<translation id="2091887806945687916">Sound</translation> +<translation id="2095887075102408547">When this feature is turned on, Chrome will use Google servers to compress pages that you visit before downloading them. Pages accessed using private connections (HTTPS) or in Incognito tabs will not be optimised or seen by Google.</translation> +<translation id="2096012225669085171">Sync and personalise across devices</translation> +<translation id="2100273922101894616">Auto Sign-in</translation> +<translation id="2111511281910874386">Go to page</translation> +<translation id="2120297377148151361">Activity and interactions</translation> +<translation id="2122601567107267586">Could not open app</translation> +<translation id="2126426811489709554">Powered by Chrome</translation> +<translation id="2131665479022868825"><ph name="DATA" /> saved</translation> +<translation id="213279576345780926">Closed <ph name="TAB_TITLE" /></translation> +<translation id="2139186145475833000">Add to Home screen</translation> +<translation id="2142289305367051020">Your favourite pages are here</translation> +<translation id="2146738493024040262">Open Instant App</translation> +<translation id="2148716181193084225">Today</translation> +<translation id="2154484045852737596">Edit card</translation> +<translation id="2154710561487035718">Copy URL</translation> +<translation id="2156074688469523661">Remaining sites (<ph name="NUMBER_OF_SITES" />)</translation> +<translation id="2206488550163399966"><ph name="APP_NAME" />, web app. <ph name="APP_URL" /></translation> +<translation id="2227444325776770048">Continue as <ph name="USER_FULL_NAME" /></translation> +<translation id="2232379019872353004">Sends some system information and page content to Google</translation> +<translation id="2234876718134438132">Sync and Google services</translation> +<translation id="2259659629660284697">Export passwords…</translation> +<translation id="2268044343513325586">Refine</translation> +<translation id="2280910239864711607">Open a new tab in private mode</translation> +<translation id="2286841657746966508">Billing address</translation> +<translation id="230115972905494466">No compatible devices found</translation> +<translation id="2315043854645842844">Client side certificate selection is not supported by the operating system.</translation> +<translation id="2321086116217818302">Preparing passwords…</translation> +<translation id="2321958826496381788">Drag the slider until you can read this comfortably. Text should look at least this big after double-tapping on a paragraph.</translation> +<translation id="2323763861024343754">Site storage</translation> +<translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised by you or your parents at any time. Google may use content on sites that you visit, as well as browsing activity and interactions, to personalise Chrome and Google services such as Translate, Search and ads.</translation> +<translation id="2328985652426384049">Can’t sign in</translation> +<translation id="2342981853652716282">Sign in to Chrome to get your bookmarks, passwords and more on all your devices.</translation> +<translation id="2343328333327081434">Installing…</translation> +<translation id="2346253980530904022">Google servers will optimise the pages that you visit, except for HTTPS and Incognito.</translation> +<translation id="2349710944427398404">Total data used by Chrome, including accounts, bookmarks and saved settings</translation> +<translation id="2351097562818989364">Your translate settings have been reset.</translation> +<translation id="2359808026110333948">Continue</translation> +<translation id="2369533728426058518">open tabs</translation> +<translation id="2387895666653383613">Text scaling</translation> +<translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> +<translation id="2410754283952462441">Choose an account</translation> +<translation id="2414672073755873541">No content here</translation> +<translation id="2414886740292270097">Dark</translation> +<translation id="2416359993254398973">Chrome needs permission to access your camera for this site.</translation> +<translation id="2426805022920575512">Choose another account</translation> +<translation id="2433507940547922241">Appearance</translation> +<translation id="2434158240863470628">Download complete <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2436117022029368436">Communicates with Google to improve browsing and Chrome</translation> +<translation id="2440823041667407902">Location access</translation> +<translation id="2450083983707403292">Do you want to start downloading <ph name="FILE_NAME" /> again?</translation> +<translation id="2476578072172137802">Site Settings</translation> +<translation id="2482878487686419369">Notifications</translation> +<translation id="2496180316473517155">Browsing history</translation> +<translation id="2498359688066513246">Help & feedback</translation> +<translation id="2501278716633472235">Go back</translation> +<translation id="2513403576141822879">For more settings that relate to privacy, security and data collection, see <ph name="BEGIN_LINK" />Sync and Google services<ph name="END_LINK" /></translation> +<translation id="2523184218357549926">Sends URLs of pages that you visit to Google</translation> +<translation id="2526148617758225454">Data Saver is on. Manage it in Settings.</translation> +<translation id="2532336938189706096">Web View</translation> +<translation id="2536728043171574184">Viewing an offline copy of this page</translation> +<translation id="2546283357679194313">Cookies and site data</translation> +<translation id="2567385386134582609">IMAGE</translation> +<translation id="2570922361219980984">Location access is also off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="257931822824936280">Expanded – click to collapse.</translation> +<translation id="2581165646603367611">This will clear cookies, cache and other data of sites Chrome doesn't think is important.</translation> +<translation id="2586657967955657006">Clipboard</translation> +<translation id="2587052924345400782">Newer version is available</translation> +<translation id="2593272815202181319">Monospace</translation> +<translation id="2612676031748830579">Card number</translation> +<translation id="2621115761605608342">Allow JavaScript for a specific site.</translation> +<translation id="2625189173221582860">Password copied</translation> +<translation id="2631006050119455616">Saved</translation> +<translation id="2633278372998075009">Private tabs</translation> +<translation id="2647434099613338025">Add language</translation> +<translation id="2650751991977523696">Download file again?</translation> +<translation id="2653659639078652383">Submit</translation> +<translation id="2677748264148917807">Leave</translation> +<translation id="2704606927547763573">Copied</translation> +<translation id="2707726405694321444">Refresh page</translation> +<translation id="2709516037105925701">Auto-fill</translation> +<translation id="271033894570825754">New</translation> +<translation id="2728754400939377704">Sort by site</translation> +<translation id="2744248271121720757">Tap a word to search instantly or see related actions</translation> +<translation id="2762000892062317888">just now</translation> +<translation id="2777555524387840389"><ph name="SECONDS" /> secs left</translation> +<translation id="2781151931089541271">1 sec left</translation> +<translation id="2803478378562657435">Showing saved passwords and password options</translation> +<translation id="2810645512293415242">Simplified page to save data and load faster.</translation> +<translation id="281504910091592009">View and manage saved passwords in your <ph name="BEGIN_LINK" />Google account<ph name="END_LINK" /></translation> +<translation id="2818669890320396765">To get your bookmarks on all your devices, sign in and turn on sync</translation> +<translation id="2836148919159985482">Touch the back button to exit full screen.</translation> +<translation id="2842985007712546952">Parent folder</translation> +<translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Previous track</translation> +<translation id="2876764156902388290">Chrome is using less data to show you this page</translation> +<translation id="2888126860611144412">About Chrome</translation> +<translation id="2891154217021530873">Stop page loading</translation> +<translation id="2900528713135656174">Create event</translation> +<translation id="2902702728133930130">Chrome failed during start-up with an unexpected error.</translation> +<translation id="290376772003165898">Page is not in <ph name="LANGUAGE" />?</translation> +<translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> +<translation id="2913331724188855103">Allow sites to save and read cookie data (recommended)</translation> +<translation id="2932150158123903946">Google <ph name="APP_NAME" /> storage</translation> +<translation id="2943166482989655199">Improve Chrome and its security by sending system and usage data to Google</translation> +<translation id="2956410042958133412">This account is managed by <ph name="PARENT_NAME_1" /> and <ph name="PARENT_NAME_2" />.</translation> +<translation id="2960796085439532066">Copyright <ph name="YEAR" /> Google Inc. All rights reserved.</translation> +<translation id="2962095958535813455">Switched to incognito tabs</translation> +<translation id="2968755619301702150">Certificate viewer</translation> +<translation id="2979025552038692506">Selected Incognito Tab</translation> +<translation id="2989523299700148168">Recently Visited</translation> +<translation id="2996291259634659425">Create passphrase</translation> +<translation id="2996809686854298943">URL required</translation> +<translation id="300526633675317032">This will clear all <ph name="SIZE_IN_KB" /> of website storage.</translation> +<translation id="3029613699374795922">Downloaded <ph name="KBS" /> KB</translation> +<translation id="3029704984691124060">Passphrases do not match</translation> +<translation id="3036750288708366620"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /></translation> +<translation id="3045654778214005718">See more like this from Google</translation> +<translation id="305593374596241526">Location is off; turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="307908932405420782">More articles will appear soon. Enjoy your morning!</translation> +<translation id="3089395242580810162">Open in incognito tab</translation> +<translation id="311456632243022227">Multiple links opened in Chrome</translation> +<translation id="3115898365077584848">Show info</translation> +<translation id="3137521801621304719">Leave incognito mode</translation> +<translation id="3148434565183091099">To get your bookmarks on all your devices, sign in to Chrome.</translation> +<translation id="3157842584138209013">See how much data you've saved from the More Options button</translation> +<translation id="3166827708714933426">Tab and window shortcuts</translation> +<translation id="3190152372525844641">Turn on permissions for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> stored data</translation> +<translation id="3207960819495026254">Bookmarked</translation> +<translation id="321773570071367578">If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="3227137524299004712">Microphone</translation> +<translation id="3232754137068452469">Web App</translation> +<translation id="3234355010754616171">New private tab</translation> +<translation id="3236059992281584593">1 min left</translation> +<translation id="3244271242291266297">MM</translation> +<translation id="3254409185687681395">Bookmark this page</translation> +<translation id="3259831549858767975">Make everything on the page smaller</translation> +<translation id="3269093882174072735">Load image</translation> +<translation id="3269956123044984603">To get your tabs from your other devices, turn on “Auto-sync data” in Android account settings.</translation> +<translation id="3282568296779691940">Sign in to Chrome</translation> +<translation id="32895400574683172">Notifications are allowed</translation> +<translation id="3295602654194328831">Hide info</translation> +<translation id="3298243779924642547">Lite</translation> +<translation id="3303414029551471755">Proceed to download the content?</translation> +<translation id="3328801116991980348">Site information</translation> +<translation id="3341058695485821946">See how much data you've saved</translation> +<translation id="3350687908700087792">Close all incognito tabs</translation> +<translation id="3365671512111106261">Unavailable when Data Saver is turned on</translation> +<translation id="3367813778245106622">Sign in again to start sync</translation> +<translation id="3377025655491224618">Private tab</translation> +<translation id="3384347053049321195">Share image</translation> +<translation id="3386292677130313581">Ask before allowing sites to know your location (recommended)</translation> +<translation id="3387650086002190359"><ph name="FILE_NAME" /> download failed due to file system errors.</translation> +<translation id="339329030417445648">This site tends to show intrusive ads</translation> +<translation id="3398320232533725830">Open the bookmarks manager</translation> +<translation id="3414952576877147120">Size:</translation> +<translation id="3443221991560634068">Reload the current page</translation> +<translation id="3452612588551937789">Sign in with your Google Account to get your bookmarks, history, passwords and other settings on all your devices.</translation> +<translation id="3485359633434254965">{FILES,plural, =1{%1$d file downloaded}other{%1$d files downloaded}}</translation> +<translation id="3492207499832628349">New incognito tab</translation> +<translation id="3493531032208478708"><ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /> about suggested content</translation> +<translation id="3518985090088779359">Accept & continue</translation> +<translation id="3522247891732774234">Update available. More options</translation> +<translation id="3527085408025491307">Folder</translation> +<translation id="3542235761944717775"><ph name="KILOBYTES" /> KB available</translation> +<translation id="3549644494707163724">Encrypt all synced data with your own sync passphrase</translation> +<translation id="3549657413697417275">Search your history</translation> +<translation id="3552151358455404883">Manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="3557336313807607643">Add to contacts</translation> +<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="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="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="3600792891314830896">Mute sites that play sound</translation> +<translation id="360207483134687714">Help improve the VR experience in Chrome</translation> +<translation id="3616113530831147358">Audio</translation> +<translation id="3620176948598597475">Resetting erases Data Saver history, including the list of visited sites.</translation> +<translation id="3630011985153972676">Allow Chrome to download articles for you when on Wi-Fi under settings.</translation> +<translation id="3632295766818638029">Unmask password</translation> +<translation id="363596933471559332">Automatically sign in to websites using stored credentials. When the feature is off, you’ll be asked for verification every time before signing in to a website.</translation> +<translation id="3661699943263275414">Third-party websites can save and read cookie data</translation> +<translation id="3662546969139119822">No history here</translation> +<translation id="3672452749423051839">Navigation error suggestions</translation> +<translation id="3692944402865947621"><ph name="FILE_NAME" /> download failed because storage location is not reachable.</translation> +<translation id="3712575778697986964">Reset Data Saver?</translation> +<translation id="3714981814255182093">Open the Find Bar</translation> +<translation id="3716182511346448902">This page uses too much memory, so Chrome paused it.</translation> +<translation id="3739899004075612870">Bookmarked in <ph name="PRODUCT_NAME" /></translation> +<translation id="3744111309925758534"><ph name="MEGABYTES" /> MB other apps</translation> +<translation id="3744111561329211289">Background sync</translation> +<translation id="3773755127849930740"><ph name="BEGIN_LINK" />Turn on Bluetooth<ph name="END_LINK" /> to allow pairing</translation> +<translation id="3778956594442850293">Added to Home screen</translation> +<translation id="3781011235031427080">More like this opened at half height</translation> +<translation id="3789841737615482174">Install</translation> +<translation id="3810838688059735925">Video</translation> +<translation id="3810973564298564668">Manage</translation> +<translation id="3819178904835489326"><ph name="NUMBER_OF_DOWNLOADS" /> downloads deleted</translation> +<translation id="3819562311292413223">Download articles for you</translation> +<translation id="3822502789641063741">Clear site storage?</translation> +<translation id="385051799172605136">Back</translation> +<translation id="3859306556332390985">Seek forward</translation> +<translation id="3868004864571585162">Cookies, media licences and site data</translation> +<translation id="3894427358181296146">Add folder</translation> +<translation id="3895926599014793903">Force enable zoom</translation> +<translation id="3927692899758076493">Sans Serif</translation> +<translation id="3928666092801078803">Combine my data</translation> +<translation id="393697183122708255">No enabled voice search available</translation> +<translation id="3950820424414687140">Sign in</translation> +<translation id="395206256282351086">Search and site suggestions disabled</translation> +<translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> +<translation id="3967822245660637423">Download complete</translation> +<translation id="397583555483684758">Sync has stopped working</translation> +<translation id="3976396876660209797">Remove and recreate this shortcut</translation> +<translation id="3985215325736559418">Do you want to download <ph name="FILE_NAME" /> again?</translation> +<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="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> +<translation id="3997476611815694295">Unimportant storage</translation> +<translation id="4002066346123236978">Title</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# hr}other{# hrs}}</translation> +<translation id="4042870126885713738">Show suggestions when a web address does not resolve or a connection cannot be made</translation> +<translation id="4046123991198612571">Next track</translation> +<translation id="4048707525896921369">Learn about topics on websites without leaving the page. Tap to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results and other details. + +To adjust your search term, long press to select. To refine your search, slide the panel all the way up and tap the search box.</translation> +<translation id="4056223980640387499">Sepia</translation> +<translation id="4060598801229743805">Options available near the top of the screen</translation> +<translation id="4062305924942672200">Legal information</translation> +<translation id="4084682180776658562">Bookmark</translation> +<translation id="4084712963632273211">From <ph name="PUBLISHER_ORIGIN" /> – <ph name="BEGIN_DEEMPHASIZED" />delivered by Google<ph name="END_DEEMPHASIZED" /></translation> +<translation id="4084836577264234537"><ph name="MEGABYTES" /> MB downloaded</translation> +<translation id="4089831646916293264">This feature may interfere with access to premium data services provided by your operator.</translation> +<translation id="4095146165863963773">Delete app data?</translation> +<translation id="4097739989936358050">This app is running in Chrome.</translation> +<translation id="4099578267706723511">Help make Chrome better by sending usage statistics and crash reports to Google.</translation> +<translation id="410351446219883937">Autoplay</translation> +<translation id="4113030288477039509">Managed by your administrator</translation> +<translation id="4116038641877404294">Download pages to use them offline</translation> +<translation id="4127069705158143605">{BOOKMARKS_COUNT,plural, =1{%1$d bookmark}other{%1$d bookmarks}}</translation> +<translation id="4149994727733219643">Simplified view for web pages</translation> +<translation id="4159800535322890630">Block sites from accessing your sensors</translation> +<translation id="4165986682804962316">Site settings</translation> +<translation id="4170011742729630528">The service is not available; try again later.</translation> +<translation id="4179980317383591987"><ph name="AMOUNT" /> used</translation> +<translation id="4181841719683918333">Languages</translation> +<translation id="4192273449750167573">Review your settings on the next screen</translation> +<translation id="4195643157523330669">Open in new tab</translation> +<translation id="4198423547019359126">No available download locations</translation> +<translation id="4209895695669353772">To get personalised content suggested by Google, turn on sync</translation> +<translation id="4226663524361240545">Notifications may vibrate the device</translation> +<translation id="4242533952199664413">Open settings</translation> +<translation id="4243710787042215766">Open in private tab</translation> +<translation id="424864128008805179">Sign out of Chrome?</translation> +<translation id="4256782883801055595">Open-source licences</translation> +<translation id="4259722352634471385">Navigation is blocked: <ph name="URL" /></translation> +<translation id="4262028915562328938">Sync error occurred, tap to get details.</translation> +<translation id="4269820728363426813">Copy link address</translation> +<translation id="4275663329226226506">Media</translation> +<translation id="4278390842282768270">Allowed</translation> +<translation id="4307992518367153382">Basics</translation> +<translation id="4351244548802238354">Close dialogue</translation> +<translation id="4378154925671717803">Phone</translation> +<translation id="4384468725000734951">Using Sogou for search</translation> +<translation id="4398088515904522762">To use this feature, turn on <ph name="BEGIN_LINK" />Activity and interactions<ph name="END_LINK" />.</translation> +<translation id="4404568932422911380">No bookmarks</translation> +<translation id="4409723563706114196">Use page predictions</translation> +<translation id="4412992751769744546">Allow third-party cookies</translation> +<translation id="4419556793104466535">Control sync, personalisation and more</translation> +<translation id="4432792777822557199">Pages in <ph name="SOURCE_LANGUAGE" /> will be translated to <ph name="TARGET_LANGUAGE" /> from now on</translation> +<translation id="4434045419905280838">Pop-ups and redirects</translation> +<translation id="4452411734226507615">Close <ph name="TAB_TITLE" /> tab</translation> +<translation id="4452548195519783679">Bookmarked to <ph name="FOLDER_NAME" /></translation> +<translation id="4453340223357552416"><ph name="FILE_NAME" /> downloaded in <ph name="PRODUCT_NAME" /></translation> +<translation id="4468959413250150279">Mute sound for a specific site.</translation> +<translation id="4472118726404937099">To sync and personalise across devices, sign in and turn on sync</translation> +<translation id="447252321002412580">Help improve Chrome's features and performance</translation> +<translation id="4479647676395637221">Ask first before allowing sites to use your camera (recommended)</translation> +<translation id="4487967297491345095">All Chrome’s app data will be deleted permanently. This includes all files, settings, accounts, databases, etc.</translation> +<translation id="4508440807153586353">Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting you'll need to reset sync. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation> +<translation id="4513387527876475750">{DAYS,plural, =1{# day ago}other{# days ago}}</translation> +<translation id="451872707440238414">Search your bookmarks</translation> +<translation id="4521489764227272523">The selected data has been removed from Chrome and your synced devices. + +Your Google Account may have other forms of browsing history such as searches and activity from other Google services at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="4532845899244822526">Choose folder</translation> +<translation id="4550003330909367850">To view or copy your password here, set screen lock on this device.</translation> +<translation id="4558311620361989323">Web page shortcuts</translation> +<translation id="4561979708150884304">No connection</translation> +<translation id="4565377596337484307">Hide password</translation> +<translation id="4570913071927164677">Details</translation> +<translation id="4572422548854449519">Sign in to managed account</translation> +<translation id="4581964774250883625">You’ve gone incognito.</translation> +<translation id="4583164079174244168">{MINUTES,plural, =1{# minute ago}other{# minutes ago}}</translation> +<translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">This offline page is from <ph name="CREATION_TIME" /> and may differ from the online version.</translation> +<translation id="4605958867780575332">Item removed: <ph name="ITEM_TITLE" /></translation> +<translation id="4616150815774728855">Open <ph name="WEBAPK_NAME" /></translation> +<translation id="4634124774493850572">Use password</translation> +<translation id="4645575059429386691">Managed by your parent</translation> +<translation id="4660011489602794167">Show keyboard</translation> +<translation id="4663756553811254707"><ph name="NUMBER_OF_BOOKMARKS" /> bookmarks deleted</translation> +<translation id="4665282149850138822"><ph name="NAME" /> was added to your Home screen</translation> +<translation id="4684427112815847243">Sync everything</translation> +<translation id="4695891336199304370">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}other{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}}</translation> +<translation id="4698034686595694889">View offline in <ph name="APP_NAME" /></translation> +<translation id="4698413471314543145">Critical functionality required to run Chrome is missing; either your Chrome installation is incomplete or not compatible with this version of Android.</translation> +<translation id="4699172675775169585">Cached images and files</translation> +<translation id="4714588616299687897">Save up to 60% of your data</translation> +<translation id="4719927025381752090">Offer to translate</translation> +<translation id="4720023427747327413">Open in <ph name="PRODUCT_NAME" /></translation> +<translation id="4720982865791209136">Help improve Chrome. <ph name="BEGIN_LINK" />Take survey<ph name="END_LINK" /></translation> +<translation id="4730876730346568982">You are switching sync accounts from <ph name="ACCOUNT_EMAIL_OLD" /> to <ph name="ACCOUNT_EMAIL_NEW" />. Your existing Chrome data is managed by <ph name="MANAGED_DOMAIN" />. This will delete your data from this device, but your data will remain in <ph name="ACCOUNT_EMAIL_OLD" />.</translation> +<translation id="473775607612524610">Update</translation> +<translation id="4738836084190194332">Last synced: <ph name="WHEN" /></translation> +<translation id="4749960740855309258">Open a new tab</translation> +<translation id="4751476147751820511">Motion or light sensors</translation> +<translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download complete.}other{# downloads complete.}}</translation> +<translation id="4766369052440583386">Data Saver is on</translation> +<translation id="4797039098279997504">Touch to return to <ph name="URL_OF_THE_CURRENT_TAB" /></translation> +<translation id="4807098396393229769">Name on card</translation> +<translation id="4807963036345170158">Data Saver is off</translation> +<translation id="4816465935029283692">Data types</translation> +<translation id="4837753911714442426">Open options to print page</translation> +<translation id="4842092870884894799">Showing password generation pop-up</translation> +<translation id="4850886885716139402">View</translation> +<translation id="4860895144060829044">Call</translation> +<translation id="4874967477260347223">Media Licenses</translation> +<translation id="4875775213178255010">Content Suggestions</translation> +<translation id="4878404682131129617">Establishing a tunnel via proxy server failed</translation> +<translation id="4881695831933465202">Open</translation> +<translation id="488187801263602086">Rename file</translation> +<translation id="4882831918239250449">Control how your browsing history is used to personalise Search, ads and more</translation> +<translation id="4883379392681899581">Leave private mode</translation> +<translation id="4885273946141277891">Unsupported number of Chrome instances.</translation> +<translation id="4910889077668685004">Payment apps</translation> +<translation id="4913161338056004800">Reset statistics</translation> +<translation id="4913169188695071480">Stop refreshing</translation> +<translation id="4915549754973153784"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /> while scanning for devices…</translation> +<translation id="4943872375798546930">No results</translation> +<translation id="4956460920135325549">Lite page delivered by Google.</translation> +<translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> is sharing your screen</translation> +<translation id="4961334780091921942">Your passwords, history & more on all devices</translation> +<translation id="4961700429721424617">You are signing out of an account managed by <ph name="MANAGED_DOMAIN" />. This will delete your Chrome data from this device, but your data will remain in your Google account.</translation> +<translation id="497421865427891073">go forward</translation> +<translation id="4988210275050210843">Downloading file (<ph name="MEGABYTES" />).</translation> +<translation id="4988526792673242964">Pages</translation> +<translation id="4996978546172906250">Share via</translation> +<translation id="5004339818306944878">Use up to 60% less data and speed up the web. Google servers will optimise the pages you visit.</translation> +<translation id="5004416275253351869">Google activity controls</translation> +<translation id="5005498671520578047">Copy password</translation> +<translation id="5011311129201317034"><ph name="SITE" /> wants to connect</translation> +<translation id="5013696553129441713">No new suggestions</translation> +<translation id="5016205925109358554">Serif</translation> +<translation id="5039804452771397117">Allow</translation> +<translation id="5040262127954254034">Privacy</translation> +<translation id="5063480226653192405">Usage</translation> +<translation id="5087580092889165836">Add card</translation> +<translation id="5100237604440890931">Collapsed – click to expand.</translation> +<translation id="510275257476243843">1 hour left</translation> +<translation id="5123685120097942451">Incognito tab</translation> +<translation id="5127805178023152808">Sync is off</translation> +<translation id="5129038482087801250">Install web app</translation> +<translation id="5139940364318403933">Learn how to use Google Drive</translation> +<translation id="515227803646670480">Clear stored data</translation> +<translation id="5152843274749979095">No supported apps installed</translation> +<translation id="5161254044473106830">Title required</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download failed.}other{# downloads failed.}}</translation> +<translation id="5168917394043976756">Open navigation drawer</translation> +<translation id="5171365962177408781">Tap to load the new tab page and view suggested articles</translation> +<translation id="5184329579814168207">Open in Chrome</translation> +<translation id="5199929503336119739">Work profile</translation> +<translation id="5210286577605176222">Jump to the previous tab</translation> +<translation id="5210365745912300556">Close tab</translation> +<translation id="5222676887888702881">Sign out</translation> +<translation id="5224771365102442243">With video</translation> +<translation id="5233638681132016545">New tab</translation> +<translation id="5240817131241497236">The settings that control sync, personalisation and other Google services in Chrome have changed. This may affect your current settings.</translation> +<translation id="5264003212305142034"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised at any time. Google may use content on sites that you visit, plus browser activity and interactions, to personalise Chrome and other Google services such as Translate, Search and ads.</translation> +<translation id="5271967389191913893">Device cannot open the content to be downloaded.</translation> +<translation id="528192093759286357">Drag from top and touch the back button to exit full screen.</translation> +<translation id="5284584623296338184">Changes to your bookmarks, history, passwords and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google account.</translation> +<translation id="5300589172476337783">Show</translation> +<translation id="5301954838959518834">OK, got it</translation> +<translation id="5304593522240415983">This field cannot be blank</translation> +<translation id="5308380583665731573">Connect</translation> +<translation id="5308603654685598744">When this feature is turned on, Chrome will offer to translate pages written in other languages using Google Translate.</translation> +<translation id="5313967007315987356">Add site</translation> +<translation id="5317780077021120954">Save</translation> +<translation id="5324858694974489420">Parental Settings</translation> +<translation id="5327248766486351172">Name</translation> +<translation id="5335288049665977812">Allow sites to run JavaScript (recommended)</translation> +<translation id="5345040418939504969">Deleted <ph name="BOOKMARK_TITLE" /></translation> +<translation id="5372829067651257087">URL copied.</translation> +<translation id="5391532827096253100">Your connection to this site is not secure. Site information</translation> +<translation id="5400569084694353794">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="5403644198645076998">Only allow certain sites</translation> +<translation id="5414836363063783498">Verifying…</translation> +<translation id="5423934151118863508">Your most visited pages will appear here</translation> +<translation id="5424588387303617268"><ph name="GIGABYTES" /> GB available</translation> +<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="5447765697759493033">This site will not be translated</translation> +<translation id="545042621069398927">Speeding up your download.</translation> +<translation id="5456381639095306749">Download page</translation> +<translation id="5466407412363861127">This feature uses <ph name="BEGIN_LINK" />sync<ph name="END_LINK" />.</translation> +<translation id="548278423535722844">Open in maps app</translation> +<translation id="5487521232677179737">Clear data</translation> +<translation id="5487729733663684359">Chrome updates are no longer supported for this version of Android.</translation> +<translation id="5494920125229734069">Select all</translation> +<translation id="550684401320795253">Updating Chrome...</translation> +<translation id="5512137114520586844">This account is managed by <ph name="PARENT_NAME" />.</translation> +<translation id="5514904542973294328">Disabled by the administrator of this device</translation> +<translation id="5515439363601853141">Unlock to view your password</translation> +<translation id="5515716148775388141">Your icons have moved to the bottom of the screen</translation> +<translation id="5517095782334947753">You have bookmarks, history, passwords and other settings from <ph name="FROM_ACCOUNT" />.</translation> +<translation id="5524843473235508879">Redirect blocked.</translation> +<translation id="5527082711130173040">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK1" />Update permissions<ph name="END_LINK1" />. Location access is also <ph name="BEGIN_LINK2" />turned off for this device<ph name="END_LINK2" />.</translation> +<translation id="5527111080432883924">Ask before allowing sites to read text and images from the clipboard (recommended)</translation> +<translation id="5530766185686772672">Close incognito tabs</translation> +<translation id="5534640966246046842">Site copied</translation> +<translation id="5537099431952529648">You and your parents can manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="5556459405103347317">Reload</translation> +<translation id="5561549206367097665">Waiting for network…</translation> +<translation id="557283862590186398">Chrome needs permission to access your microphone for this site.</translation> +<translation id="55737423895878184">Location and notifications are allowed</translation> +<translation id="5578795271662203820">Search <ph name="SEARCH_ENGINE" /> for this image</translation> +<translation id="5595485650161345191">Edit address</translation> +<translation id="5596627076506792578">More options</translation> +<translation id="5620299005957670886">Allow sites to access your sensors (recommended)</translation> +<translation id="5620928963363755975">Find your files and pages in Downloads from the More Options button</translation> +<translation id="5626134646977739690">Name:</translation> +<translation id="5639724618331995626">Allow all sites</translation> +<translation id="5648166631817621825">Last 7 days</translation> +<translation id="5655963694829536461">Search your downloads</translation> +<translation id="5659593005791499971">Email</translation> +<translation id="5665379678064389456">Create event in <ph name="APP_NAME" /></translation> +<translation id="5668404140385795438">Override a website’s request to prevent zooming in</translation> +<translation id="5676636989614905379">Cannot play video on <ph name="SCREEN_NAME" />.</translation> +<translation id="5677928146339483299">Blocked</translation> +<translation id="5684874026226664614">Oops. This page could not be translated.</translation> +<translation id="5686790454216892815">File name too long</translation> +<translation id="5689516760719285838">Location</translation> +<translation id="5719837394786370183">Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your incognito tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your Internet service provider or the websites you visit.</translation> +<translation id="572328651809341494">Recent tabs</translation> +<translation id="5726692708398506830">Make everything on the page bigger</translation> +<translation id="5738816946784116349">Chrome Downloads</translation> +<translation id="5748802427693696783">Switched to standard tabs</translation> +<translation id="5749068826913805084">Chrome needs storage access to download files.</translation> +<translation id="5763382633136178763">Incognito tabs</translation> +<translation id="5763514718066511291">Tap to copy the URL for this app</translation> +<translation id="5765780083710877561">Description:</translation> +<translation id="5777170031995031090">Control how Google uses your browsing history to personalise Search, ads and other Google services.</translation> +<translation id="5793665092639000975">Using <ph name="SPACE_USED" /> of <ph name="SPACE_AVAILABLE" /></translation> +<translation id="5804241973901381774">Permissions</translation> +<translation id="5809361687334836369">{HOURS,plural, =1{# hour ago}other{# hours ago}}</translation> +<translation id="5817918615728894473">Pair</translation> +<translation id="583281660410589416">Unknown</translation> +<translation id="5833397272224757657">Uses content on sites that you visit, plus browser activity and interactions, for personalisation</translation> +<translation id="5833984609253377421">Share link</translation> +<translation id="584427517463557805">Selected private tab</translation> +<translation id="5854790677617711513">Older than 30 days</translation> +<translation id="5858741533101922242">Chrome is unable to turn on Bluetooth adaptor</translation> +<translation id="5860033963881614850">Off</translation> +<translation id="5862731021271217234">To get your tabs from your other devices, turn on sync</translation> +<translation id="5864174910718532887">Details: Sorted by site name</translation> +<translation id="5864419784173784555">Waiting for another download…</translation> +<translation id="5865733239029070421">Automatically sends usage statistics and crash reports to Google</translation> +<translation id="5869522115854928033">Saved passwords</translation> +<translation id="5878455346526065919">Block ads from sites that tend to show intrusive ads</translation> +<translation id="5902828464777634901">All local data stored by this website, including cookies, will be deleted.</translation> +<translation id="5911030830365207728">Google Translate</translation> +<translation id="5916664084637901428">On</translation> +<translation id="5919204609460789179">Update <ph name="PRODUCT_NAME" /> to start sync</translation> +<translation id="5937580074298050696"><ph name="AMOUNT" /> saved</translation> +<translation id="5939518447894949180">Reset</translation> +<translation id="5942872142862698679">Using Google for search</translation> +<translation id="5952764234151283551">Sends the URL of a page that you're trying to reach to Google</translation> +<translation id="5956665950594638604">Open the Chrome Help Centre in a new tab</translation> +<translation id="5958275228015807058">Find your files and pages in Downloads</translation> +<translation id="5962718611393537961">Tap to collapse</translation> +<translation id="5990142338020175451">More personal Google services, such as better page suggestions</translation> +<translation id="6000066717592683814">Keep Google</translation> +<translation id="6005538289190791541">Suggested password</translation> +<translation id="6039379616847168523">Jump to the next tab</translation> +<translation id="6040143037577758943">Close</translation> +<translation id="6042308850641462728">More</translation> +<translation id="604996488070107836"><ph name="FILE_NAME" /> download failed due to an unknown error.</translation> +<translation id="605721222689873409">YY</translation> +<translation id="6075798973483050474">Edit home page</translation> +<translation id="60923314841986378"><ph name="HOURS" /> hours left</translation> +<translation id="60924377787140961">More articles will appear soon. Enjoy your afternoon!</translation> +<translation id="6099151465289169210">Switched to private tabs</translation> +<translation id="6108923351542677676">Setup in progress…</translation> +<translation id="6111020039983847643">data used</translation> +<translation id="6112702117600201073">Refreshing page</translation> +<translation id="6127379762771434464">Item removed</translation> +<translation id="6140912465461743537">Country/Region</translation> +<translation id="6154478581116148741">Turn on screen lock in Settings to export your passwords from this device</translation> +<translation id="6159335304067198720"><ph name="PERCENT" /> data savings</translation> +<translation id="6165508094623778733">Learn more</translation> +<translation id="6177111841848151710">Blocked for current search engine</translation> +<translation id="6177390657002841081">Turn on Data Saver</translation> +<translation id="6181444274883918285">Add site exception</translation> +<translation id="618993374665929060">More like this opened at full height</translation> +<translation id="6192333916571137726">Download File</translation> +<translation id="6192792657125177640">Exceptions</translation> +<translation id="6206551242102657620">Connection is secure. Site information</translation> +<translation id="6210748933810148297">Not <ph name="EMAIL" />?</translation> +<translation id="6216432067784365534"><ph name="NAME_OF_LIST_ITEM" /> Options</translation> +<translation id="6221633008163990886">Unlock to export your passwords</translation> +<translation id="6232535412751077445">Enabling “Do Not Track” means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request and how the request is interpreted. + +For example, some websites may respond to this request by showing you ads that aren’t based on other websites that you’ve visited. Many websites will still collect and use your browsing data – for example to improve security, to provide content, ads and recommendations and to generate reporting statistics.</translation> +<translation id="6255999984061454636">Content suggestions</translation> +<translation id="6277522088822131679">There was a problem printing the page. Please try again.</translation> +<translation id="6295158916970320988">All sites</translation> +<translation id="629730747756840877">Account</translation> +<translation id="6303969859164067831">Sign out and turn off sync</translation> +<translation id="6320088164292336938">Vibrate</translation> +<translation id="6324034347079777476">Android system sync disabled</translation> +<translation id="6333140779060797560">Share via <ph name="APPLICATION" /></translation> +<translation id="6336451774241870485">New private tab</translation> +<translation id="6337234675334993532">Encryption</translation> +<translation id="6341580099087024258">Ask where to save files</translation> +<translation id="6343192674172527289">No downloads found</translation> +<translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}}</translation> +<translation id="6364438453358674297">Remove suggestion from history?</translation> +<translation id="6378173571450987352">Details: Sorted by amount of data used</translation> +<translation id="6383961787135158834">Clear Site Storage…</translation> +<translation id="6388207532828177975">Clear & reset</translation> +<translation id="6393863479814692971">Chrome needs permission to access your camera and microphone for this site.</translation> +<translation id="6395288395575013217">LINK</translation> +<translation id="6404511346730675251">Edit bookmark</translation> +<translation id="6406506848690869874">Sync</translation> +<translation id="641643625718530986">Print…</translation> +<translation id="6416782512398055893">Downloaded <ph name="MBS" /> MB</translation> +<translation id="6433501201775827830">Choose your search engine</translation> +<translation id="6437478888915024427">Page info</translation> +<translation id="6447842834002726250">Cookies</translation> +<translation id="6448273550210938826">Search and URL suggestions</translation> +<translation id="6461962085415701688">Can’t open file</translation> +<translation id="6475951671322991020">Download video</translation> +<translation id="6482749332252372425"><ph name="FILE_NAME" /> download failed due to lack of storage space.</translation> +<translation id="6496823230996795692">To use <ph name="APP_NAME" /> for the first time, please connect to the Internet.</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6534565668554028783">Google took too long to respond</translation> +<translation id="6538442820324228105">Downloaded <ph name="GBS" /> GB</translation> +<translation id="654446541061731451">Select a tab to beam</translation> +<translation id="6545017243486555795">Clear All Data</translation> +<translation id="6556716549745717622">Block if site tends to show intrusive ads (recommended)</translation> +<translation id="6560414384669816528">Search with Sogou</translation> +<translation id="6566259936974865419">Chrome has saved you <ph name="GIGABYTES" /> GB</translation> +<translation id="6573096386450695060">Always allow</translation> +<translation id="6573431926118603307">Tabs that you've opened in Chrome on your other devices will appear here.</translation> +<translation id="6575643671698722332">Reset failed. Ensure that your device is online and try again.</translation> +<translation id="6583199322650523874">Bookmark the current page</translation> +<translation id="6584721918629302382">AR</translation> +<translation id="6593061639179217415">Desktop site</translation> +<translation id="6600954340915313787">Copied to Chrome</translation> +<translation id="6608650720463149374"><ph name="GIGABYTES" /> GB</translation> +<translation id="6610147964972079463">Close private tabs</translation> +<translation id="6612358246767739896">Protected content</translation> +<translation id="6627583120233659107">Edit folder</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6643649862576733715">Sort by amount of data saved</translation> +<translation id="6648977384226967773">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}other{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}}</translation> +<translation id="6656545060687952787">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK" />Update permissions<ph name="END_LINK" /></translation> +<translation id="6657585470893396449">Password</translation> +<translation id="6659594942844771486">Tab</translation> +<translation id="666268767214822976">Use a prediction service to show related queries and popular websites as you type in the address bar</translation> +<translation id="666731172850799929">Open in <ph name="APP_NAME" /></translation> +<translation id="666981079809192359">Chrome Privacy Notice</translation> +<translation id="6697492270171225480">Show suggestions for similar pages when a page can't be found</translation> +<translation id="6697947395630195233">Chrome needs access to your location to share your location with this site.</translation> +<translation id="6698801883190606802">Manage synced data</translation> +<translation id="6710213216561001401">Previous</translation> +<translation id="6712388303105732168">See more like this from Google using the More Like This button</translation> +<translation id="6738867403308150051">Downloading…</translation> +<translation id="6746124502594467657">Move down</translation> +<translation id="6762156594045689028">To change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="6766622839693428701">Swipe down to close.</translation> +<translation id="6770414673596662518">Chrome’s Safe Browsing system will also be used to detect malicious pages and protect you from phishing, malware and harmful downloads.</translation> +<translation id="6776813977906306442">Download videos to watch later using the Download button</translation> +<translation id="6790428901817661496">Play</translation> +<translation id="679325081238418596">Get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="6820607729870073286">You have no saved website settings.</translation> +<translation id="6820686453637990663">CVC</translation> +<translation id="6831043979455480757">Translate</translation> +<translation id="6846298663435243399">Loading…</translation> +<translation id="685040365210406336">Make no changes</translation> +<translation id="6850409657436465440">Your download is still in progress</translation> +<translation id="6850830437481525139"><ph name="TAB_COUNT" /> tabs closed</translation> +<translation id="6864459304226931083">Download image</translation> +<translation id="6865313869410766144">Autofill form data</translation> +<translation id="6868088497967843822">Sign in to get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="688738109438487280">Add existing data to <ph name="TO_ACCOUNT" />.</translation> +<translation id="6891726759199484455">Unlock to copy your password</translation> +<translation id="6891858906296486776">{OPEN_TABS,plural, =1{%1$d open tab}other{%1$d open tabs}}</translation> +<translation id="6896758677409633944">Copy</translation> +<translation id="6910211073230771657">Deleted</translation> +<translation id="6912998170423641340">Block sites from reading text and images from the clipboard</translation> +<translation id="6914783257214138813">Your passwords will be visible to anyone who can see the exported file.</translation> +<translation id="6942665639005891494">Change the default download location at any time using the Settings menu option</translation> +<translation id="6945221475159498467">Select</translation> +<translation id="6963642900430330478">This page is dangerous. Site information</translation> +<translation id="6963766334940102469">Delete bookmarks</translation> +<translation id="6965382102122355670">OK</translation> +<translation id="6978479750597523876">Reset translate settings</translation> +<translation id="6979737339423435258">All time</translation> +<translation id="6981982820502123353">Accessibility</translation> +<translation id="6985347914332179298">No downloads here</translation> +<translation id="6990079615885386641">Get the app from the Google Play Store: <ph name="APP_ACTION" /></translation> +<translation id="699220179437400583">Automatically report details of possible security incidents to Google</translation> +<translation id="6992289844737586249">Ask first before allowing sites to use your microphone (recommended)</translation> +<translation id="7016516562562142042">Allowed for current search engine</translation> +<translation id="7021515813996758557"><ph name="FILE_NAME" /> downloaded</translation> +<translation id="7022756207310403729">Open in browser</translation> +<translation id="702463548815491781">Recommended when TalkBack or Switch Access are on</translation> +<translation id="7029809446516969842">Passwords</translation> +<translation id="7031882061095297553">Sync to</translation> +<translation id="7032663816368481562">When you tap More like this <ph name="ICON" /> in the address bar, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="7034608350006174882">Cards and addresses using Google Pay</translation> +<translation id="7053983685419859001">Block</translation> +<translation id="7055152154916055070">Redirect blocked:</translation> +<translation id="7062545763355031412">Accept and switch accounts</translation> +<translation id="7063006564040364415">Could not connect to the sync server.</translation> +<translation id="7066151586745993502">{NUM_SELECTED,plural, =1{1 selected}other{# selected}}</translation> +<translation id="7077143737582773186">SD Card</translation> +<translation id="7087918508125750058"><ph name="ITEM_COUNT" /> selected. Options available near top of the screen</translation> +<translation id="7108338896283013870">Hide</translation> +<translation id="7121362699166175603">Clears history and autocompletions in the address bar. 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="7128222689758636196">Allow for current search engine</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7139148793369023665">More like this closed</translation> +<translation id="7141896414559753902">Block sites from showing pop-ups and redirects (recommended)</translation> +<translation id="7149158118503947153"><ph name="BEGIN_LINK" />Load original page<ph name="END_LINK" /> from <ph name="DOMAIN_NAME" /></translation> +<translation id="7149893636342594995">Last 24 Hours</translation> +<translation id="7176368934862295254"><ph name="KILOBYTES" /> KB</translation> +<translation id="7177466738963138057">You can change this later in Settings</translation> +<translation id="7180611975245234373">Refresh</translation> +<translation id="7189372733857464326">Waiting for Google Play Services to finish updating</translation> +<translation id="7189598951263744875">Share...</translation> +<translation id="7191430249889272776">Tab opened in background.</translation> +<translation id="723171743924126238">Select images</translation> +<translation id="7243308994586599757">Options available near bottom of the screen</translation> +<translation id="7250468141469952378"><ph name="ITEM_COUNT" /> selected</translation> +<translation id="7251326866581677552">Blocked from some sites</translation> +<translation id="7253272406652746122">Add a Google account from the Accounts page in your device’s Settings app.</translation> +<translation id="7274013316676448362">Blocked site</translation> +<translation id="729975465115245577">Your device doesn’t have an app to store the passwords file.</translation> +<translation id="7302081693174882195">Details: Sorted by amount of data saved</translation> +<translation id="7333031090786104871">Still adding previous site</translation> +<translation id="7352939065658542140">VIDEO</translation> +<translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Share 1 selected item}other{Share # selected items}}</translation> +<translation id="7359002509206457351">Access payment methods</translation> +<translation id="7366340029385295517">Casting to <ph name="SCREEN_NAME" /></translation> +<translation id="7375125077091615385">Type:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> +<translation id="7400418766976504921">URL</translation> +<translation id="7403691278183511381">Chrome First Run Experience</translation> +<translation id="741204030948306876">Yes, I'm in</translation> +<translation id="7413229368719586778">Start date <ph name="DATE" /></translation> +<translation id="7423098979219808738">Ask first</translation> +<translation id="7423538860840206698">Blocked from reading clipboard</translation> +<translation id="7431991332293347422">Control how your browsing history is used to personalise Search and more</translation> +<translation id="7437998757836447326">Sign out of Chrome</translation> +<translation id="7444811645081526538">More categories</translation> +<translation id="7445411102860286510">Allow sites to automatically play muted videos (recommended)</translation> +<translation id="7454641608352164238">Not enough space</translation> +<translation id="7455923816558154057">Tap to view</translation> +<translation id="7465104139234185284">Close all private tabs</translation> +<translation id="7473891865547856676">No Thanks</translation> +<translation id="7475192538862203634">If you’re seeing this frequently, try these <ph name="BEGIN_LINK" />suggestions<ph name="END_LINK" />.</translation> +<translation id="7475688122056506577">SD card not found. Some of your files may be missing.</translation> +<translation id="748127970106343339">Confirm device credential deletion</translation> +<translation id="7481312909269577407">Forward</translation> +<translation id="7493994139787901920"><ph name="VERSION" /> (Updated <ph name="TIME_SINCE_UPDATE" />)</translation> +<translation id="7494879913343971937">Show passwords</translation> +<translation id="7494974237137038751">data saved</translation> +<translation id="7498271377022651285">Please wait…</translation> +<translation id="7514365320538308">Download</translation> +<translation id="751961395872307827">Can't connect to the site</translation> +<translation id="7521387064766892559">JavaScript</translation> +<translation id="7542481630195938534">Can’t get suggestions</translation> +<translation id="7562080006725997899">Clear browsing data</translation> +<translation id="756809126120519699">Cleared Chrome data</translation> +<translation id="757524316907819857">Block sites from playing protected content</translation> +<translation id="7589445247086920869">Block for current search engine</translation> +<translation id="7593557518625677601">Open Android settings and re-enable Android system sync to start Chrome sync</translation> +<translation id="7596558890252710462">Operating system</translation> +<translation id="7605594153474022051">Sync isn't working</translation> +<translation id="7612619742409846846">Signed in to Google as</translation> +<translation id="7619072057915878432"><ph name="FILE_NAME" /> download failed due to network failures.</translation> +<translation id="7624880197989616768"><ph name="BEGIN_LINK1" />Get help<ph name="END_LINK1" /> or <ph name="BEGIN_LINK2" />re-scan<ph name="END_LINK2" /></translation> +<translation id="7626032353295482388">Welcome to Chrome</translation> +<translation id="7638584964844754484">Incorrect passphrase</translation> +<translation id="7641339528570811325">Clear browsing data…</translation> +<translation id="7648422057306047504">Encrypt passwords with Google credentials</translation> +<translation id="7649070708921625228">Help</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7665369617277396874">Add account</translation> +<translation id="7682724950699840886">Try the following tips: make sure that there is enough space on your device; try to export again.</translation> +<translation id="7698359219371678927">Create email in <ph name="APP_NAME" /></translation> +<translation id="7704317875155739195">Auto-complete searches and URLs</translation> +<translation id="773466115871691567">Always translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> +<translation id="773905249182896430">Protects you and your device from dangerous sites</translation> +<translation id="7762668264895820836">SD Card <ph name="SD_CARD_NUMBER" /></translation> +<translation id="7764225426217299476">Add address</translation> +<translation id="7765158879357617694">Move</translation> +<translation id="7769602470925380267">Accept and sign out</translation> +<translation id="7772032839648071052">Confirm passphrase</translation> +<translation id="7774809984919390718">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}other{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}}</translation> +<translation id="7781829728241885113">Yesterday</translation> +<translation id="7791543448312431591">Add</translation> +<translation id="780301667611848630">No, thank you</translation> +<translation id="7810647596859435254">Open with…</translation> +<translation id="7821588508402923572">Your data savings will appear here</translation> +<translation id="7832327313660264358">The data that you sync to Google and the features that you use will not change</translation> +<translation id="7837721118676387834">Allow auto-play of muted videos for a specific site.</translation> +<translation id="7846076177841592234">Cancel selection</translation> +<translation id="784934925303690534">Time range</translation> +<translation id="7851858861565204677">Other Devices</translation> +<translation id="7854964836418414587">Close more like this</translation> +<translation id="7875915731392087153">Create email</translation> +<translation id="7876243839304621966">Remove all</translation> +<translation id="7882131421121961860">No history found</translation> +<translation id="7882806643839505685">Allow sound for a specific site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Downloading file.}other{Downloading # files.}}</translation> +<translation id="7929962904089429003">Opening the menu</translation> +<translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> is out of date.</translation> +<translation id="7947953824732555851">Accept and sign in</translation> +<translation id="7963646190083259054">Vendor:</translation> +<translation id="7981313251711023384">Preload pages for faster browsing and searching</translation> +<translation id="79859296434321399">To view augmented reality content, install ARCore</translation> +<translation id="7986741934819883144">Select a contact</translation> +<translation id="7987073022710626672">Chrome Terms of Service</translation> +<translation id="7987764905897278458">Get more Google smarts</translation> +<translation id="7998918019931843664">Re-open closed tab</translation> +<translation id="7999064672810608036">Are you sure that you want to clear all local data, including cookies, and reset all permissions for this website?</translation> +<translation id="8004582292198964060">Browser</translation> +<translation id="8007176423574883786">Turned off for this device</translation> +<translation id="8015452622527143194">Return everything on the page to default size</translation> +<translation id="802154636333426148">Download failed</translation> +<translation id="8026334261755873520">Clear browsing data</translation> +<translation id="8035133914807600019">New folder…</translation> +<translation id="8037411810184515274">VR</translation> +<translation id="8037686209485537503">More like this</translation> +<translation id="8037750541064988519"><ph name="DAYS" /> days left</translation> +<translation id="804335162455518893">SD card not found</translation> +<translation id="805047784848435650">Based on your browsing history</translation> +<translation id="8051695050440594747"><ph name="MEGABYTES" /> MB available</translation> +<translation id="8058746566562539958">Open in new Chrome tab</translation> +<translation id="8063895661287329888">Failed to add bookmark.</translation> +<translation id="806745655614357130">Keep my data separate</translation> +<translation id="8068648041423924542">Unable to select certificate.</translation> +<translation id="8073388330009372546">Open image in new tab</translation> +<translation id="8084114998886531721">Saved password</translation> +<translation id="8087000398470557479">This content is from <ph name="DOMAIN_NAME" />, delivered by Google.</translation> +<translation id="8103578431304235997">Incognito Tab</translation> +<translation id="8105951947646329362">Suggest related pages</translation> +<translation id="8109613176066109935">To get your bookmarks on all your devices, turn on sync</translation> +<translation id="8116925261070264013">Muted</translation> +<translation id="813082847718468539">View site information</translation> +<translation id="8156139159503939589">What languages do you read?</translation> +<translation id="8168435359814927499">Content</translation> +<translation id="8186512483418048923"><ph name="FILES" /> files left</translation> +<translation id="8190358571722158785">1 day left</translation> +<translation id="8200772114523450471">Resume</translation> +<translation id="8209050860603202033">Open image</translation> +<translation id="8220488350232498290"><ph name="GIGABYTES" /> GB downloaded</translation> +<translation id="8249310407154411074">Move to top</translation> +<translation id="8250920743982581267">Documents</translation> +<translation id="825412236959742607">This page uses too much memory, so Chrome removed some content.</translation> +<translation id="8260126382462817229">Try signing in again</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8266862848225348053">Download location</translation> +<translation id="8274165955039650276">See downloads</translation> +<translation id="8283853025636624853">Syncing to <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8310344678080805313">Standard tabs</translation> +<translation id="8313455859591948645">Edit startup page</translation> +<translation id="8316092324682955408"><ph name="DOMAIN_NAME" /> and more sites</translation> +<translation id="8339163506404995330">Pages in <ph name="LANGUAGE" /> will not be translated</translation> +<translation id="8349013245300336738">Sort by amount of data used</translation> +<translation id="8372893542064058268">Allow Background Sync for a specific site.</translation> +<translation id="8374821112118309944">You need to update TalkBack to a newer version.</translation> +<translation id="8393700583063109961">Send message</translation> +<translation id="8413126021676339697">Show full history</translation> +<translation id="8428213095426709021">Settings</translation> +<translation id="8438566539970814960">Make searches and browsing better</translation> +<translation id="8441146129660941386">Seek backward</translation> +<translation id="8445448999790540984">Can’t export passwords</translation> +<translation id="8447861592752582886">Revoke device permission</translation> +<translation id="8477071352266846533">Sync off for <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8487700953926739672">Available offline</translation> +<translation id="8489271220582375723">Open the history page</translation> +<translation id="8493948351860045254">Free up space</translation> +<translation id="8497726226069778601">Nothing to see here… yet</translation> +<translation id="8503559462189395349">Chrome Passwords</translation> +<translation id="8503813439785031346">Username</translation> +<translation id="8504988642345501642">When you scroll up, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="8507520749471379845">Passwords available</translation> +<translation id="8514477925623180633">Export passwords stored with Chrome</translation> +<translation id="8514577642972634246">Enter incognito mode</translation> +<translation id="851751545965956758">Block sites from connecting to devices</translation> +<translation id="8523928698583292556">Delete stored password</translation> +<translation id="854522910157234410">Open this page:</translation> +<translation id="8558485628462305855">To view augmented reality content, update ARCore</translation> +<translation id="8559990750235505898">Offer to translate pages in other languages</translation> +<translation id="8562452229998620586">Your saved passwords will appear here.</translation> +<translation id="8569404424186215731">since <ph name="DATE" /></translation> +<translation id="8571213806525832805">Last 4 weeks</translation> +<translation id="857509777403223202">More articles will appear soon. Enjoy your evening!</translation> +<translation id="857943718398505171">Allowed (recommended)</translation> +<translation id="8583805026567836021">Clearing account data</translation> +<translation id="8609465669617005112">Move up</translation> +<translation id="8616006591992756292">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="8617240290563765734">Open the suggested URL specified in the downloaded content?</translation> +<translation id="862875433388403934">Content (films, music, etc.) downloaded in other applications may no longer be playable until those applications re-acquire licences based on a new device credential. To obtain new licences, connect to the Internet and play your downloaded content.</translation> +<translation id="8636825310635137004">To get your tabs from your other devices, turn on sync.</translation> +<translation id="8641930654639604085">Try to block mature sites</translation> +<translation id="8662811608048051533">Signs you out of most sites.</translation> +<translation id="8664979001105139458">File name already exists</translation> +<translation id="8676374126336081632">Clear input</translation> +<translation id="8687353297350450808">{N_BARS,plural, =1{Signal Strength Level: # bar}other{Signal Strength Level: # bars}}</translation> +<translation id="868929229000858085">Search your contacts</translation> +<translation id="869891660844655955">Expiry date</translation> +<translation id="8719023831149562936">Can’t beam current tab</translation> +<translation id="8725066075913043281">Try again</translation> +<translation id="8728487861892616501">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8730621377337864115">Done</translation> +<translation id="8748850008226585750">Contents hidden</translation> +<translation id="8751914237388039244">Select an image</translation> +<translation id="8788968922598763114">Reopen the last closed tab</translation> +<translation id="8812260976093120287">On some websites, you can pay with above supported payment apps on your device.</translation> +<translation id="8816439037877937734"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome's <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8820817407110198400">Bookmarks</translation> +<translation id="8823704566850948458">Suggest password...</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> +<translation id="883806473910249246">An error occurred while downloading the content.</translation> +<translation id="8840953339110955557">This page may differ from the online version.</translation> +<translation id="8847988622838149491">USB</translation> +<translation id="8853345339104747198"><ph name="TAB_TITLE" />, tab</translation> +<translation id="885701979325669005">Storage</translation> +<translation id="8901170036886848654">No bookmarks found</translation> +<translation id="8909135823018751308">Share…</translation> +<translation id="8912362522468806198">Google Account</translation> +<translation id="8920114477895755567">Waiting for details of parents.</translation> +<translation id="8922289737868596582">Download pages from the More Options button to use them offline</translation> +<translation id="8941729603749328384">www.example.com</translation> +<translation id="8942627711005830162">Open in other window</translation> +<translation id="8951232171465285730">Chrome has saved you <ph name="MEGABYTES" /> MB</translation> +<translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> +<translation id="8972098258593396643">Download to default folder?</translation> +<translation id="8979405271719829084">Download videos to watch later</translation> +<translation id="8981454092730389528">Google Activity Controls</translation> +<translation id="8983677657449185470">Help improve Safe Browsing</translation> +<translation id="8986494364107987395">Automatically send usage statistics and crash reports to Google</translation> +<translation id="8993760627012879038">Open a new tab in Incognito mode</translation> +<translation id="8998729206196772491">You are signing in with an account managed by <ph name="MANAGED_DOMAIN" /> and giving its administrator control over your Chrome data. Your data will become permanently tied to this account. Signing out of Chrome will delete your data from this device, but it will remain stored in your Google account.</translation> +<translation id="9019902583201351841">Managed by your parents</translation> +<translation id="9040142327097499898">Notifications are allowed. Location is off for this device.</translation> +<translation id="9050666287014529139">Passphrase</translation> +<translation id="9060538597317784206">View app <ph name="APP_NAME" /> on the Play Store. Rating: <ph name="APP_RATING" />.</translation> +<translation id="9063523880881406963">Turn off Request desktop site</translation> +<translation id="9065203028668620118">Edit</translation> +<translation id="9070377983101773829">Start voice search</translation> +<translation id="9071742570345586758">To view virtual reality content, install Google VR Services</translation> +<translation id="9074336505530349563">To get personalised content suggested by Google, sign in and turn on sync</translation> +<translation id="9080642952018487277">Enter private mode</translation> +<translation id="9086455579313502267">Unable to access the network</translation> +<translation id="9099018167121903954"><ph name="KILOBYTES" /> KB downloaded</translation> +<translation id="9100505651305367705">Offer to show articles in simplified view, when supported</translation> +<translation id="9100610230175265781">Passphrase required</translation> +<translation id="9100939710791843300">Tap the home button to load the new tab page and view suggested articles</translation> +<translation id="9133515669113036225">Reset device credentials</translation> +<translation id="9133703968756164531"><ph name="ITEM_NAME" /> (<ph name="ITEM_ID" />)</translation> +<translation id="9137013805542155359">Show original</translation> +<translation id="9139068048179869749">Ask before allowing sites to send notifications (recommended)</translation> +<translation id="9155898266292537608">You can also search with a quick tap on a word</translation> +<translation id="9188680907066685419">Sign out of managed account</translation> +<translation id="9204836675896933765">1 file left</translation> +<translation id="9206873250291191720">A</translation> +<translation id="9218033835049520260">Suggest strong password...</translation> +<translation id="9219103736887031265">Images</translation> +<translation id="932327136139879170">Home</translation> +<translation id="932599481871055447">Save data and browse faster</translation> +<translation id="938850635132480979">Error: <ph name="ERROR_CODE" /></translation> +<translation id="945522503751344254">Send feedback</translation> +<translation id="945632385593298557">Access your microphone</translation> +<translation id="951339005376969845">Delete existing data. You can retrieve it by switching back to <ph name="FROM_ACCOUNT" />.</translation> +<translation id="95817756606698420">Chrome can use <ph name="BEGIN_BOLD" />Sogou<ph name="END_BOLD" /> for search in China. You can change this in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="970715775301869095"><ph name="MINUTES" /> mins left</translation> +<translation id="974555521953189084">Enter your passphrase to start sync</translation> +<translation id="981121421437150478">Offline</translation> +<translation id="982182592107339124">This will clear data for all sites, including:</translation> +<translation id="983192555821071799">Close all tabs</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_ta.xtb b/chrome/android/java/strings/translations/android_chrome_strings_ta.xtb new file mode 100644 index 0000000..a963a9ec --- /dev/null +++ b/chrome/android/java/strings/translations/android_chrome_strings_ta.xtb
@@ -0,0 +1,1056 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ta"> +<translation id="1006017844123154345">Open Online</translation> +<translation id="1036727731225946849">Adding <ph name="WEBAPK_NAME" />...</translation> +<translation id="1041308826830691739">From websites</translation> +<translation id="1049743911850919806">Incognito</translation> +<translation id="1054301162707478098">You’ve gone private.</translation> +<translation id="10614374240317010">Never saved</translation> +<translation id="1067922213147265141">Other Google services</translation> +<translation id="1068672505746868501">Never translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="10713315585330490"><ph name="FILE_SIZE" /> – <ph name="DESCRIPTION" /></translation> +<translation id="1080790410959514870">You are signing out of an account managed by <ph name="DOMAIN_NAME" />. This will delete the Chrome data stored on this device, but the data will remain in your Google Account.</translation> +<translation id="1105960400813249514">Screen Capture</translation> +<translation id="1111673857033749125">Bookmarks saved on your other devices will appear here.</translation> +<translation id="1113597929977215864">Show simplified view</translation> +<translation id="1121094540300013208">Usage and crash reports</translation> +<translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download pending.}other{# downloads pending.}}</translation> +<translation id="1145536944570833626">Delete existing data.</translation> +<translation id="1146678959555564648">Enter VR</translation> +<translation id="114721135501989771">Get Google smarts in Chrome</translation> +<translation id="1157102636231978136">Your browsing data and activity, synced to your Google account</translation> +<translation id="116280672541001035">Used</translation> +<translation id="1172593791219290334">Startup Page</translation> +<translation id="1175310183703641346">Your bookmarks, history, passwords and more will no longer be synced to your Google account</translation> +<translation id="1178581264944972037">Pause</translation> +<translation id="1181037720776840403">Remove</translation> +<translation id="1197267115302279827">Move bookmarks</translation> +<translation id="119944043368869598">Clear all</translation> +<translation id="1201402288615127009">Next</translation> +<translation id="1204037785786432551">Download link</translation> +<translation id="1206892813135768548">Copy link text</translation> +<translation id="1208340532756947324">To sync and personalise across devices, turn on sync</translation> +<translation id="1209206284964581585">Hide for now</translation> +<translation id="123724288017357924">Reload the current page, ignoring cached content</translation> +<translation id="124116460088058876">More languages</translation> +<translation id="124678866338384709">Close current tab</translation> +<translation id="1258753120186372309">Google doodle: <ph name="DOODLE_DESCRIPTION" /></translation> +<translation id="1259100630977430756">Pages that you view in private tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your private tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going private doesn’t hide your browsing from your employer, your Internet service provider or the websites that you visit.</translation> +<translation id="127138278192656016">Use sync and all services</translation> +<translation id="1272079795634619415">Stop</translation> +<translation id="1283039547216852943">Tap to expand</translation> +<translation id="1285320974508926690">Never translate this site</translation> +<translation id="1291207594882862231">Clear history, cookies, site data, cache…</translation> +<translation id="129553762522093515">Recently closed</translation> +<translation id="1326317727527857210">To get your tabs from your other devices, sign in to Chrome.</translation> +<translation id="1332501820983677155">Google Chrome feature shortcuts</translation> +<translation id="1360432990279830238">Sign out and turn off sync?</translation> +<translation id="136248372334525878">Preload pages for faster loading and offline reading</translation> +<translation id="1369915414381695676">Site <ph name="SITE_NAME" /> added</translation> +<translation id="1373696734384179344">Insufficient memory to download the selected content.</translation> +<translation id="1376578503827013741">Computing…</translation> +<translation id="138361230106469022">Hi, <ph name="FULL_NAME" /></translation> +<translation id="1383876407941801731">Search</translation> +<translation id="1384959399684842514">Download paused</translation> +<translation id="1389974829397082527">No bookmarks here</translation> +<translation id="1397811292916898096">Search with <ph name="PRODUCT_NAME" /></translation> +<translation id="1397854323885047133">Sync and personalisation</translation> +<translation id="1404122904123200417">Embedded in <ph name="WEBSITE_URL" /></translation> +<translation id="1406000523432664303">“Do Not Track”</translation> +<translation id="1407135791313364759">Open all</translation> +<translation id="1409426117486808224">Simplified view for open tabs</translation> +<translation id="1409879593029778104"><ph name="FILE_NAME" /> download prevented because file already exists.</translation> +<translation id="1414981605391750300">Contacting Google. This may take a minute…</translation> +<translation id="1416550906796893042">Application version</translation> +<translation id="1430915738399379752">Print</translation> +<translation id="1445680696957526815">Chrome’s components are incompatible with one another. Chrome may be upgrading, please try again in a few minutes. If the problem continues, try uninstalling and re-installing Chrome.</translation> +<translation id="1446450296470737166">Allow full control of MIDI devices</translation> +<translation id="145097072038377568">Turned off in Android Settings</translation> +<translation id="1477626028522505441"><ph name="FILE_NAME" /> download failed due to server issues.</translation> +<translation id="1506061864768559482">Search engine</translation> +<translation id="1513352483775369820">Bookmarks and web history</translation> +<translation id="1513858653616922153">Delete password</translation> +<translation id="1516229014686355813">Tap to Search sends the selected word and the current page as context to Google Search. You can turn it off in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="1539064842193522527">Link opened in Chrome</translation> +<translation id="1549000191223877751">Move to other window</translation> +<translation id="1553358976309200471">Update Chrome</translation> +<translation id="1566400915470565838">To use <ph name="APP_NAME" />, please connect to the Internet.</translation> +<translation id="1569387923882100876">Connected device</translation> +<translation id="1571304935088121812">Copy username</translation> +<translation id="1576370611341449972">Download occurs only on Wi-Fi</translation> +<translation id="1612196535745283361">Chrome needs location access to scan for devices. Location access is <ph name="BEGIN_LINK" />turned off for this device<ph name="END_LINK" />.</translation> +<translation id="162035744160882748">Turn on sync, personalisation and other Google services</translation> +<translation id="1620510694547887537">Camera</translation> +<translation id="1623104350909869708">Prevent this page from creating additional dialogues</translation> +<translation id="1628019612362412531">{NUM_SELECTED,plural, =1{Remove 1 selected item}other{Remove # selected items}}</translation> +<translation id="1641113438599504367">Safe Browsing</translation> +<translation id="164269334534774161">You are viewing an offline copy of this page from <ph name="CREATION_TIME" /></translation> +<translation id="1644574205037202324">History</translation> +<translation id="1647391597548383849">Access your camera</translation> +<translation id="1660204651932907780">Allow sites to play sound (recommended)</translation> +<translation id="1670399744444387456">Basic</translation> +<translation id="1671236975893690980">Download pending...</translation> +<translation id="1672586136351118594">Don‘t show again</translation> +<translation id="1709438864123551175">Data Saver</translation> +<translation id="1718835860248848330">Last hour</translation> +<translation id="1729516292547892356">To view virtual reality content, update Google VR Services</translation> +<translation id="1733116627827457509"><ph name="FILE_SIZE" /> – Updated <ph name="TIME_SINCE_UPDATE" /></translation> +<translation id="1736419249208073774">Explore</translation> +<translation id="1743802530341753419">Ask before allowing sites to connect to a device (recommended)</translation> +<translation id="1749561566933687563">Sync your bookmarks</translation> +<translation id="17513872634828108">Open tabs</translation> +<translation id="1756600373018374892">Tap this button for quick access to your tabs.</translation> +<translation id="1779089405699405702">Image decoder</translation> +<translation id="1782483593938241562">End date <ph name="DATE" /></translation> +<translation id="1792959175193046959">Change the default download location at any time</translation> +<translation id="1807246157184219062">Light</translation> +<translation id="1821253160463689938">Uses cookies to remember your preferences, even if you don't visit those pages</translation> +<translation id="1829244130665387512">Find in page</translation> +<translation id="1832521218263067499">Security incidents</translation> +<translation id="1853692000353488670">New incognito tab</translation> +<translation id="1868024384445905608">Chrome now downloads files faster</translation> +<translation id="1878302395768190018">You can customise this at any time in Chrome Settings</translation> +<translation id="1880072593381090678">Popular pages from Chrome</translation> +<translation id="1883903952484604915">My files</translation> +<translation id="1887786770086287077">Location access is off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1891331835972267886"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="189172778771606813">Close navigation drawer</translation> +<translation id="1919345977826869612">Ads</translation> +<translation id="1919950603503897840">Select contacts</translation> +<translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/<ph name="FILE_SIZE_WITH_UNITS" /></translation> +<translation id="1933845786846280168">Selected Tab</translation> +<translation id="1938981467853765413">Provide feedback</translation> +<translation id="194341124344773587">Turn on permission for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1943432128510653496">Save passwords</translation> +<translation id="1944384637046898011">Encrypt all with Google password as of <ph name="TIME" /></translation> +<translation id="1946005195648379376">Control how Google uses your browsing history to personalise Search and other Google services.</translation> +<translation id="1952172573699511566">Websites will show text in your preferred language, when possible.</translation> +<translation id="195283394249132567">Personalised Google services</translation> +<translation id="1966710179511230534">Please update your sign-in details.</translation> +<translation id="1974060860693918893">Advanced</translation> +<translation id="1984937141057606926">Allowed, except third-party</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> button</translation> +<translation id="1989112275319619282">Browse</translation> +<translation id="1993768208584545658"><ph name="SITE" /> wants to pair</translation> +<translation id="1994173015038366702">Site URL</translation> +<translation id="2000419248597011803">Sends some cookies and searches from the address bar and search box to your default search engine</translation> +<translation id="2002537628803770967">Credit cards and addresses using Google Pay</translation> +<translation id="200815880754187296"><ph name="KILOBYTES" /> KB other apps</translation> +<translation id="2017836877785168846">Clears history and autocompletions in the address bar.</translation> +<translation id="2021896219286479412">Full screen site controls</translation> +<translation id="2038563949887743358">Turn on Request desktop site</translation> +<translation id="2045104531052923016"><ph name="GIGABYTES" /> GB other apps</translation> +<translation id="2063713494490388661">Tap to Search</translation> +<translation id="2079545284768500474">Undo</translation> +<translation id="2082238445998314030">Result <ph name="RESULT_NUMBER" /> of <ph name="TOTAL_RESULTS" /></translation> +<translation id="2086652334978798447">To get personalised content suggested by Google, sign in to Chrome.</translation> +<translation id="2091887806945687916">Sound</translation> +<translation id="2095887075102408547">When this feature is turned on, Chrome will use Google servers to compress pages that you visit before downloading them. Pages accessed using private connections (HTTPS) or in Incognito tabs will not be optimised or seen by Google.</translation> +<translation id="2096012225669085171">Sync and personalise across devices</translation> +<translation id="2100273922101894616">Auto Sign-in</translation> +<translation id="2111511281910874386">Go to page</translation> +<translation id="2120297377148151361">Activity and interactions</translation> +<translation id="2122601567107267586">Could not open app</translation> +<translation id="2126426811489709554">Powered by Chrome</translation> +<translation id="2131665479022868825"><ph name="DATA" /> saved</translation> +<translation id="213279576345780926">Closed <ph name="TAB_TITLE" /></translation> +<translation id="2139186145475833000">Add to Home screen</translation> +<translation id="2142289305367051020">Your favourite pages are here</translation> +<translation id="2146738493024040262">Open Instant App</translation> +<translation id="2148716181193084225">Today</translation> +<translation id="2154484045852737596">Edit card</translation> +<translation id="2154710561487035718">Copy URL</translation> +<translation id="2156074688469523661">Remaining sites (<ph name="NUMBER_OF_SITES" />)</translation> +<translation id="2206488550163399966"><ph name="APP_NAME" />, web app. <ph name="APP_URL" /></translation> +<translation id="2227444325776770048">Continue as <ph name="USER_FULL_NAME" /></translation> +<translation id="2232379019872353004">Sends some system information and page content to Google</translation> +<translation id="2234876718134438132">Sync and Google services</translation> +<translation id="2259659629660284697">Export passwords…</translation> +<translation id="2268044343513325586">Refine</translation> +<translation id="2280910239864711607">Open a new tab in private mode</translation> +<translation id="2286841657746966508">Billing address</translation> +<translation id="230115972905494466">No compatible devices found</translation> +<translation id="2315043854645842844">Client side certificate selection is not supported by the operating system.</translation> +<translation id="2321086116217818302">Preparing passwords…</translation> +<translation id="2321958826496381788">Drag the slider until you can read this comfortably. Text should look at least this big after double-tapping on a paragraph.</translation> +<translation id="2323763861024343754">Site storage</translation> +<translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised by you or your parents at any time. Google may use content on sites that you visit, as well as browsing activity and interactions, to personalise Chrome and Google services such as Translate, Search and ads.</translation> +<translation id="2328985652426384049">Can’t sign in</translation> +<translation id="2342981853652716282">Sign in to Chrome to get your bookmarks, passwords and more on all your devices.</translation> +<translation id="2343328333327081434">Installing…</translation> +<translation id="2346253980530904022">Google servers will optimise the pages that you visit, except for HTTPS and Incognito.</translation> +<translation id="2349710944427398404">Total data used by Chrome, including accounts, bookmarks and saved settings</translation> +<translation id="2351097562818989364">Your translate settings have been reset.</translation> +<translation id="2359808026110333948">Continue</translation> +<translation id="2369533728426058518">open tabs</translation> +<translation id="2387895666653383613">Text scaling</translation> +<translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> +<translation id="2410754283952462441">Choose an account</translation> +<translation id="2414672073755873541">No content here</translation> +<translation id="2414886740292270097">Dark</translation> +<translation id="2416359993254398973">Chrome needs permission to access your camera for this site.</translation> +<translation id="2426805022920575512">Choose another account</translation> +<translation id="2433507940547922241">Appearance</translation> +<translation id="2434158240863470628">Download complete <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2436117022029368436">Communicates with Google to improve browsing and Chrome</translation> +<translation id="2440823041667407902">Location access</translation> +<translation id="2450083983707403292">Do you want to start downloading <ph name="FILE_NAME" /> again?</translation> +<translation id="2476578072172137802">Site Settings</translation> +<translation id="2482878487686419369">Notifications</translation> +<translation id="2496180316473517155">Browsing history</translation> +<translation id="2498359688066513246">Help & feedback</translation> +<translation id="2501278716633472235">Go back</translation> +<translation id="2513403576141822879">For more settings that relate to privacy, security and data collection, see <ph name="BEGIN_LINK" />Sync and Google services<ph name="END_LINK" /></translation> +<translation id="2523184218357549926">Sends URLs of pages that you visit to Google</translation> +<translation id="2526148617758225454">Data Saver is on. Manage it in Settings.</translation> +<translation id="2532336938189706096">Web View</translation> +<translation id="2536728043171574184">Viewing an offline copy of this page</translation> +<translation id="2546283357679194313">Cookies and site data</translation> +<translation id="2567385386134582609">IMAGE</translation> +<translation id="2570922361219980984">Location access is also off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="257931822824936280">Expanded – click to collapse.</translation> +<translation id="2581165646603367611">This will clear cookies, cache and other data of sites Chrome doesn't think is important.</translation> +<translation id="2586657967955657006">Clipboard</translation> +<translation id="2587052924345400782">Newer version is available</translation> +<translation id="2593272815202181319">Monospace</translation> +<translation id="2612676031748830579">Card number</translation> +<translation id="2621115761605608342">Allow JavaScript for a specific site.</translation> +<translation id="2625189173221582860">Password copied</translation> +<translation id="2631006050119455616">Saved</translation> +<translation id="2633278372998075009">Private tabs</translation> +<translation id="2647434099613338025">Add language</translation> +<translation id="2650751991977523696">Download file again?</translation> +<translation id="2653659639078652383">Submit</translation> +<translation id="2677748264148917807">Leave</translation> +<translation id="2704606927547763573">Copied</translation> +<translation id="2707726405694321444">Refresh page</translation> +<translation id="2709516037105925701">Auto-fill</translation> +<translation id="271033894570825754">New</translation> +<translation id="2728754400939377704">Sort by site</translation> +<translation id="2744248271121720757">Tap a word to search instantly or see related actions</translation> +<translation id="2762000892062317888">just now</translation> +<translation id="2777555524387840389"><ph name="SECONDS" /> secs left</translation> +<translation id="2781151931089541271">1 sec left</translation> +<translation id="2803478378562657435">Showing saved passwords and password options</translation> +<translation id="2810645512293415242">Simplified page to save data and load faster.</translation> +<translation id="281504910091592009">View and manage saved passwords in your <ph name="BEGIN_LINK" />Google account<ph name="END_LINK" /></translation> +<translation id="2818669890320396765">To get your bookmarks on all your devices, sign in and turn on sync</translation> +<translation id="2836148919159985482">Touch the back button to exit full screen.</translation> +<translation id="2842985007712546952">Parent folder</translation> +<translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Previous track</translation> +<translation id="2876764156902388290">Chrome is using less data to show you this page</translation> +<translation id="2888126860611144412">About Chrome</translation> +<translation id="2891154217021530873">Stop page loading</translation> +<translation id="2900528713135656174">Create event</translation> +<translation id="2902702728133930130">Chrome failed during start-up with an unexpected error.</translation> +<translation id="290376772003165898">Page is not in <ph name="LANGUAGE" />?</translation> +<translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> +<translation id="2913331724188855103">Allow sites to save and read cookie data (recommended)</translation> +<translation id="2932150158123903946">Google <ph name="APP_NAME" /> storage</translation> +<translation id="2943166482989655199">Improve Chrome and its security by sending system and usage data to Google</translation> +<translation id="2956410042958133412">This account is managed by <ph name="PARENT_NAME_1" /> and <ph name="PARENT_NAME_2" />.</translation> +<translation id="2960796085439532066">Copyright <ph name="YEAR" /> Google Inc. All rights reserved.</translation> +<translation id="2962095958535813455">Switched to incognito tabs</translation> +<translation id="2968755619301702150">Certificate viewer</translation> +<translation id="2979025552038692506">Selected Incognito Tab</translation> +<translation id="2989523299700148168">Recently Visited</translation> +<translation id="2996291259634659425">Create passphrase</translation> +<translation id="2996809686854298943">URL required</translation> +<translation id="300526633675317032">This will clear all <ph name="SIZE_IN_KB" /> of website storage.</translation> +<translation id="3029613699374795922">Downloaded <ph name="KBS" /> KB</translation> +<translation id="3029704984691124060">Passphrases do not match</translation> +<translation id="3036750288708366620"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /></translation> +<translation id="3045654778214005718">See more like this from Google</translation> +<translation id="305593374596241526">Location is off; turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="307908932405420782">More articles will appear soon. Enjoy your morning!</translation> +<translation id="3089395242580810162">Open in incognito tab</translation> +<translation id="311456632243022227">Multiple links opened in Chrome</translation> +<translation id="3115898365077584848">Show info</translation> +<translation id="3137521801621304719">Leave incognito mode</translation> +<translation id="3148434565183091099">To get your bookmarks on all your devices, sign in to Chrome.</translation> +<translation id="3157842584138209013">See how much data you've saved from the More Options button</translation> +<translation id="3166827708714933426">Tab and window shortcuts</translation> +<translation id="3190152372525844641">Turn on permissions for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> stored data</translation> +<translation id="3207960819495026254">Bookmarked</translation> +<translation id="321773570071367578">If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="3227137524299004712">Microphone</translation> +<translation id="3232754137068452469">Web App</translation> +<translation id="3234355010754616171">New private tab</translation> +<translation id="3236059992281584593">1 min left</translation> +<translation id="3244271242291266297">MM</translation> +<translation id="3254409185687681395">Bookmark this page</translation> +<translation id="3259831549858767975">Make everything on the page smaller</translation> +<translation id="3269093882174072735">Load image</translation> +<translation id="3269956123044984603">To get your tabs from your other devices, turn on “Auto-sync data” in Android account settings.</translation> +<translation id="3282568296779691940">Sign in to Chrome</translation> +<translation id="32895400574683172">Notifications are allowed</translation> +<translation id="3295602654194328831">Hide info</translation> +<translation id="3298243779924642547">Lite</translation> +<translation id="3303414029551471755">Proceed to download the content?</translation> +<translation id="3328801116991980348">Site information</translation> +<translation id="3341058695485821946">See how much data you've saved</translation> +<translation id="3350687908700087792">Close all incognito tabs</translation> +<translation id="3365671512111106261">Unavailable when Data Saver is turned on</translation> +<translation id="3367813778245106622">Sign in again to start sync</translation> +<translation id="3377025655491224618">Private tab</translation> +<translation id="3384347053049321195">Share image</translation> +<translation id="3386292677130313581">Ask before allowing sites to know your location (recommended)</translation> +<translation id="3387650086002190359"><ph name="FILE_NAME" /> download failed due to file system errors.</translation> +<translation id="339329030417445648">This site tends to show intrusive ads</translation> +<translation id="3398320232533725830">Open the bookmarks manager</translation> +<translation id="3414952576877147120">Size:</translation> +<translation id="3443221991560634068">Reload the current page</translation> +<translation id="3452612588551937789">Sign in with your Google Account to get your bookmarks, history, passwords and other settings on all your devices.</translation> +<translation id="3485359633434254965">{FILES,plural, =1{%1$d file downloaded}other{%1$d files downloaded}}</translation> +<translation id="3492207499832628349">New incognito tab</translation> +<translation id="3493531032208478708"><ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /> about suggested content</translation> +<translation id="3518985090088779359">Accept & continue</translation> +<translation id="3522247891732774234">Update available. More options</translation> +<translation id="3527085408025491307">Folder</translation> +<translation id="3542235761944717775"><ph name="KILOBYTES" /> KB available</translation> +<translation id="3549644494707163724">Encrypt all synced data with your own sync passphrase</translation> +<translation id="3549657413697417275">Search your history</translation> +<translation id="3552151358455404883">Manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="3557336313807607643">Add to contacts</translation> +<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="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="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="3600792891314830896">Mute sites that play sound</translation> +<translation id="360207483134687714">Help improve the VR experience in Chrome</translation> +<translation id="3616113530831147358">Audio</translation> +<translation id="3620176948598597475">Resetting erases Data Saver history, including the list of visited sites.</translation> +<translation id="3630011985153972676">Allow Chrome to download articles for you when on Wi-Fi under settings.</translation> +<translation id="3632295766818638029">Unmask password</translation> +<translation id="363596933471559332">Automatically sign in to websites using stored credentials. When the feature is off, you’ll be asked for verification every time before signing in to a website.</translation> +<translation id="3661699943263275414">Third-party websites can save and read cookie data</translation> +<translation id="3662546969139119822">No history here</translation> +<translation id="3672452749423051839">Navigation error suggestions</translation> +<translation id="3692944402865947621"><ph name="FILE_NAME" /> download failed because storage location is not reachable.</translation> +<translation id="3712575778697986964">Reset Data Saver?</translation> +<translation id="3714981814255182093">Open the Find Bar</translation> +<translation id="3716182511346448902">This page uses too much memory, so Chrome paused it.</translation> +<translation id="3739899004075612870">Bookmarked in <ph name="PRODUCT_NAME" /></translation> +<translation id="3744111309925758534"><ph name="MEGABYTES" /> MB other apps</translation> +<translation id="3744111561329211289">Background sync</translation> +<translation id="3773755127849930740"><ph name="BEGIN_LINK" />Turn on Bluetooth<ph name="END_LINK" /> to allow pairing</translation> +<translation id="3778956594442850293">Added to Home screen</translation> +<translation id="3781011235031427080">More like this opened at half height</translation> +<translation id="3789841737615482174">Install</translation> +<translation id="3810838688059735925">Video</translation> +<translation id="3810973564298564668">Manage</translation> +<translation id="3819178904835489326"><ph name="NUMBER_OF_DOWNLOADS" /> downloads deleted</translation> +<translation id="3819562311292413223">Download articles for you</translation> +<translation id="3822502789641063741">Clear site storage?</translation> +<translation id="385051799172605136">Back</translation> +<translation id="3859306556332390985">Seek forward</translation> +<translation id="3868004864571585162">Cookies, media licences and site data</translation> +<translation id="3894427358181296146">Add folder</translation> +<translation id="3895926599014793903">Force enable zoom</translation> +<translation id="3927692899758076493">Sans Serif</translation> +<translation id="3928666092801078803">Combine my data</translation> +<translation id="393697183122708255">No enabled voice search available</translation> +<translation id="3950820424414687140">Sign in</translation> +<translation id="395206256282351086">Search and site suggestions disabled</translation> +<translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> +<translation id="3967822245660637423">Download complete</translation> +<translation id="397583555483684758">Sync has stopped working</translation> +<translation id="3976396876660209797">Remove and recreate this shortcut</translation> +<translation id="3985215325736559418">Do you want to download <ph name="FILE_NAME" /> again?</translation> +<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="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> +<translation id="3997476611815694295">Unimportant storage</translation> +<translation id="4002066346123236978">Title</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# hr}other{# hrs}}</translation> +<translation id="4042870126885713738">Show suggestions when a web address does not resolve or a connection cannot be made</translation> +<translation id="4046123991198612571">Next track</translation> +<translation id="4048707525896921369">Learn about topics on websites without leaving the page. Tap to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results and other details. + +To adjust your search term, long press to select. To refine your search, slide the panel all the way up and tap the search box.</translation> +<translation id="4056223980640387499">Sepia</translation> +<translation id="4060598801229743805">Options available near the top of the screen</translation> +<translation id="4062305924942672200">Legal information</translation> +<translation id="4084682180776658562">Bookmark</translation> +<translation id="4084712963632273211">From <ph name="PUBLISHER_ORIGIN" /> – <ph name="BEGIN_DEEMPHASIZED" />delivered by Google<ph name="END_DEEMPHASIZED" /></translation> +<translation id="4084836577264234537"><ph name="MEGABYTES" /> MB downloaded</translation> +<translation id="4089831646916293264">This feature may interfere with access to premium data services provided by your operator.</translation> +<translation id="4095146165863963773">Delete app data?</translation> +<translation id="4097739989936358050">This app is running in Chrome.</translation> +<translation id="4099578267706723511">Help make Chrome better by sending usage statistics and crash reports to Google.</translation> +<translation id="410351446219883937">Autoplay</translation> +<translation id="4113030288477039509">Managed by your administrator</translation> +<translation id="4116038641877404294">Download pages to use them offline</translation> +<translation id="4127069705158143605">{BOOKMARKS_COUNT,plural, =1{%1$d bookmark}other{%1$d bookmarks}}</translation> +<translation id="4149994727733219643">Simplified view for web pages</translation> +<translation id="4159800535322890630">Block sites from accessing your sensors</translation> +<translation id="4165986682804962316">Site settings</translation> +<translation id="4170011742729630528">The service is not available; try again later.</translation> +<translation id="4179980317383591987"><ph name="AMOUNT" /> used</translation> +<translation id="4181841719683918333">Languages</translation> +<translation id="4192273449750167573">Review your settings on the next screen</translation> +<translation id="4195643157523330669">Open in new tab</translation> +<translation id="4198423547019359126">No available download locations</translation> +<translation id="4209895695669353772">To get personalised content suggested by Google, turn on sync</translation> +<translation id="4226663524361240545">Notifications may vibrate the device</translation> +<translation id="4242533952199664413">Open settings</translation> +<translation id="4243710787042215766">Open in private tab</translation> +<translation id="424864128008805179">Sign out of Chrome?</translation> +<translation id="4256782883801055595">Open-source licences</translation> +<translation id="4259722352634471385">Navigation is blocked: <ph name="URL" /></translation> +<translation id="4262028915562328938">Sync error occurred, tap to get details.</translation> +<translation id="4269820728363426813">Copy link address</translation> +<translation id="4275663329226226506">Media</translation> +<translation id="4278390842282768270">Allowed</translation> +<translation id="4307992518367153382">Basics</translation> +<translation id="4351244548802238354">Close dialogue</translation> +<translation id="4378154925671717803">Phone</translation> +<translation id="4384468725000734951">Using Sogou for search</translation> +<translation id="4398088515904522762">To use this feature, turn on <ph name="BEGIN_LINK" />Activity and interactions<ph name="END_LINK" />.</translation> +<translation id="4404568932422911380">No bookmarks</translation> +<translation id="4409723563706114196">Use page predictions</translation> +<translation id="4412992751769744546">Allow third-party cookies</translation> +<translation id="4419556793104466535">Control sync, personalisation and more</translation> +<translation id="4432792777822557199">Pages in <ph name="SOURCE_LANGUAGE" /> will be translated to <ph name="TARGET_LANGUAGE" /> from now on</translation> +<translation id="4434045419905280838">Pop-ups and redirects</translation> +<translation id="4452411734226507615">Close <ph name="TAB_TITLE" /> tab</translation> +<translation id="4452548195519783679">Bookmarked to <ph name="FOLDER_NAME" /></translation> +<translation id="4453340223357552416"><ph name="FILE_NAME" /> downloaded in <ph name="PRODUCT_NAME" /></translation> +<translation id="4468959413250150279">Mute sound for a specific site.</translation> +<translation id="4472118726404937099">To sync and personalise across devices, sign in and turn on sync</translation> +<translation id="447252321002412580">Help improve Chrome's features and performance</translation> +<translation id="4479647676395637221">Ask first before allowing sites to use your camera (recommended)</translation> +<translation id="4487967297491345095">All Chrome’s app data will be deleted permanently. This includes all files, settings, accounts, databases, etc.</translation> +<translation id="4508440807153586353">Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting you'll need to reset sync. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation> +<translation id="4513387527876475750">{DAYS,plural, =1{# day ago}other{# days ago}}</translation> +<translation id="451872707440238414">Search your bookmarks</translation> +<translation id="4521489764227272523">The selected data has been removed from Chrome and your synced devices. + +Your Google Account may have other forms of browsing history such as searches and activity from other Google services at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="4532845899244822526">Choose folder</translation> +<translation id="4550003330909367850">To view or copy your password here, set screen lock on this device.</translation> +<translation id="4558311620361989323">Web page shortcuts</translation> +<translation id="4561979708150884304">No connection</translation> +<translation id="4565377596337484307">Hide password</translation> +<translation id="4570913071927164677">Details</translation> +<translation id="4572422548854449519">Sign in to managed account</translation> +<translation id="4581964774250883625">You’ve gone incognito.</translation> +<translation id="4583164079174244168">{MINUTES,plural, =1{# minute ago}other{# minutes ago}}</translation> +<translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">This offline page is from <ph name="CREATION_TIME" /> and may differ from the online version.</translation> +<translation id="4605958867780575332">Item removed: <ph name="ITEM_TITLE" /></translation> +<translation id="4616150815774728855">Open <ph name="WEBAPK_NAME" /></translation> +<translation id="4634124774493850572">Use password</translation> +<translation id="4645575059429386691">Managed by your parent</translation> +<translation id="4660011489602794167">Show keyboard</translation> +<translation id="4663756553811254707"><ph name="NUMBER_OF_BOOKMARKS" /> bookmarks deleted</translation> +<translation id="4665282149850138822"><ph name="NAME" /> was added to your Home screen</translation> +<translation id="4684427112815847243">Sync everything</translation> +<translation id="4695891336199304370">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}other{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}}</translation> +<translation id="4698034686595694889">View offline in <ph name="APP_NAME" /></translation> +<translation id="4698413471314543145">Critical functionality required to run Chrome is missing; either your Chrome installation is incomplete or not compatible with this version of Android.</translation> +<translation id="4699172675775169585">Cached images and files</translation> +<translation id="4714588616299687897">Save up to 60% of your data</translation> +<translation id="4719927025381752090">Offer to translate</translation> +<translation id="4720023427747327413">Open in <ph name="PRODUCT_NAME" /></translation> +<translation id="4720982865791209136">Help improve Chrome. <ph name="BEGIN_LINK" />Take survey<ph name="END_LINK" /></translation> +<translation id="4730876730346568982">You are switching sync accounts from <ph name="ACCOUNT_EMAIL_OLD" /> to <ph name="ACCOUNT_EMAIL_NEW" />. Your existing Chrome data is managed by <ph name="MANAGED_DOMAIN" />. This will delete your data from this device, but your data will remain in <ph name="ACCOUNT_EMAIL_OLD" />.</translation> +<translation id="473775607612524610">Update</translation> +<translation id="4738836084190194332">Last synced: <ph name="WHEN" /></translation> +<translation id="4749960740855309258">Open a new tab</translation> +<translation id="4751476147751820511">Motion or light sensors</translation> +<translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download complete.}other{# downloads complete.}}</translation> +<translation id="4766369052440583386">Data Saver is on</translation> +<translation id="4797039098279997504">Touch to return to <ph name="URL_OF_THE_CURRENT_TAB" /></translation> +<translation id="4807098396393229769">Name on card</translation> +<translation id="4807963036345170158">Data Saver is off</translation> +<translation id="4816465935029283692">Data types</translation> +<translation id="4837753911714442426">Open options to print page</translation> +<translation id="4842092870884894799">Showing password generation pop-up</translation> +<translation id="4850886885716139402">View</translation> +<translation id="4860895144060829044">Call</translation> +<translation id="4874967477260347223">Media Licenses</translation> +<translation id="4875775213178255010">Content Suggestions</translation> +<translation id="4878404682131129617">Establishing a tunnel via proxy server failed</translation> +<translation id="4881695831933465202">Open</translation> +<translation id="488187801263602086">Rename file</translation> +<translation id="4882831918239250449">Control how your browsing history is used to personalise Search, ads and more</translation> +<translation id="4883379392681899581">Leave private mode</translation> +<translation id="4885273946141277891">Unsupported number of Chrome instances.</translation> +<translation id="4910889077668685004">Payment apps</translation> +<translation id="4913161338056004800">Reset statistics</translation> +<translation id="4913169188695071480">Stop refreshing</translation> +<translation id="4915549754973153784"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /> while scanning for devices…</translation> +<translation id="4943872375798546930">No results</translation> +<translation id="4956460920135325549">Lite page delivered by Google.</translation> +<translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> is sharing your screen</translation> +<translation id="4961334780091921942">Your passwords, history & more on all devices</translation> +<translation id="4961700429721424617">You are signing out of an account managed by <ph name="MANAGED_DOMAIN" />. This will delete your Chrome data from this device, but your data will remain in your Google account.</translation> +<translation id="497421865427891073">go forward</translation> +<translation id="4988210275050210843">Downloading file (<ph name="MEGABYTES" />).</translation> +<translation id="4988526792673242964">Pages</translation> +<translation id="4996978546172906250">Share via</translation> +<translation id="5004339818306944878">Use up to 60% less data and speed up the web. Google servers will optimise the pages you visit.</translation> +<translation id="5004416275253351869">Google activity controls</translation> +<translation id="5005498671520578047">Copy password</translation> +<translation id="5011311129201317034"><ph name="SITE" /> wants to connect</translation> +<translation id="5013696553129441713">No new suggestions</translation> +<translation id="5016205925109358554">Serif</translation> +<translation id="5039804452771397117">Allow</translation> +<translation id="5040262127954254034">Privacy</translation> +<translation id="5063480226653192405">Usage</translation> +<translation id="5087580092889165836">Add card</translation> +<translation id="5100237604440890931">Collapsed – click to expand.</translation> +<translation id="510275257476243843">1 hour left</translation> +<translation id="5123685120097942451">Incognito tab</translation> +<translation id="5127805178023152808">Sync is off</translation> +<translation id="5129038482087801250">Install web app</translation> +<translation id="5139940364318403933">Learn how to use Google Drive</translation> +<translation id="515227803646670480">Clear stored data</translation> +<translation id="5152843274749979095">No supported apps installed</translation> +<translation id="5161254044473106830">Title required</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download failed.}other{# downloads failed.}}</translation> +<translation id="5168917394043976756">Open navigation drawer</translation> +<translation id="5171365962177408781">Tap to load the new tab page and view suggested articles</translation> +<translation id="5184329579814168207">Open in Chrome</translation> +<translation id="5199929503336119739">Work profile</translation> +<translation id="5210286577605176222">Jump to the previous tab</translation> +<translation id="5210365745912300556">Close tab</translation> +<translation id="5222676887888702881">Sign out</translation> +<translation id="5224771365102442243">With video</translation> +<translation id="5233638681132016545">New tab</translation> +<translation id="5240817131241497236">The settings that control sync, personalisation and other Google services in Chrome have changed. This may affect your current settings.</translation> +<translation id="5264003212305142034"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised at any time. Google may use content on sites that you visit, plus browser activity and interactions, to personalise Chrome and other Google services such as Translate, Search and ads.</translation> +<translation id="5271967389191913893">Device cannot open the content to be downloaded.</translation> +<translation id="528192093759286357">Drag from top and touch the back button to exit full screen.</translation> +<translation id="5284584623296338184">Changes to your bookmarks, history, passwords and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google account.</translation> +<translation id="5300589172476337783">Show</translation> +<translation id="5301954838959518834">OK, got it</translation> +<translation id="5304593522240415983">This field cannot be blank</translation> +<translation id="5308380583665731573">Connect</translation> +<translation id="5308603654685598744">When this feature is turned on, Chrome will offer to translate pages written in other languages using Google Translate.</translation> +<translation id="5313967007315987356">Add site</translation> +<translation id="5317780077021120954">Save</translation> +<translation id="5324858694974489420">Parental Settings</translation> +<translation id="5327248766486351172">Name</translation> +<translation id="5335288049665977812">Allow sites to run JavaScript (recommended)</translation> +<translation id="5345040418939504969">Deleted <ph name="BOOKMARK_TITLE" /></translation> +<translation id="5372829067651257087">URL copied.</translation> +<translation id="5391532827096253100">Your connection to this site is not secure. Site information</translation> +<translation id="5400569084694353794">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="5403644198645076998">Only allow certain sites</translation> +<translation id="5414836363063783498">Verifying…</translation> +<translation id="5423934151118863508">Your most visited pages will appear here</translation> +<translation id="5424588387303617268"><ph name="GIGABYTES" /> GB available</translation> +<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="5447765697759493033">This site will not be translated</translation> +<translation id="545042621069398927">Speeding up your download.</translation> +<translation id="5456381639095306749">Download page</translation> +<translation id="5466407412363861127">This feature uses <ph name="BEGIN_LINK" />sync<ph name="END_LINK" />.</translation> +<translation id="548278423535722844">Open in maps app</translation> +<translation id="5487521232677179737">Clear data</translation> +<translation id="5487729733663684359">Chrome updates are no longer supported for this version of Android.</translation> +<translation id="5494920125229734069">Select all</translation> +<translation id="550684401320795253">Updating Chrome...</translation> +<translation id="5512137114520586844">This account is managed by <ph name="PARENT_NAME" />.</translation> +<translation id="5514904542973294328">Disabled by the administrator of this device</translation> +<translation id="5515439363601853141">Unlock to view your password</translation> +<translation id="5515716148775388141">Your icons have moved to the bottom of the screen</translation> +<translation id="5517095782334947753">You have bookmarks, history, passwords and other settings from <ph name="FROM_ACCOUNT" />.</translation> +<translation id="5524843473235508879">Redirect blocked.</translation> +<translation id="5527082711130173040">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK1" />Update permissions<ph name="END_LINK1" />. Location access is also <ph name="BEGIN_LINK2" />turned off for this device<ph name="END_LINK2" />.</translation> +<translation id="5527111080432883924">Ask before allowing sites to read text and images from the clipboard (recommended)</translation> +<translation id="5530766185686772672">Close incognito tabs</translation> +<translation id="5534640966246046842">Site copied</translation> +<translation id="5537099431952529648">You and your parents can manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="5556459405103347317">Reload</translation> +<translation id="5561549206367097665">Waiting for network…</translation> +<translation id="557283862590186398">Chrome needs permission to access your microphone for this site.</translation> +<translation id="55737423895878184">Location and notifications are allowed</translation> +<translation id="5578795271662203820">Search <ph name="SEARCH_ENGINE" /> for this image</translation> +<translation id="5595485650161345191">Edit address</translation> +<translation id="5596627076506792578">More options</translation> +<translation id="5620299005957670886">Allow sites to access your sensors (recommended)</translation> +<translation id="5620928963363755975">Find your files and pages in Downloads from the More Options button</translation> +<translation id="5626134646977739690">Name:</translation> +<translation id="5639724618331995626">Allow all sites</translation> +<translation id="5648166631817621825">Last 7 days</translation> +<translation id="5655963694829536461">Search your downloads</translation> +<translation id="5659593005791499971">Email</translation> +<translation id="5665379678064389456">Create event in <ph name="APP_NAME" /></translation> +<translation id="5668404140385795438">Override a website’s request to prevent zooming in</translation> +<translation id="5676636989614905379">Cannot play video on <ph name="SCREEN_NAME" />.</translation> +<translation id="5677928146339483299">Blocked</translation> +<translation id="5684874026226664614">Oops. This page could not be translated.</translation> +<translation id="5686790454216892815">File name too long</translation> +<translation id="5689516760719285838">Location</translation> +<translation id="5719837394786370183">Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your incognito tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your Internet service provider or the websites you visit.</translation> +<translation id="572328651809341494">Recent tabs</translation> +<translation id="5726692708398506830">Make everything on the page bigger</translation> +<translation id="5738816946784116349">Chrome Downloads</translation> +<translation id="5748802427693696783">Switched to standard tabs</translation> +<translation id="5749068826913805084">Chrome needs storage access to download files.</translation> +<translation id="5763382633136178763">Incognito tabs</translation> +<translation id="5763514718066511291">Tap to copy the URL for this app</translation> +<translation id="5765780083710877561">Description:</translation> +<translation id="5777170031995031090">Control how Google uses your browsing history to personalise Search, ads and other Google services.</translation> +<translation id="5793665092639000975">Using <ph name="SPACE_USED" /> of <ph name="SPACE_AVAILABLE" /></translation> +<translation id="5804241973901381774">Permissions</translation> +<translation id="5809361687334836369">{HOURS,plural, =1{# hour ago}other{# hours ago}}</translation> +<translation id="5817918615728894473">Pair</translation> +<translation id="583281660410589416">Unknown</translation> +<translation id="5833397272224757657">Uses content on sites that you visit, plus browser activity and interactions, for personalisation</translation> +<translation id="5833984609253377421">Share link</translation> +<translation id="584427517463557805">Selected private tab</translation> +<translation id="5854790677617711513">Older than 30 days</translation> +<translation id="5858741533101922242">Chrome is unable to turn on Bluetooth adaptor</translation> +<translation id="5860033963881614850">Off</translation> +<translation id="5862731021271217234">To get your tabs from your other devices, turn on sync</translation> +<translation id="5864174910718532887">Details: Sorted by site name</translation> +<translation id="5864419784173784555">Waiting for another download…</translation> +<translation id="5865733239029070421">Automatically sends usage statistics and crash reports to Google</translation> +<translation id="5869522115854928033">Saved passwords</translation> +<translation id="5878455346526065919">Block ads from sites that tend to show intrusive ads</translation> +<translation id="5902828464777634901">All local data stored by this website, including cookies, will be deleted.</translation> +<translation id="5911030830365207728">Google Translate</translation> +<translation id="5916664084637901428">On</translation> +<translation id="5919204609460789179">Update <ph name="PRODUCT_NAME" /> to start sync</translation> +<translation id="5937580074298050696"><ph name="AMOUNT" /> saved</translation> +<translation id="5939518447894949180">Reset</translation> +<translation id="5942872142862698679">Using Google for search</translation> +<translation id="5952764234151283551">Sends the URL of a page that you're trying to reach to Google</translation> +<translation id="5956665950594638604">Open the Chrome Help Centre in a new tab</translation> +<translation id="5958275228015807058">Find your files and pages in Downloads</translation> +<translation id="5962718611393537961">Tap to collapse</translation> +<translation id="5990142338020175451">More personal Google services, such as better page suggestions</translation> +<translation id="6000066717592683814">Keep Google</translation> +<translation id="6005538289190791541">Suggested password</translation> +<translation id="6039379616847168523">Jump to the next tab</translation> +<translation id="6040143037577758943">Close</translation> +<translation id="6042308850641462728">More</translation> +<translation id="604996488070107836"><ph name="FILE_NAME" /> download failed due to an unknown error.</translation> +<translation id="605721222689873409">YY</translation> +<translation id="6075798973483050474">Edit home page</translation> +<translation id="60923314841986378"><ph name="HOURS" /> hours left</translation> +<translation id="60924377787140961">More articles will appear soon. Enjoy your afternoon!</translation> +<translation id="6099151465289169210">Switched to private tabs</translation> +<translation id="6108923351542677676">Setup in progress…</translation> +<translation id="6111020039983847643">data used</translation> +<translation id="6112702117600201073">Refreshing page</translation> +<translation id="6127379762771434464">Item removed</translation> +<translation id="6140912465461743537">Country/Region</translation> +<translation id="6154478581116148741">Turn on screen lock in Settings to export your passwords from this device</translation> +<translation id="6159335304067198720"><ph name="PERCENT" /> data savings</translation> +<translation id="6165508094623778733">Learn more</translation> +<translation id="6177111841848151710">Blocked for current search engine</translation> +<translation id="6177390657002841081">Turn on Data Saver</translation> +<translation id="6181444274883918285">Add site exception</translation> +<translation id="618993374665929060">More like this opened at full height</translation> +<translation id="6192333916571137726">Download File</translation> +<translation id="6192792657125177640">Exceptions</translation> +<translation id="6206551242102657620">Connection is secure. Site information</translation> +<translation id="6210748933810148297">Not <ph name="EMAIL" />?</translation> +<translation id="6216432067784365534"><ph name="NAME_OF_LIST_ITEM" /> Options</translation> +<translation id="6221633008163990886">Unlock to export your passwords</translation> +<translation id="6232535412751077445">Enabling “Do Not Track” means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request and how the request is interpreted. + +For example, some websites may respond to this request by showing you ads that aren’t based on other websites that you’ve visited. Many websites will still collect and use your browsing data – for example to improve security, to provide content, ads and recommendations and to generate reporting statistics.</translation> +<translation id="6255999984061454636">Content suggestions</translation> +<translation id="6277522088822131679">There was a problem printing the page. Please try again.</translation> +<translation id="6295158916970320988">All sites</translation> +<translation id="629730747756840877">Account</translation> +<translation id="6303969859164067831">Sign out and turn off sync</translation> +<translation id="6320088164292336938">Vibrate</translation> +<translation id="6324034347079777476">Android system sync disabled</translation> +<translation id="6333140779060797560">Share via <ph name="APPLICATION" /></translation> +<translation id="6336451774241870485">New private tab</translation> +<translation id="6337234675334993532">Encryption</translation> +<translation id="6341580099087024258">Ask where to save files</translation> +<translation id="6343192674172527289">No downloads found</translation> +<translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}}</translation> +<translation id="6364438453358674297">Remove suggestion from history?</translation> +<translation id="6378173571450987352">Details: Sorted by amount of data used</translation> +<translation id="6383961787135158834">Clear Site Storage…</translation> +<translation id="6388207532828177975">Clear & reset</translation> +<translation id="6393863479814692971">Chrome needs permission to access your camera and microphone for this site.</translation> +<translation id="6395288395575013217">LINK</translation> +<translation id="6404511346730675251">Edit bookmark</translation> +<translation id="6406506848690869874">Sync</translation> +<translation id="641643625718530986">Print…</translation> +<translation id="6416782512398055893">Downloaded <ph name="MBS" /> MB</translation> +<translation id="6433501201775827830">Choose your search engine</translation> +<translation id="6437478888915024427">Page info</translation> +<translation id="6447842834002726250">Cookies</translation> +<translation id="6448273550210938826">Search and URL suggestions</translation> +<translation id="6461962085415701688">Can’t open file</translation> +<translation id="6475951671322991020">Download video</translation> +<translation id="6482749332252372425"><ph name="FILE_NAME" /> download failed due to lack of storage space.</translation> +<translation id="6496823230996795692">To use <ph name="APP_NAME" /> for the first time, please connect to the Internet.</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6534565668554028783">Google took too long to respond</translation> +<translation id="6538442820324228105">Downloaded <ph name="GBS" /> GB</translation> +<translation id="654446541061731451">Select a tab to beam</translation> +<translation id="6545017243486555795">Clear All Data</translation> +<translation id="6556716549745717622">Block if site tends to show intrusive ads (recommended)</translation> +<translation id="6560414384669816528">Search with Sogou</translation> +<translation id="6566259936974865419">Chrome has saved you <ph name="GIGABYTES" /> GB</translation> +<translation id="6573096386450695060">Always allow</translation> +<translation id="6573431926118603307">Tabs that you've opened in Chrome on your other devices will appear here.</translation> +<translation id="6575643671698722332">Reset failed. Ensure that your device is online and try again.</translation> +<translation id="6583199322650523874">Bookmark the current page</translation> +<translation id="6584721918629302382">AR</translation> +<translation id="6593061639179217415">Desktop site</translation> +<translation id="6600954340915313787">Copied to Chrome</translation> +<translation id="6608650720463149374"><ph name="GIGABYTES" /> GB</translation> +<translation id="6610147964972079463">Close private tabs</translation> +<translation id="6612358246767739896">Protected content</translation> +<translation id="6627583120233659107">Edit folder</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6643649862576733715">Sort by amount of data saved</translation> +<translation id="6648977384226967773">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}other{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}}</translation> +<translation id="6656545060687952787">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK" />Update permissions<ph name="END_LINK" /></translation> +<translation id="6657585470893396449">Password</translation> +<translation id="6659594942844771486">Tab</translation> +<translation id="666268767214822976">Use a prediction service to show related queries and popular websites as you type in the address bar</translation> +<translation id="666731172850799929">Open in <ph name="APP_NAME" /></translation> +<translation id="666981079809192359">Chrome Privacy Notice</translation> +<translation id="6697492270171225480">Show suggestions for similar pages when a page can't be found</translation> +<translation id="6697947395630195233">Chrome needs access to your location to share your location with this site.</translation> +<translation id="6698801883190606802">Manage synced data</translation> +<translation id="6710213216561001401">Previous</translation> +<translation id="6712388303105732168">See more like this from Google using the More Like This button</translation> +<translation id="6738867403308150051">Downloading…</translation> +<translation id="6746124502594467657">Move down</translation> +<translation id="6762156594045689028">To change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="6766622839693428701">Swipe down to close.</translation> +<translation id="6770414673596662518">Chrome’s Safe Browsing system will also be used to detect malicious pages and protect you from phishing, malware and harmful downloads.</translation> +<translation id="6776813977906306442">Download videos to watch later using the Download button</translation> +<translation id="6790428901817661496">Play</translation> +<translation id="679325081238418596">Get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="6820607729870073286">You have no saved website settings.</translation> +<translation id="6820686453637990663">CVC</translation> +<translation id="6831043979455480757">Translate</translation> +<translation id="6846298663435243399">Loading…</translation> +<translation id="685040365210406336">Make no changes</translation> +<translation id="6850409657436465440">Your download is still in progress</translation> +<translation id="6850830437481525139"><ph name="TAB_COUNT" /> tabs closed</translation> +<translation id="6864459304226931083">Download image</translation> +<translation id="6865313869410766144">Autofill form data</translation> +<translation id="6868088497967843822">Sign in to get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="688738109438487280">Add existing data to <ph name="TO_ACCOUNT" />.</translation> +<translation id="6891726759199484455">Unlock to copy your password</translation> +<translation id="6891858906296486776">{OPEN_TABS,plural, =1{%1$d open tab}other{%1$d open tabs}}</translation> +<translation id="6896758677409633944">Copy</translation> +<translation id="6910211073230771657">Deleted</translation> +<translation id="6912998170423641340">Block sites from reading text and images from the clipboard</translation> +<translation id="6914783257214138813">Your passwords will be visible to anyone who can see the exported file.</translation> +<translation id="6942665639005891494">Change the default download location at any time using the Settings menu option</translation> +<translation id="6945221475159498467">Select</translation> +<translation id="6963642900430330478">This page is dangerous. Site information</translation> +<translation id="6963766334940102469">Delete bookmarks</translation> +<translation id="6965382102122355670">OK</translation> +<translation id="6978479750597523876">Reset translate settings</translation> +<translation id="6979737339423435258">All time</translation> +<translation id="6981982820502123353">Accessibility</translation> +<translation id="6985347914332179298">No downloads here</translation> +<translation id="6990079615885386641">Get the app from the Google Play Store: <ph name="APP_ACTION" /></translation> +<translation id="699220179437400583">Automatically report details of possible security incidents to Google</translation> +<translation id="6992289844737586249">Ask first before allowing sites to use your microphone (recommended)</translation> +<translation id="7016516562562142042">Allowed for current search engine</translation> +<translation id="7021515813996758557"><ph name="FILE_NAME" /> downloaded</translation> +<translation id="7022756207310403729">Open in browser</translation> +<translation id="702463548815491781">Recommended when TalkBack or Switch Access are on</translation> +<translation id="7029809446516969842">Passwords</translation> +<translation id="7031882061095297553">Sync to</translation> +<translation id="7032663816368481562">When you tap More like this <ph name="ICON" /> in the address bar, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="7034608350006174882">Cards and addresses using Google Pay</translation> +<translation id="7053983685419859001">Block</translation> +<translation id="7055152154916055070">Redirect blocked:</translation> +<translation id="7062545763355031412">Accept and switch accounts</translation> +<translation id="7063006564040364415">Could not connect to the sync server.</translation> +<translation id="7066151586745993502">{NUM_SELECTED,plural, =1{1 selected}other{# selected}}</translation> +<translation id="7077143737582773186">SD Card</translation> +<translation id="7087918508125750058"><ph name="ITEM_COUNT" /> selected. Options available near top of the screen</translation> +<translation id="7108338896283013870">Hide</translation> +<translation id="7121362699166175603">Clears history and autocompletions in the address bar. 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="7128222689758636196">Allow for current search engine</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7139148793369023665">More like this closed</translation> +<translation id="7141896414559753902">Block sites from showing pop-ups and redirects (recommended)</translation> +<translation id="7149158118503947153"><ph name="BEGIN_LINK" />Load original page<ph name="END_LINK" /> from <ph name="DOMAIN_NAME" /></translation> +<translation id="7149893636342594995">Last 24 Hours</translation> +<translation id="7176368934862295254"><ph name="KILOBYTES" /> KB</translation> +<translation id="7177466738963138057">You can change this later in Settings</translation> +<translation id="7180611975245234373">Refresh</translation> +<translation id="7189372733857464326">Waiting for Google Play Services to finish updating</translation> +<translation id="7189598951263744875">Share...</translation> +<translation id="7191430249889272776">Tab opened in background.</translation> +<translation id="723171743924126238">Select images</translation> +<translation id="7243308994586599757">Options available near bottom of the screen</translation> +<translation id="7250468141469952378"><ph name="ITEM_COUNT" /> selected</translation> +<translation id="7251326866581677552">Blocked from some sites</translation> +<translation id="7253272406652746122">Add a Google account from the Accounts page in your device’s Settings app.</translation> +<translation id="7274013316676448362">Blocked site</translation> +<translation id="729975465115245577">Your device doesn’t have an app to store the passwords file.</translation> +<translation id="7302081693174882195">Details: Sorted by amount of data saved</translation> +<translation id="7333031090786104871">Still adding previous site</translation> +<translation id="7352939065658542140">VIDEO</translation> +<translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Share 1 selected item}other{Share # selected items}}</translation> +<translation id="7359002509206457351">Access payment methods</translation> +<translation id="7366340029385295517">Casting to <ph name="SCREEN_NAME" /></translation> +<translation id="7375125077091615385">Type:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> +<translation id="7400418766976504921">URL</translation> +<translation id="7403691278183511381">Chrome First Run Experience</translation> +<translation id="741204030948306876">Yes, I'm in</translation> +<translation id="7413229368719586778">Start date <ph name="DATE" /></translation> +<translation id="7423098979219808738">Ask first</translation> +<translation id="7423538860840206698">Blocked from reading clipboard</translation> +<translation id="7431991332293347422">Control how your browsing history is used to personalise Search and more</translation> +<translation id="7437998757836447326">Sign out of Chrome</translation> +<translation id="7444811645081526538">More categories</translation> +<translation id="7445411102860286510">Allow sites to automatically play muted videos (recommended)</translation> +<translation id="7454641608352164238">Not enough space</translation> +<translation id="7455923816558154057">Tap to view</translation> +<translation id="7465104139234185284">Close all private tabs</translation> +<translation id="7473891865547856676">No Thanks</translation> +<translation id="7475192538862203634">If you’re seeing this frequently, try these <ph name="BEGIN_LINK" />suggestions<ph name="END_LINK" />.</translation> +<translation id="7475688122056506577">SD card not found. Some of your files may be missing.</translation> +<translation id="748127970106343339">Confirm device credential deletion</translation> +<translation id="7481312909269577407">Forward</translation> +<translation id="7493994139787901920"><ph name="VERSION" /> (Updated <ph name="TIME_SINCE_UPDATE" />)</translation> +<translation id="7494879913343971937">Show passwords</translation> +<translation id="7494974237137038751">data saved</translation> +<translation id="7498271377022651285">Please wait…</translation> +<translation id="7514365320538308">Download</translation> +<translation id="751961395872307827">Can't connect to the site</translation> +<translation id="7521387064766892559">JavaScript</translation> +<translation id="7542481630195938534">Can’t get suggestions</translation> +<translation id="7562080006725997899">Clear browsing data</translation> +<translation id="756809126120519699">Cleared Chrome data</translation> +<translation id="757524316907819857">Block sites from playing protected content</translation> +<translation id="7589445247086920869">Block for current search engine</translation> +<translation id="7593557518625677601">Open Android settings and re-enable Android system sync to start Chrome sync</translation> +<translation id="7596558890252710462">Operating system</translation> +<translation id="7605594153474022051">Sync isn't working</translation> +<translation id="7612619742409846846">Signed in to Google as</translation> +<translation id="7619072057915878432"><ph name="FILE_NAME" /> download failed due to network failures.</translation> +<translation id="7624880197989616768"><ph name="BEGIN_LINK1" />Get help<ph name="END_LINK1" /> or <ph name="BEGIN_LINK2" />re-scan<ph name="END_LINK2" /></translation> +<translation id="7626032353295482388">Welcome to Chrome</translation> +<translation id="7638584964844754484">Incorrect passphrase</translation> +<translation id="7641339528570811325">Clear browsing data…</translation> +<translation id="7648422057306047504">Encrypt passwords with Google credentials</translation> +<translation id="7649070708921625228">Help</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7665369617277396874">Add account</translation> +<translation id="7682724950699840886">Try the following tips: make sure that there is enough space on your device; try to export again.</translation> +<translation id="7698359219371678927">Create email in <ph name="APP_NAME" /></translation> +<translation id="7704317875155739195">Auto-complete searches and URLs</translation> +<translation id="773466115871691567">Always translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> +<translation id="773905249182896430">Protects you and your device from dangerous sites</translation> +<translation id="7762668264895820836">SD Card <ph name="SD_CARD_NUMBER" /></translation> +<translation id="7764225426217299476">Add address</translation> +<translation id="7765158879357617694">Move</translation> +<translation id="7769602470925380267">Accept and sign out</translation> +<translation id="7772032839648071052">Confirm passphrase</translation> +<translation id="7774809984919390718">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}other{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}}</translation> +<translation id="7781829728241885113">Yesterday</translation> +<translation id="7791543448312431591">Add</translation> +<translation id="780301667611848630">No, thank you</translation> +<translation id="7810647596859435254">Open with…</translation> +<translation id="7821588508402923572">Your data savings will appear here</translation> +<translation id="7832327313660264358">The data that you sync to Google and the features that you use will not change</translation> +<translation id="7837721118676387834">Allow auto-play of muted videos for a specific site.</translation> +<translation id="7846076177841592234">Cancel selection</translation> +<translation id="784934925303690534">Time range</translation> +<translation id="7851858861565204677">Other Devices</translation> +<translation id="7854964836418414587">Close more like this</translation> +<translation id="7875915731392087153">Create email</translation> +<translation id="7876243839304621966">Remove all</translation> +<translation id="7882131421121961860">No history found</translation> +<translation id="7882806643839505685">Allow sound for a specific site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Downloading file.}other{Downloading # files.}}</translation> +<translation id="7929962904089429003">Opening the menu</translation> +<translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> is out of date.</translation> +<translation id="7947953824732555851">Accept and sign in</translation> +<translation id="7963646190083259054">Vendor:</translation> +<translation id="7981313251711023384">Preload pages for faster browsing and searching</translation> +<translation id="79859296434321399">To view augmented reality content, install ARCore</translation> +<translation id="7986741934819883144">Select a contact</translation> +<translation id="7987073022710626672">Chrome Terms of Service</translation> +<translation id="7987764905897278458">Get more Google smarts</translation> +<translation id="7998918019931843664">Re-open closed tab</translation> +<translation id="7999064672810608036">Are you sure that you want to clear all local data, including cookies, and reset all permissions for this website?</translation> +<translation id="8004582292198964060">Browser</translation> +<translation id="8007176423574883786">Turned off for this device</translation> +<translation id="8015452622527143194">Return everything on the page to default size</translation> +<translation id="802154636333426148">Download failed</translation> +<translation id="8026334261755873520">Clear browsing data</translation> +<translation id="8035133914807600019">New folder…</translation> +<translation id="8037411810184515274">VR</translation> +<translation id="8037686209485537503">More like this</translation> +<translation id="8037750541064988519"><ph name="DAYS" /> days left</translation> +<translation id="804335162455518893">SD card not found</translation> +<translation id="805047784848435650">Based on your browsing history</translation> +<translation id="8051695050440594747"><ph name="MEGABYTES" /> MB available</translation> +<translation id="8058746566562539958">Open in new Chrome tab</translation> +<translation id="8063895661287329888">Failed to add bookmark.</translation> +<translation id="806745655614357130">Keep my data separate</translation> +<translation id="8068648041423924542">Unable to select certificate.</translation> +<translation id="8073388330009372546">Open image in new tab</translation> +<translation id="8084114998886531721">Saved password</translation> +<translation id="8087000398470557479">This content is from <ph name="DOMAIN_NAME" />, delivered by Google.</translation> +<translation id="8103578431304235997">Incognito Tab</translation> +<translation id="8105951947646329362">Suggest related pages</translation> +<translation id="8109613176066109935">To get your bookmarks on all your devices, turn on sync</translation> +<translation id="8116925261070264013">Muted</translation> +<translation id="813082847718468539">View site information</translation> +<translation id="8156139159503939589">What languages do you read?</translation> +<translation id="8168435359814927499">Content</translation> +<translation id="8186512483418048923"><ph name="FILES" /> files left</translation> +<translation id="8190358571722158785">1 day left</translation> +<translation id="8200772114523450471">Resume</translation> +<translation id="8209050860603202033">Open image</translation> +<translation id="8220488350232498290"><ph name="GIGABYTES" /> GB downloaded</translation> +<translation id="8249310407154411074">Move to top</translation> +<translation id="8250920743982581267">Documents</translation> +<translation id="825412236959742607">This page uses too much memory, so Chrome removed some content.</translation> +<translation id="8260126382462817229">Try signing in again</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8266862848225348053">Download location</translation> +<translation id="8274165955039650276">See downloads</translation> +<translation id="8283853025636624853">Syncing to <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8310344678080805313">Standard tabs</translation> +<translation id="8313455859591948645">Edit startup page</translation> +<translation id="8316092324682955408"><ph name="DOMAIN_NAME" /> and more sites</translation> +<translation id="8339163506404995330">Pages in <ph name="LANGUAGE" /> will not be translated</translation> +<translation id="8349013245300336738">Sort by amount of data used</translation> +<translation id="8372893542064058268">Allow Background Sync for a specific site.</translation> +<translation id="8374821112118309944">You need to update TalkBack to a newer version.</translation> +<translation id="8393700583063109961">Send message</translation> +<translation id="8413126021676339697">Show full history</translation> +<translation id="8428213095426709021">Settings</translation> +<translation id="8438566539970814960">Make searches and browsing better</translation> +<translation id="8441146129660941386">Seek backward</translation> +<translation id="8445448999790540984">Can’t export passwords</translation> +<translation id="8447861592752582886">Revoke device permission</translation> +<translation id="8477071352266846533">Sync off for <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8487700953926739672">Available offline</translation> +<translation id="8489271220582375723">Open the history page</translation> +<translation id="8493948351860045254">Free up space</translation> +<translation id="8497726226069778601">Nothing to see here… yet</translation> +<translation id="8503559462189395349">Chrome Passwords</translation> +<translation id="8503813439785031346">Username</translation> +<translation id="8504988642345501642">When you scroll up, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="8507520749471379845">Passwords available</translation> +<translation id="8514477925623180633">Export passwords stored with Chrome</translation> +<translation id="8514577642972634246">Enter incognito mode</translation> +<translation id="851751545965956758">Block sites from connecting to devices</translation> +<translation id="8523928698583292556">Delete stored password</translation> +<translation id="854522910157234410">Open this page:</translation> +<translation id="8558485628462305855">To view augmented reality content, update ARCore</translation> +<translation id="8559990750235505898">Offer to translate pages in other languages</translation> +<translation id="8562452229998620586">Your saved passwords will appear here.</translation> +<translation id="8569404424186215731">since <ph name="DATE" /></translation> +<translation id="8571213806525832805">Last 4 weeks</translation> +<translation id="857509777403223202">More articles will appear soon. Enjoy your evening!</translation> +<translation id="857943718398505171">Allowed (recommended)</translation> +<translation id="8583805026567836021">Clearing account data</translation> +<translation id="8609465669617005112">Move up</translation> +<translation id="8616006591992756292">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="8617240290563765734">Open the suggested URL specified in the downloaded content?</translation> +<translation id="862875433388403934">Content (films, music, etc.) downloaded in other applications may no longer be playable until those applications re-acquire licences based on a new device credential. To obtain new licences, connect to the Internet and play your downloaded content.</translation> +<translation id="8636825310635137004">To get your tabs from your other devices, turn on sync.</translation> +<translation id="8641930654639604085">Try to block mature sites</translation> +<translation id="8662811608048051533">Signs you out of most sites.</translation> +<translation id="8664979001105139458">File name already exists</translation> +<translation id="8676374126336081632">Clear input</translation> +<translation id="8687353297350450808">{N_BARS,plural, =1{Signal Strength Level: # bar}other{Signal Strength Level: # bars}}</translation> +<translation id="868929229000858085">Search your contacts</translation> +<translation id="869891660844655955">Expiry date</translation> +<translation id="8719023831149562936">Can’t beam current tab</translation> +<translation id="8725066075913043281">Try again</translation> +<translation id="8728487861892616501">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8730621377337864115">Done</translation> +<translation id="8748850008226585750">Contents hidden</translation> +<translation id="8751914237388039244">Select an image</translation> +<translation id="8788968922598763114">Reopen the last closed tab</translation> +<translation id="8812260976093120287">On some websites, you can pay with above supported payment apps on your device.</translation> +<translation id="8816439037877937734"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome's <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8820817407110198400">Bookmarks</translation> +<translation id="8823704566850948458">Suggest password...</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> +<translation id="883806473910249246">An error occurred while downloading the content.</translation> +<translation id="8840953339110955557">This page may differ from the online version.</translation> +<translation id="8847988622838149491">USB</translation> +<translation id="8853345339104747198"><ph name="TAB_TITLE" />, tab</translation> +<translation id="885701979325669005">Storage</translation> +<translation id="8901170036886848654">No bookmarks found</translation> +<translation id="8909135823018751308">Share…</translation> +<translation id="8912362522468806198">Google Account</translation> +<translation id="8920114477895755567">Waiting for details of parents.</translation> +<translation id="8922289737868596582">Download pages from the More Options button to use them offline</translation> +<translation id="8941729603749328384">www.example.com</translation> +<translation id="8942627711005830162">Open in other window</translation> +<translation id="8951232171465285730">Chrome has saved you <ph name="MEGABYTES" /> MB</translation> +<translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> +<translation id="8972098258593396643">Download to default folder?</translation> +<translation id="8979405271719829084">Download videos to watch later</translation> +<translation id="8981454092730389528">Google Activity Controls</translation> +<translation id="8983677657449185470">Help improve Safe Browsing</translation> +<translation id="8986494364107987395">Automatically send usage statistics and crash reports to Google</translation> +<translation id="8993760627012879038">Open a new tab in Incognito mode</translation> +<translation id="8998729206196772491">You are signing in with an account managed by <ph name="MANAGED_DOMAIN" /> and giving its administrator control over your Chrome data. Your data will become permanently tied to this account. Signing out of Chrome will delete your data from this device, but it will remain stored in your Google account.</translation> +<translation id="9019902583201351841">Managed by your parents</translation> +<translation id="9040142327097499898">Notifications are allowed. Location is off for this device.</translation> +<translation id="9050666287014529139">Passphrase</translation> +<translation id="9060538597317784206">View app <ph name="APP_NAME" /> on the Play Store. Rating: <ph name="APP_RATING" />.</translation> +<translation id="9063523880881406963">Turn off Request desktop site</translation> +<translation id="9065203028668620118">Edit</translation> +<translation id="9070377983101773829">Start voice search</translation> +<translation id="9071742570345586758">To view virtual reality content, install Google VR Services</translation> +<translation id="9074336505530349563">To get personalised content suggested by Google, sign in and turn on sync</translation> +<translation id="9080642952018487277">Enter private mode</translation> +<translation id="9086455579313502267">Unable to access the network</translation> +<translation id="9099018167121903954"><ph name="KILOBYTES" /> KB downloaded</translation> +<translation id="9100505651305367705">Offer to show articles in simplified view, when supported</translation> +<translation id="9100610230175265781">Passphrase required</translation> +<translation id="9100939710791843300">Tap the home button to load the new tab page and view suggested articles</translation> +<translation id="9133515669113036225">Reset device credentials</translation> +<translation id="9133703968756164531"><ph name="ITEM_NAME" /> (<ph name="ITEM_ID" />)</translation> +<translation id="9137013805542155359">Show original</translation> +<translation id="9139068048179869749">Ask before allowing sites to send notifications (recommended)</translation> +<translation id="9155898266292537608">You can also search with a quick tap on a word</translation> +<translation id="9188680907066685419">Sign out of managed account</translation> +<translation id="9204836675896933765">1 file left</translation> +<translation id="9206873250291191720">A</translation> +<translation id="9218033835049520260">Suggest strong password...</translation> +<translation id="9219103736887031265">Images</translation> +<translation id="932327136139879170">Home</translation> +<translation id="932599481871055447">Save data and browse faster</translation> +<translation id="938850635132480979">Error: <ph name="ERROR_CODE" /></translation> +<translation id="945522503751344254">Send feedback</translation> +<translation id="945632385593298557">Access your microphone</translation> +<translation id="951339005376969845">Delete existing data. You can retrieve it by switching back to <ph name="FROM_ACCOUNT" />.</translation> +<translation id="95817756606698420">Chrome can use <ph name="BEGIN_BOLD" />Sogou<ph name="END_BOLD" /> for search in China. You can change this in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="970715775301869095"><ph name="MINUTES" /> mins left</translation> +<translation id="974555521953189084">Enter your passphrase to start sync</translation> +<translation id="981121421437150478">Offline</translation> +<translation id="982182592107339124">This will clear data for all sites, including:</translation> +<translation id="983192555821071799">Close all tabs</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/java/strings/translations/android_chrome_strings_te.xtb b/chrome/android/java/strings/translations/android_chrome_strings_te.xtb new file mode 100644 index 0000000..253f0c55 --- /dev/null +++ b/chrome/android/java/strings/translations/android_chrome_strings_te.xtb
@@ -0,0 +1,1056 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="te"> +<translation id="1006017844123154345">Open Online</translation> +<translation id="1036727731225946849">Adding <ph name="WEBAPK_NAME" />...</translation> +<translation id="1041308826830691739">From websites</translation> +<translation id="1049743911850919806">Incognito</translation> +<translation id="1054301162707478098">You’ve gone private.</translation> +<translation id="10614374240317010">Never saved</translation> +<translation id="1067922213147265141">Other Google services</translation> +<translation id="1068672505746868501">Never translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="10713315585330490"><ph name="FILE_SIZE" /> – <ph name="DESCRIPTION" /></translation> +<translation id="1080790410959514870">You are signing out of an account managed by <ph name="DOMAIN_NAME" />. This will delete the Chrome data stored on this device, but the data will remain in your Google Account.</translation> +<translation id="1105960400813249514">Screen Capture</translation> +<translation id="1111673857033749125">Bookmarks saved on your other devices will appear here.</translation> +<translation id="1113597929977215864">Show simplified view</translation> +<translation id="1121094540300013208">Usage and crash reports</translation> +<translation id="1129510026454351943">Details: <ph name="ERROR_DESCRIPTION" /></translation> +<translation id="1141800923049248244">{FILE_COUNT,plural, =1{1 download pending.}other{# downloads pending.}}</translation> +<translation id="1145536944570833626">Delete existing data.</translation> +<translation id="1146678959555564648">Enter VR</translation> +<translation id="114721135501989771">Get Google smarts in Chrome</translation> +<translation id="1157102636231978136">Your browsing data and activity, synced to your Google account</translation> +<translation id="116280672541001035">Used</translation> +<translation id="1172593791219290334">Startup Page</translation> +<translation id="1175310183703641346">Your bookmarks, history, passwords and more will no longer be synced to your Google account</translation> +<translation id="1178581264944972037">Pause</translation> +<translation id="1181037720776840403">Remove</translation> +<translation id="1197267115302279827">Move bookmarks</translation> +<translation id="119944043368869598">Clear all</translation> +<translation id="1201402288615127009">Next</translation> +<translation id="1204037785786432551">Download link</translation> +<translation id="1206892813135768548">Copy link text</translation> +<translation id="1208340532756947324">To sync and personalise across devices, turn on sync</translation> +<translation id="1209206284964581585">Hide for now</translation> +<translation id="123724288017357924">Reload the current page, ignoring cached content</translation> +<translation id="124116460088058876">More languages</translation> +<translation id="124678866338384709">Close current tab</translation> +<translation id="1258753120186372309">Google doodle: <ph name="DOODLE_DESCRIPTION" /></translation> +<translation id="1259100630977430756">Pages that you view in private tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your private tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going private doesn’t hide your browsing from your employer, your Internet service provider or the websites that you visit.</translation> +<translation id="127138278192656016">Use sync and all services</translation> +<translation id="1272079795634619415">Stop</translation> +<translation id="1283039547216852943">Tap to expand</translation> +<translation id="1285320974508926690">Never translate this site</translation> +<translation id="1291207594882862231">Clear history, cookies, site data, cache…</translation> +<translation id="129553762522093515">Recently closed</translation> +<translation id="1326317727527857210">To get your tabs from your other devices, sign in to Chrome.</translation> +<translation id="1332501820983677155">Google Chrome feature shortcuts</translation> +<translation id="1360432990279830238">Sign out and turn off sync?</translation> +<translation id="136248372334525878">Preload pages for faster loading and offline reading</translation> +<translation id="1369915414381695676">Site <ph name="SITE_NAME" /> added</translation> +<translation id="1373696734384179344">Insufficient memory to download the selected content.</translation> +<translation id="1376578503827013741">Computing…</translation> +<translation id="138361230106469022">Hi, <ph name="FULL_NAME" /></translation> +<translation id="1383876407941801731">Search</translation> +<translation id="1384959399684842514">Download paused</translation> +<translation id="1389974829397082527">No bookmarks here</translation> +<translation id="1397811292916898096">Search with <ph name="PRODUCT_NAME" /></translation> +<translation id="1397854323885047133">Sync and personalisation</translation> +<translation id="1404122904123200417">Embedded in <ph name="WEBSITE_URL" /></translation> +<translation id="1406000523432664303">“Do Not Track”</translation> +<translation id="1407135791313364759">Open all</translation> +<translation id="1409426117486808224">Simplified view for open tabs</translation> +<translation id="1409879593029778104"><ph name="FILE_NAME" /> download prevented because file already exists.</translation> +<translation id="1414981605391750300">Contacting Google. This may take a minute…</translation> +<translation id="1416550906796893042">Application version</translation> +<translation id="1430915738399379752">Print</translation> +<translation id="1445680696957526815">Chrome’s components are incompatible with one another. Chrome may be upgrading, please try again in a few minutes. If the problem continues, try uninstalling and re-installing Chrome.</translation> +<translation id="1446450296470737166">Allow full control of MIDI devices</translation> +<translation id="145097072038377568">Turned off in Android Settings</translation> +<translation id="1477626028522505441"><ph name="FILE_NAME" /> download failed due to server issues.</translation> +<translation id="1506061864768559482">Search engine</translation> +<translation id="1513352483775369820">Bookmarks and web history</translation> +<translation id="1513858653616922153">Delete password</translation> +<translation id="1516229014686355813">Tap to Search sends the selected word and the current page as context to Google Search. You can turn it off in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="1539064842193522527">Link opened in Chrome</translation> +<translation id="1549000191223877751">Move to other window</translation> +<translation id="1553358976309200471">Update Chrome</translation> +<translation id="1566400915470565838">To use <ph name="APP_NAME" />, please connect to the Internet.</translation> +<translation id="1569387923882100876">Connected device</translation> +<translation id="1571304935088121812">Copy username</translation> +<translation id="1576370611341449972">Download occurs only on Wi-Fi</translation> +<translation id="1612196535745283361">Chrome needs location access to scan for devices. Location access is <ph name="BEGIN_LINK" />turned off for this device<ph name="END_LINK" />.</translation> +<translation id="162035744160882748">Turn on sync, personalisation and other Google services</translation> +<translation id="1620510694547887537">Camera</translation> +<translation id="1623104350909869708">Prevent this page from creating additional dialogues</translation> +<translation id="1628019612362412531">{NUM_SELECTED,plural, =1{Remove 1 selected item}other{Remove # selected items}}</translation> +<translation id="1641113438599504367">Safe Browsing</translation> +<translation id="164269334534774161">You are viewing an offline copy of this page from <ph name="CREATION_TIME" /></translation> +<translation id="1644574205037202324">History</translation> +<translation id="1647391597548383849">Access your camera</translation> +<translation id="1660204651932907780">Allow sites to play sound (recommended)</translation> +<translation id="1670399744444387456">Basic</translation> +<translation id="1671236975893690980">Download pending...</translation> +<translation id="1672586136351118594">Don‘t show again</translation> +<translation id="1709438864123551175">Data Saver</translation> +<translation id="1718835860248848330">Last hour</translation> +<translation id="1729516292547892356">To view virtual reality content, update Google VR Services</translation> +<translation id="1733116627827457509"><ph name="FILE_SIZE" /> – Updated <ph name="TIME_SINCE_UPDATE" /></translation> +<translation id="1736419249208073774">Explore</translation> +<translation id="1743802530341753419">Ask before allowing sites to connect to a device (recommended)</translation> +<translation id="1749561566933687563">Sync your bookmarks</translation> +<translation id="17513872634828108">Open tabs</translation> +<translation id="1756600373018374892">Tap this button for quick access to your tabs.</translation> +<translation id="1779089405699405702">Image decoder</translation> +<translation id="1782483593938241562">End date <ph name="DATE" /></translation> +<translation id="1792959175193046959">Change the default download location at any time</translation> +<translation id="1807246157184219062">Light</translation> +<translation id="1821253160463689938">Uses cookies to remember your preferences, even if you don't visit those pages</translation> +<translation id="1829244130665387512">Find in page</translation> +<translation id="1832521218263067499">Security incidents</translation> +<translation id="1853692000353488670">New incognito tab</translation> +<translation id="1868024384445905608">Chrome now downloads files faster</translation> +<translation id="1878302395768190018">You can customise this at any time in Chrome Settings</translation> +<translation id="1880072593381090678">Popular pages from Chrome</translation> +<translation id="1883903952484604915">My files</translation> +<translation id="1887786770086287077">Location access is off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1891331835972267886"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="189172778771606813">Close navigation drawer</translation> +<translation id="1919345977826869612">Ads</translation> +<translation id="1919950603503897840">Select contacts</translation> +<translation id="1923695749281512248"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/<ph name="FILE_SIZE_WITH_UNITS" /></translation> +<translation id="1933845786846280168">Selected Tab</translation> +<translation id="1938981467853765413">Provide feedback</translation> +<translation id="194341124344773587">Turn on permission for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="1943432128510653496">Save passwords</translation> +<translation id="1944384637046898011">Encrypt all with Google password as of <ph name="TIME" /></translation> +<translation id="1946005195648379376">Control how Google uses your browsing history to personalise Search and other Google services.</translation> +<translation id="1952172573699511566">Websites will show text in your preferred language, when possible.</translation> +<translation id="195283394249132567">Personalised Google services</translation> +<translation id="1966710179511230534">Please update your sign-in details.</translation> +<translation id="1974060860693918893">Advanced</translation> +<translation id="1984937141057606926">Allowed, except third-party</translation> +<translation id="1987739130650180037"><ph name="MESSAGE" /> <ph name="LINK_NAME" /> button</translation> +<translation id="1989112275319619282">Browse</translation> +<translation id="1993768208584545658"><ph name="SITE" /> wants to pair</translation> +<translation id="1994173015038366702">Site URL</translation> +<translation id="2000419248597011803">Sends some cookies and searches from the address bar and search box to your default search engine</translation> +<translation id="2002537628803770967">Credit cards and addresses using Google Pay</translation> +<translation id="200815880754187296"><ph name="KILOBYTES" /> KB other apps</translation> +<translation id="2017836877785168846">Clears history and autocompletions in the address bar.</translation> +<translation id="2021896219286479412">Full screen site controls</translation> +<translation id="2038563949887743358">Turn on Request desktop site</translation> +<translation id="2045104531052923016"><ph name="GIGABYTES" /> GB other apps</translation> +<translation id="2063713494490388661">Tap to Search</translation> +<translation id="2079545284768500474">Undo</translation> +<translation id="2082238445998314030">Result <ph name="RESULT_NUMBER" /> of <ph name="TOTAL_RESULTS" /></translation> +<translation id="2086652334978798447">To get personalised content suggested by Google, sign in to Chrome.</translation> +<translation id="2091887806945687916">Sound</translation> +<translation id="2095887075102408547">When this feature is turned on, Chrome will use Google servers to compress pages that you visit before downloading them. Pages accessed using private connections (HTTPS) or in Incognito tabs will not be optimised or seen by Google.</translation> +<translation id="2096012225669085171">Sync and personalise across devices</translation> +<translation id="2100273922101894616">Auto Sign-in</translation> +<translation id="2111511281910874386">Go to page</translation> +<translation id="2120297377148151361">Activity and interactions</translation> +<translation id="2122601567107267586">Could not open app</translation> +<translation id="2126426811489709554">Powered by Chrome</translation> +<translation id="2131665479022868825"><ph name="DATA" /> saved</translation> +<translation id="213279576345780926">Closed <ph name="TAB_TITLE" /></translation> +<translation id="2139186145475833000">Add to Home screen</translation> +<translation id="2142289305367051020">Your favourite pages are here</translation> +<translation id="2146738493024040262">Open Instant App</translation> +<translation id="2148716181193084225">Today</translation> +<translation id="2154484045852737596">Edit card</translation> +<translation id="2154710561487035718">Copy URL</translation> +<translation id="2156074688469523661">Remaining sites (<ph name="NUMBER_OF_SITES" />)</translation> +<translation id="2206488550163399966"><ph name="APP_NAME" />, web app. <ph name="APP_URL" /></translation> +<translation id="2227444325776770048">Continue as <ph name="USER_FULL_NAME" /></translation> +<translation id="2232379019872353004">Sends some system information and page content to Google</translation> +<translation id="2234876718134438132">Sync and Google services</translation> +<translation id="2259659629660284697">Export passwords…</translation> +<translation id="2268044343513325586">Refine</translation> +<translation id="2280910239864711607">Open a new tab in private mode</translation> +<translation id="2286841657746966508">Billing address</translation> +<translation id="230115972905494466">No compatible devices found</translation> +<translation id="2315043854645842844">Client side certificate selection is not supported by the operating system.</translation> +<translation id="2321086116217818302">Preparing passwords…</translation> +<translation id="2321958826496381788">Drag the slider until you can read this comfortably. Text should look at least this big after double-tapping on a paragraph.</translation> +<translation id="2323763861024343754">Site storage</translation> +<translation id="2325181368089033281"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised by you or your parents at any time. Google may use content on sites that you visit, as well as browsing activity and interactions, to personalise Chrome and Google services such as Translate, Search and ads.</translation> +<translation id="2328985652426384049">Can’t sign in</translation> +<translation id="2342981853652716282">Sign in to Chrome to get your bookmarks, passwords and more on all your devices.</translation> +<translation id="2343328333327081434">Installing…</translation> +<translation id="2346253980530904022">Google servers will optimise the pages that you visit, except for HTTPS and Incognito.</translation> +<translation id="2349710944427398404">Total data used by Chrome, including accounts, bookmarks and saved settings</translation> +<translation id="2351097562818989364">Your translate settings have been reset.</translation> +<translation id="2359808026110333948">Continue</translation> +<translation id="2369533728426058518">open tabs</translation> +<translation id="2387895666653383613">Text scaling</translation> +<translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> +<translation id="2410754283952462441">Choose an account</translation> +<translation id="2414672073755873541">No content here</translation> +<translation id="2414886740292270097">Dark</translation> +<translation id="2416359993254398973">Chrome needs permission to access your camera for this site.</translation> +<translation id="2426805022920575512">Choose another account</translation> +<translation id="2433507940547922241">Appearance</translation> +<translation id="2434158240863470628">Download complete <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2436117022029368436">Communicates with Google to improve browsing and Chrome</translation> +<translation id="2440823041667407902">Location access</translation> +<translation id="2450083983707403292">Do you want to start downloading <ph name="FILE_NAME" /> again?</translation> +<translation id="2476578072172137802">Site Settings</translation> +<translation id="2482878487686419369">Notifications</translation> +<translation id="2496180316473517155">Browsing history</translation> +<translation id="2498359688066513246">Help & feedback</translation> +<translation id="2501278716633472235">Go back</translation> +<translation id="2513403576141822879">For more settings that relate to privacy, security and data collection, see <ph name="BEGIN_LINK" />Sync and Google services<ph name="END_LINK" /></translation> +<translation id="2523184218357549926">Sends URLs of pages that you visit to Google</translation> +<translation id="2526148617758225454">Data Saver is on. Manage it in Settings.</translation> +<translation id="2532336938189706096">Web View</translation> +<translation id="2536728043171574184">Viewing an offline copy of this page</translation> +<translation id="2546283357679194313">Cookies and site data</translation> +<translation id="2567385386134582609">IMAGE</translation> +<translation id="2570922361219980984">Location access is also off for this device. Turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="257931822824936280">Expanded – click to collapse.</translation> +<translation id="2581165646603367611">This will clear cookies, cache and other data of sites Chrome doesn't think is important.</translation> +<translation id="2586657967955657006">Clipboard</translation> +<translation id="2587052924345400782">Newer version is available</translation> +<translation id="2593272815202181319">Monospace</translation> +<translation id="2612676031748830579">Card number</translation> +<translation id="2621115761605608342">Allow JavaScript for a specific site.</translation> +<translation id="2625189173221582860">Password copied</translation> +<translation id="2631006050119455616">Saved</translation> +<translation id="2633278372998075009">Private tabs</translation> +<translation id="2647434099613338025">Add language</translation> +<translation id="2650751991977523696">Download file again?</translation> +<translation id="2653659639078652383">Submit</translation> +<translation id="2677748264148917807">Leave</translation> +<translation id="2704606927547763573">Copied</translation> +<translation id="2707726405694321444">Refresh page</translation> +<translation id="2709516037105925701">Auto-fill</translation> +<translation id="271033894570825754">New</translation> +<translation id="2728754400939377704">Sort by site</translation> +<translation id="2744248271121720757">Tap a word to search instantly or see related actions</translation> +<translation id="2762000892062317888">just now</translation> +<translation id="2777555524387840389"><ph name="SECONDS" /> secs left</translation> +<translation id="2781151931089541271">1 sec left</translation> +<translation id="2803478378562657435">Showing saved passwords and password options</translation> +<translation id="2810645512293415242">Simplified page to save data and load faster.</translation> +<translation id="281504910091592009">View and manage saved passwords in your <ph name="BEGIN_LINK" />Google account<ph name="END_LINK" /></translation> +<translation id="2818669890320396765">To get your bookmarks on all your devices, sign in and turn on sync</translation> +<translation id="2836148919159985482">Touch the back button to exit full screen.</translation> +<translation id="2842985007712546952">Parent folder</translation> +<translation id="2870560284913253234">Site</translation> +<translation id="2874939134665556319">Previous track</translation> +<translation id="2876764156902388290">Chrome is using less data to show you this page</translation> +<translation id="2888126860611144412">About Chrome</translation> +<translation id="2891154217021530873">Stop page loading</translation> +<translation id="2900528713135656174">Create event</translation> +<translation id="2902702728133930130">Chrome failed during start-up with an unexpected error.</translation> +<translation id="290376772003165898">Page is not in <ph name="LANGUAGE" />?</translation> +<translation id="2910701580606108292">Ask before allowing sites to play protected content</translation> +<translation id="2913331724188855103">Allow sites to save and read cookie data (recommended)</translation> +<translation id="2932150158123903946">Google <ph name="APP_NAME" /> storage</translation> +<translation id="2943166482989655199">Improve Chrome and its security by sending system and usage data to Google</translation> +<translation id="2956410042958133412">This account is managed by <ph name="PARENT_NAME_1" /> and <ph name="PARENT_NAME_2" />.</translation> +<translation id="2960796085439532066">Copyright <ph name="YEAR" /> Google Inc. All rights reserved.</translation> +<translation id="2962095958535813455">Switched to incognito tabs</translation> +<translation id="2968755619301702150">Certificate viewer</translation> +<translation id="2979025552038692506">Selected Incognito Tab</translation> +<translation id="2989523299700148168">Recently Visited</translation> +<translation id="2996291259634659425">Create passphrase</translation> +<translation id="2996809686854298943">URL required</translation> +<translation id="300526633675317032">This will clear all <ph name="SIZE_IN_KB" /> of website storage.</translation> +<translation id="3029613699374795922">Downloaded <ph name="KBS" /> KB</translation> +<translation id="3029704984691124060">Passphrases do not match</translation> +<translation id="3036750288708366620"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /></translation> +<translation id="3045654778214005718">See more like this from Google</translation> +<translation id="305593374596241526">Location is off; turn it on in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="307908932405420782">More articles will appear soon. Enjoy your morning!</translation> +<translation id="3089395242580810162">Open in incognito tab</translation> +<translation id="311456632243022227">Multiple links opened in Chrome</translation> +<translation id="3115898365077584848">Show info</translation> +<translation id="3137521801621304719">Leave incognito mode</translation> +<translation id="3148434565183091099">To get your bookmarks on all your devices, sign in to Chrome.</translation> +<translation id="3157842584138209013">See how much data you've saved from the More Options button</translation> +<translation id="3166827708714933426">Tab and window shortcuts</translation> +<translation id="3190152372525844641">Turn on permissions for Chrome in <ph name="BEGIN_LINK" />Android Settings<ph name="END_LINK" />.</translation> +<translation id="3198916472715691905"><ph name="STORAGE_AMOUNT" /> stored data</translation> +<translation id="3207960819495026254">Bookmarked</translation> +<translation id="321773570071367578">If you forgot your passphrase or want to change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="3227137524299004712">Microphone</translation> +<translation id="3232754137068452469">Web App</translation> +<translation id="3234355010754616171">New private tab</translation> +<translation id="3236059992281584593">1 min left</translation> +<translation id="3244271242291266297">MM</translation> +<translation id="3254409185687681395">Bookmark this page</translation> +<translation id="3259831549858767975">Make everything on the page smaller</translation> +<translation id="3269093882174072735">Load image</translation> +<translation id="3269956123044984603">To get your tabs from your other devices, turn on “Auto-sync data” in Android account settings.</translation> +<translation id="3282568296779691940">Sign in to Chrome</translation> +<translation id="32895400574683172">Notifications are allowed</translation> +<translation id="3295602654194328831">Hide info</translation> +<translation id="3298243779924642547">Lite</translation> +<translation id="3303414029551471755">Proceed to download the content?</translation> +<translation id="3328801116991980348">Site information</translation> +<translation id="3341058695485821946">See how much data you've saved</translation> +<translation id="3350687908700087792">Close all incognito tabs</translation> +<translation id="3365671512111106261">Unavailable when Data Saver is turned on</translation> +<translation id="3367813778245106622">Sign in again to start sync</translation> +<translation id="3377025655491224618">Private tab</translation> +<translation id="3384347053049321195">Share image</translation> +<translation id="3386292677130313581">Ask before allowing sites to know your location (recommended)</translation> +<translation id="3387650086002190359"><ph name="FILE_NAME" /> download failed due to file system errors.</translation> +<translation id="339329030417445648">This site tends to show intrusive ads</translation> +<translation id="3398320232533725830">Open the bookmarks manager</translation> +<translation id="3414952576877147120">Size:</translation> +<translation id="3443221991560634068">Reload the current page</translation> +<translation id="3452612588551937789">Sign in with your Google Account to get your bookmarks, history, passwords and other settings on all your devices.</translation> +<translation id="3485359633434254965">{FILES,plural, =1{%1$d file downloaded}other{%1$d files downloaded}}</translation> +<translation id="3492207499832628349">New incognito tab</translation> +<translation id="3493531032208478708"><ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /> about suggested content</translation> +<translation id="3518985090088779359">Accept & continue</translation> +<translation id="3522247891732774234">Update available. More options</translation> +<translation id="3527085408025491307">Folder</translation> +<translation id="3542235761944717775"><ph name="KILOBYTES" /> KB available</translation> +<translation id="3549644494707163724">Encrypt all synced data with your own sync passphrase</translation> +<translation id="3549657413697417275">Search your history</translation> +<translation id="3552151358455404883">Manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="3557336313807607643">Add to contacts</translation> +<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="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="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="3600792891314830896">Mute sites that play sound</translation> +<translation id="360207483134687714">Help improve the VR experience in Chrome</translation> +<translation id="3616113530831147358">Audio</translation> +<translation id="3620176948598597475">Resetting erases Data Saver history, including the list of visited sites.</translation> +<translation id="3630011985153972676">Allow Chrome to download articles for you when on Wi-Fi under settings.</translation> +<translation id="3632295766818638029">Unmask password</translation> +<translation id="363596933471559332">Automatically sign in to websites using stored credentials. When the feature is off, you’ll be asked for verification every time before signing in to a website.</translation> +<translation id="3661699943263275414">Third-party websites can save and read cookie data</translation> +<translation id="3662546969139119822">No history here</translation> +<translation id="3672452749423051839">Navigation error suggestions</translation> +<translation id="3692944402865947621"><ph name="FILE_NAME" /> download failed because storage location is not reachable.</translation> +<translation id="3712575778697986964">Reset Data Saver?</translation> +<translation id="3714981814255182093">Open the Find Bar</translation> +<translation id="3716182511346448902">This page uses too much memory, so Chrome paused it.</translation> +<translation id="3739899004075612870">Bookmarked in <ph name="PRODUCT_NAME" /></translation> +<translation id="3744111309925758534"><ph name="MEGABYTES" /> MB other apps</translation> +<translation id="3744111561329211289">Background sync</translation> +<translation id="3773755127849930740"><ph name="BEGIN_LINK" />Turn on Bluetooth<ph name="END_LINK" /> to allow pairing</translation> +<translation id="3778956594442850293">Added to Home screen</translation> +<translation id="3781011235031427080">More like this opened at half height</translation> +<translation id="3789841737615482174">Install</translation> +<translation id="3810838688059735925">Video</translation> +<translation id="3810973564298564668">Manage</translation> +<translation id="3819178904835489326"><ph name="NUMBER_OF_DOWNLOADS" /> downloads deleted</translation> +<translation id="3819562311292413223">Download articles for you</translation> +<translation id="3822502789641063741">Clear site storage?</translation> +<translation id="385051799172605136">Back</translation> +<translation id="3859306556332390985">Seek forward</translation> +<translation id="3868004864571585162">Cookies, media licences and site data</translation> +<translation id="3894427358181296146">Add folder</translation> +<translation id="3895926599014793903">Force enable zoom</translation> +<translation id="3927692899758076493">Sans Serif</translation> +<translation id="3928666092801078803">Combine my data</translation> +<translation id="393697183122708255">No enabled voice search available</translation> +<translation id="3950820424414687140">Sign in</translation> +<translation id="395206256282351086">Search and site suggestions disabled</translation> +<translation id="3955193568934677022">Allow sites to play protected content (recommended)</translation> +<translation id="3967822245660637423">Download complete</translation> +<translation id="397583555483684758">Sync has stopped working</translation> +<translation id="3976396876660209797">Remove and recreate this shortcut</translation> +<translation id="3985215325736559418">Do you want to download <ph name="FILE_NAME" /> again?</translation> +<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="3991845972263764475"><ph name="BYTES_DOWNLOADED_WITH_UNITS" />/?</translation> +<translation id="3997476611815694295">Unimportant storage</translation> +<translation id="4002066346123236978">Title</translation> +<translation id="4034817413553209278">{HOURS,plural, =1{# hr}other{# hrs}}</translation> +<translation id="4042870126885713738">Show suggestions when a web address does not resolve or a connection cannot be made</translation> +<translation id="4046123991198612571">Next track</translation> +<translation id="4048707525896921369">Learn about topics on websites without leaving the page. Tap to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results and other details. + +To adjust your search term, long press to select. To refine your search, slide the panel all the way up and tap the search box.</translation> +<translation id="4056223980640387499">Sepia</translation> +<translation id="4060598801229743805">Options available near the top of the screen</translation> +<translation id="4062305924942672200">Legal information</translation> +<translation id="4084682180776658562">Bookmark</translation> +<translation id="4084712963632273211">From <ph name="PUBLISHER_ORIGIN" /> – <ph name="BEGIN_DEEMPHASIZED" />delivered by Google<ph name="END_DEEMPHASIZED" /></translation> +<translation id="4084836577264234537"><ph name="MEGABYTES" /> MB downloaded</translation> +<translation id="4089831646916293264">This feature may interfere with access to premium data services provided by your operator.</translation> +<translation id="4095146165863963773">Delete app data?</translation> +<translation id="4097739989936358050">This app is running in Chrome.</translation> +<translation id="4099578267706723511">Help make Chrome better by sending usage statistics and crash reports to Google.</translation> +<translation id="410351446219883937">Autoplay</translation> +<translation id="4113030288477039509">Managed by your administrator</translation> +<translation id="4116038641877404294">Download pages to use them offline</translation> +<translation id="4127069705158143605">{BOOKMARKS_COUNT,plural, =1{%1$d bookmark}other{%1$d bookmarks}}</translation> +<translation id="4149994727733219643">Simplified view for web pages</translation> +<translation id="4159800535322890630">Block sites from accessing your sensors</translation> +<translation id="4165986682804962316">Site settings</translation> +<translation id="4170011742729630528">The service is not available; try again later.</translation> +<translation id="4179980317383591987"><ph name="AMOUNT" /> used</translation> +<translation id="4181841719683918333">Languages</translation> +<translation id="4192273449750167573">Review your settings on the next screen</translation> +<translation id="4195643157523330669">Open in new tab</translation> +<translation id="4198423547019359126">No available download locations</translation> +<translation id="4209895695669353772">To get personalised content suggested by Google, turn on sync</translation> +<translation id="4226663524361240545">Notifications may vibrate the device</translation> +<translation id="4242533952199664413">Open settings</translation> +<translation id="4243710787042215766">Open in private tab</translation> +<translation id="424864128008805179">Sign out of Chrome?</translation> +<translation id="4256782883801055595">Open-source licences</translation> +<translation id="4259722352634471385">Navigation is blocked: <ph name="URL" /></translation> +<translation id="4262028915562328938">Sync error occurred, tap to get details.</translation> +<translation id="4269820728363426813">Copy link address</translation> +<translation id="4275663329226226506">Media</translation> +<translation id="4278390842282768270">Allowed</translation> +<translation id="4307992518367153382">Basics</translation> +<translation id="4351244548802238354">Close dialogue</translation> +<translation id="4378154925671717803">Phone</translation> +<translation id="4384468725000734951">Using Sogou for search</translation> +<translation id="4398088515904522762">To use this feature, turn on <ph name="BEGIN_LINK" />Activity and interactions<ph name="END_LINK" />.</translation> +<translation id="4404568932422911380">No bookmarks</translation> +<translation id="4409723563706114196">Use page predictions</translation> +<translation id="4412992751769744546">Allow third-party cookies</translation> +<translation id="4419556793104466535">Control sync, personalisation and more</translation> +<translation id="4432792777822557199">Pages in <ph name="SOURCE_LANGUAGE" /> will be translated to <ph name="TARGET_LANGUAGE" /> from now on</translation> +<translation id="4434045419905280838">Pop-ups and redirects</translation> +<translation id="4452411734226507615">Close <ph name="TAB_TITLE" /> tab</translation> +<translation id="4452548195519783679">Bookmarked to <ph name="FOLDER_NAME" /></translation> +<translation id="4453340223357552416"><ph name="FILE_NAME" /> downloaded in <ph name="PRODUCT_NAME" /></translation> +<translation id="4468959413250150279">Mute sound for a specific site.</translation> +<translation id="4472118726404937099">To sync and personalise across devices, sign in and turn on sync</translation> +<translation id="447252321002412580">Help improve Chrome's features and performance</translation> +<translation id="4479647676395637221">Ask first before allowing sites to use your camera (recommended)</translation> +<translation id="4487967297491345095">All Chrome’s app data will be deleted permanently. This includes all files, settings, accounts, databases, etc.</translation> +<translation id="4508440807153586353">Only someone with your passphrase can read your encrypted data. The passphrase is not sent to or stored by Google. If you forget your passphrase or want to change this setting you'll need to reset sync. <ph name="BEGIN_LINK" />Find out more<ph name="END_LINK" /></translation> +<translation id="4513387527876475750">{DAYS,plural, =1{# day ago}other{# days ago}}</translation> +<translation id="451872707440238414">Search your bookmarks</translation> +<translation id="4521489764227272523">The selected data has been removed from Chrome and your synced devices. + +Your Google Account may have other forms of browsing history such as searches and activity from other Google services at <ph name="BEGIN_LINK" />myactivity.google.com<ph name="END_LINK" />.</translation> +<translation id="4532845899244822526">Choose folder</translation> +<translation id="4550003330909367850">To view or copy your password here, set screen lock on this device.</translation> +<translation id="4558311620361989323">Web page shortcuts</translation> +<translation id="4561979708150884304">No connection</translation> +<translation id="4565377596337484307">Hide password</translation> +<translation id="4570913071927164677">Details</translation> +<translation id="4572422548854449519">Sign in to managed account</translation> +<translation id="4581964774250883625">You’ve gone incognito.</translation> +<translation id="4583164079174244168">{MINUTES,plural, =1{# minute ago}other{# minutes ago}}</translation> +<translation id="4587589328781138893">Sites</translation> +<translation id="4594952190837476234">This offline page is from <ph name="CREATION_TIME" /> and may differ from the online version.</translation> +<translation id="4605958867780575332">Item removed: <ph name="ITEM_TITLE" /></translation> +<translation id="4616150815774728855">Open <ph name="WEBAPK_NAME" /></translation> +<translation id="4634124774493850572">Use password</translation> +<translation id="4645575059429386691">Managed by your parent</translation> +<translation id="4660011489602794167">Show keyboard</translation> +<translation id="4663756553811254707"><ph name="NUMBER_OF_BOOKMARKS" /> bookmarks deleted</translation> +<translation id="4665282149850138822"><ph name="NAME" /> was added to your Home screen</translation> +<translation id="4684427112815847243">Sync everything</translation> +<translation id="4695891336199304370">{SHIPPING_OPTIONS,plural, =1{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}other{<ph name="SHIPPING_OPTION_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> more}}</translation> +<translation id="4698034686595694889">View offline in <ph name="APP_NAME" /></translation> +<translation id="4698413471314543145">Critical functionality required to run Chrome is missing; either your Chrome installation is incomplete or not compatible with this version of Android.</translation> +<translation id="4699172675775169585">Cached images and files</translation> +<translation id="4714588616299687897">Save up to 60% of your data</translation> +<translation id="4719927025381752090">Offer to translate</translation> +<translation id="4720023427747327413">Open in <ph name="PRODUCT_NAME" /></translation> +<translation id="4720982865791209136">Help improve Chrome. <ph name="BEGIN_LINK" />Take survey<ph name="END_LINK" /></translation> +<translation id="4730876730346568982">You are switching sync accounts from <ph name="ACCOUNT_EMAIL_OLD" /> to <ph name="ACCOUNT_EMAIL_NEW" />. Your existing Chrome data is managed by <ph name="MANAGED_DOMAIN" />. This will delete your data from this device, but your data will remain in <ph name="ACCOUNT_EMAIL_OLD" />.</translation> +<translation id="473775607612524610">Update</translation> +<translation id="4738836084190194332">Last synced: <ph name="WHEN" /></translation> +<translation id="4749960740855309258">Open a new tab</translation> +<translation id="4751476147751820511">Motion or light sensors</translation> +<translation id="4759238208242260848">Downloads</translation> +<translation id="4763829664323285145">{FILE_COUNT,plural, =1{1 download complete.}other{# downloads complete.}}</translation> +<translation id="4766369052440583386">Data Saver is on</translation> +<translation id="4797039098279997504">Touch to return to <ph name="URL_OF_THE_CURRENT_TAB" /></translation> +<translation id="4807098396393229769">Name on card</translation> +<translation id="4807963036345170158">Data Saver is off</translation> +<translation id="4816465935029283692">Data types</translation> +<translation id="4837753911714442426">Open options to print page</translation> +<translation id="4842092870884894799">Showing password generation pop-up</translation> +<translation id="4850886885716139402">View</translation> +<translation id="4860895144060829044">Call</translation> +<translation id="4874967477260347223">Media Licenses</translation> +<translation id="4875775213178255010">Content Suggestions</translation> +<translation id="4878404682131129617">Establishing a tunnel via proxy server failed</translation> +<translation id="4881695831933465202">Open</translation> +<translation id="488187801263602086">Rename file</translation> +<translation id="4882831918239250449">Control how your browsing history is used to personalise Search, ads and more</translation> +<translation id="4883379392681899581">Leave private mode</translation> +<translation id="4885273946141277891">Unsupported number of Chrome instances.</translation> +<translation id="4910889077668685004">Payment apps</translation> +<translation id="4913161338056004800">Reset statistics</translation> +<translation id="4913169188695071480">Stop refreshing</translation> +<translation id="4915549754973153784"><ph name="BEGIN_LINK" />Get help<ph name="END_LINK" /> while scanning for devices…</translation> +<translation id="4943872375798546930">No results</translation> +<translation id="4956460920135325549">Lite page delivered by Google.</translation> +<translation id="4958708863221495346"><ph name="URL_OF_THE_CURRENT_TAB" /> is sharing your screen</translation> +<translation id="4961334780091921942">Your passwords, history & more on all devices</translation> +<translation id="4961700429721424617">You are signing out of an account managed by <ph name="MANAGED_DOMAIN" />. This will delete your Chrome data from this device, but your data will remain in your Google account.</translation> +<translation id="497421865427891073">go forward</translation> +<translation id="4988210275050210843">Downloading file (<ph name="MEGABYTES" />).</translation> +<translation id="4988526792673242964">Pages</translation> +<translation id="4996978546172906250">Share via</translation> +<translation id="5004339818306944878">Use up to 60% less data and speed up the web. Google servers will optimise the pages you visit.</translation> +<translation id="5004416275253351869">Google activity controls</translation> +<translation id="5005498671520578047">Copy password</translation> +<translation id="5011311129201317034"><ph name="SITE" /> wants to connect</translation> +<translation id="5013696553129441713">No new suggestions</translation> +<translation id="5016205925109358554">Serif</translation> +<translation id="5039804452771397117">Allow</translation> +<translation id="5040262127954254034">Privacy</translation> +<translation id="5063480226653192405">Usage</translation> +<translation id="5087580092889165836">Add card</translation> +<translation id="5100237604440890931">Collapsed – click to expand.</translation> +<translation id="510275257476243843">1 hour left</translation> +<translation id="5123685120097942451">Incognito tab</translation> +<translation id="5127805178023152808">Sync is off</translation> +<translation id="5129038482087801250">Install web app</translation> +<translation id="5139940364318403933">Learn how to use Google Drive</translation> +<translation id="515227803646670480">Clear stored data</translation> +<translation id="5152843274749979095">No supported apps installed</translation> +<translation id="5161254044473106830">Title required</translation> +<translation id="5162754098604580781">{FILE_COUNT,plural, =1{1 download failed.}other{# downloads failed.}}</translation> +<translation id="5168917394043976756">Open navigation drawer</translation> +<translation id="5171365962177408781">Tap to load the new tab page and view suggested articles</translation> +<translation id="5184329579814168207">Open in Chrome</translation> +<translation id="5199929503336119739">Work profile</translation> +<translation id="5210286577605176222">Jump to the previous tab</translation> +<translation id="5210365745912300556">Close tab</translation> +<translation id="5222676887888702881">Sign out</translation> +<translation id="5224771365102442243">With video</translation> +<translation id="5233638681132016545">New tab</translation> +<translation id="5240817131241497236">The settings that control sync, personalisation and other Google services in Chrome have changed. This may affect your current settings.</translation> +<translation id="5264003212305142034"><ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /> can be customised at any time. Google may use content on sites that you visit, plus browser activity and interactions, to personalise Chrome and other Google services such as Translate, Search and ads.</translation> +<translation id="5271967389191913893">Device cannot open the content to be downloaded.</translation> +<translation id="528192093759286357">Drag from top and touch the back button to exit full screen.</translation> +<translation id="5284584623296338184">Changes to your bookmarks, history, passwords and other settings will no longer be synced to your Google Account. However, your existing data will remain stored in your Google account.</translation> +<translation id="5300589172476337783">Show</translation> +<translation id="5301954838959518834">OK, got it</translation> +<translation id="5304593522240415983">This field cannot be blank</translation> +<translation id="5308380583665731573">Connect</translation> +<translation id="5308603654685598744">When this feature is turned on, Chrome will offer to translate pages written in other languages using Google Translate.</translation> +<translation id="5313967007315987356">Add site</translation> +<translation id="5317780077021120954">Save</translation> +<translation id="5324858694974489420">Parental Settings</translation> +<translation id="5327248766486351172">Name</translation> +<translation id="5335288049665977812">Allow sites to run JavaScript (recommended)</translation> +<translation id="5345040418939504969">Deleted <ph name="BOOKMARK_TITLE" /></translation> +<translation id="5372829067651257087">URL copied.</translation> +<translation id="5391532827096253100">Your connection to this site is not secure. Site information</translation> +<translation id="5400569084694353794">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />.</translation> +<translation id="5403644198645076998">Only allow certain sites</translation> +<translation id="5414836363063783498">Verifying…</translation> +<translation id="5423934151118863508">Your most visited pages will appear here</translation> +<translation id="5424588387303617268"><ph name="GIGABYTES" /> GB available</translation> +<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="5447765697759493033">This site will not be translated</translation> +<translation id="545042621069398927">Speeding up your download.</translation> +<translation id="5456381639095306749">Download page</translation> +<translation id="5466407412363861127">This feature uses <ph name="BEGIN_LINK" />sync<ph name="END_LINK" />.</translation> +<translation id="548278423535722844">Open in maps app</translation> +<translation id="5487521232677179737">Clear data</translation> +<translation id="5487729733663684359">Chrome updates are no longer supported for this version of Android.</translation> +<translation id="5494920125229734069">Select all</translation> +<translation id="550684401320795253">Updating Chrome...</translation> +<translation id="5512137114520586844">This account is managed by <ph name="PARENT_NAME" />.</translation> +<translation id="5514904542973294328">Disabled by the administrator of this device</translation> +<translation id="5515439363601853141">Unlock to view your password</translation> +<translation id="5515716148775388141">Your icons have moved to the bottom of the screen</translation> +<translation id="5517095782334947753">You have bookmarks, history, passwords and other settings from <ph name="FROM_ACCOUNT" />.</translation> +<translation id="5524843473235508879">Redirect blocked.</translation> +<translation id="5527082711130173040">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK1" />Update permissions<ph name="END_LINK1" />. Location access is also <ph name="BEGIN_LINK2" />turned off for this device<ph name="END_LINK2" />.</translation> +<translation id="5527111080432883924">Ask before allowing sites to read text and images from the clipboard (recommended)</translation> +<translation id="5530766185686772672">Close incognito tabs</translation> +<translation id="5534640966246046842">Site copied</translation> +<translation id="5537099431952529648">You and your parents can manage Chrome Sync and personalisation in <ph name="BEGIN_LINK1" />Settings<ph name="END_LINK1" /></translation> +<translation id="5556459405103347317">Reload</translation> +<translation id="5561549206367097665">Waiting for network…</translation> +<translation id="557283862590186398">Chrome needs permission to access your microphone for this site.</translation> +<translation id="55737423895878184">Location and notifications are allowed</translation> +<translation id="5578795271662203820">Search <ph name="SEARCH_ENGINE" /> for this image</translation> +<translation id="5595485650161345191">Edit address</translation> +<translation id="5596627076506792578">More options</translation> +<translation id="5620299005957670886">Allow sites to access your sensors (recommended)</translation> +<translation id="5620928963363755975">Find your files and pages in Downloads from the More Options button</translation> +<translation id="5626134646977739690">Name:</translation> +<translation id="5639724618331995626">Allow all sites</translation> +<translation id="5648166631817621825">Last 7 days</translation> +<translation id="5655963694829536461">Search your downloads</translation> +<translation id="5659593005791499971">Email</translation> +<translation id="5665379678064389456">Create event in <ph name="APP_NAME" /></translation> +<translation id="5668404140385795438">Override a website’s request to prevent zooming in</translation> +<translation id="5676636989614905379">Cannot play video on <ph name="SCREEN_NAME" />.</translation> +<translation id="5677928146339483299">Blocked</translation> +<translation id="5684874026226664614">Oops. This page could not be translated.</translation> +<translation id="5686790454216892815">File name too long</translation> +<translation id="5689516760719285838">Location</translation> +<translation id="5719837394786370183">Pages that you view in incognito tabs won’t stick around in your browser’s history, cookie store or search history after you’ve closed all of your incognito tabs. Any files that you download or bookmarks that you create will be kept. + +However, you aren’t invisible. Going incognito doesn’t hide your browsing from your employer, your Internet service provider or the websites you visit.</translation> +<translation id="572328651809341494">Recent tabs</translation> +<translation id="5726692708398506830">Make everything on the page bigger</translation> +<translation id="5738816946784116349">Chrome Downloads</translation> +<translation id="5748802427693696783">Switched to standard tabs</translation> +<translation id="5749068826913805084">Chrome needs storage access to download files.</translation> +<translation id="5763382633136178763">Incognito tabs</translation> +<translation id="5763514718066511291">Tap to copy the URL for this app</translation> +<translation id="5765780083710877561">Description:</translation> +<translation id="5777170031995031090">Control how Google uses your browsing history to personalise Search, ads and other Google services.</translation> +<translation id="5793665092639000975">Using <ph name="SPACE_USED" /> of <ph name="SPACE_AVAILABLE" /></translation> +<translation id="5804241973901381774">Permissions</translation> +<translation id="5809361687334836369">{HOURS,plural, =1{# hour ago}other{# hours ago}}</translation> +<translation id="5817918615728894473">Pair</translation> +<translation id="583281660410589416">Unknown</translation> +<translation id="5833397272224757657">Uses content on sites that you visit, plus browser activity and interactions, for personalisation</translation> +<translation id="5833984609253377421">Share link</translation> +<translation id="584427517463557805">Selected private tab</translation> +<translation id="5854790677617711513">Older than 30 days</translation> +<translation id="5858741533101922242">Chrome is unable to turn on Bluetooth adaptor</translation> +<translation id="5860033963881614850">Off</translation> +<translation id="5862731021271217234">To get your tabs from your other devices, turn on sync</translation> +<translation id="5864174910718532887">Details: Sorted by site name</translation> +<translation id="5864419784173784555">Waiting for another download…</translation> +<translation id="5865733239029070421">Automatically sends usage statistics and crash reports to Google</translation> +<translation id="5869522115854928033">Saved passwords</translation> +<translation id="5878455346526065919">Block ads from sites that tend to show intrusive ads</translation> +<translation id="5902828464777634901">All local data stored by this website, including cookies, will be deleted.</translation> +<translation id="5911030830365207728">Google Translate</translation> +<translation id="5916664084637901428">On</translation> +<translation id="5919204609460789179">Update <ph name="PRODUCT_NAME" /> to start sync</translation> +<translation id="5937580074298050696"><ph name="AMOUNT" /> saved</translation> +<translation id="5939518447894949180">Reset</translation> +<translation id="5942872142862698679">Using Google for search</translation> +<translation id="5952764234151283551">Sends the URL of a page that you're trying to reach to Google</translation> +<translation id="5956665950594638604">Open the Chrome Help Centre in a new tab</translation> +<translation id="5958275228015807058">Find your files and pages in Downloads</translation> +<translation id="5962718611393537961">Tap to collapse</translation> +<translation id="5990142338020175451">More personal Google services, such as better page suggestions</translation> +<translation id="6000066717592683814">Keep Google</translation> +<translation id="6005538289190791541">Suggested password</translation> +<translation id="6039379616847168523">Jump to the next tab</translation> +<translation id="6040143037577758943">Close</translation> +<translation id="6042308850641462728">More</translation> +<translation id="604996488070107836"><ph name="FILE_NAME" /> download failed due to an unknown error.</translation> +<translation id="605721222689873409">YY</translation> +<translation id="6075798973483050474">Edit home page</translation> +<translation id="60923314841986378"><ph name="HOURS" /> hours left</translation> +<translation id="60924377787140961">More articles will appear soon. Enjoy your afternoon!</translation> +<translation id="6099151465289169210">Switched to private tabs</translation> +<translation id="6108923351542677676">Setup in progress…</translation> +<translation id="6111020039983847643">data used</translation> +<translation id="6112702117600201073">Refreshing page</translation> +<translation id="6127379762771434464">Item removed</translation> +<translation id="6140912465461743537">Country/Region</translation> +<translation id="6154478581116148741">Turn on screen lock in Settings to export your passwords from this device</translation> +<translation id="6159335304067198720"><ph name="PERCENT" /> data savings</translation> +<translation id="6165508094623778733">Learn more</translation> +<translation id="6177111841848151710">Blocked for current search engine</translation> +<translation id="6177390657002841081">Turn on Data Saver</translation> +<translation id="6181444274883918285">Add site exception</translation> +<translation id="618993374665929060">More like this opened at full height</translation> +<translation id="6192333916571137726">Download File</translation> +<translation id="6192792657125177640">Exceptions</translation> +<translation id="6206551242102657620">Connection is secure. Site information</translation> +<translation id="6210748933810148297">Not <ph name="EMAIL" />?</translation> +<translation id="6216432067784365534"><ph name="NAME_OF_LIST_ITEM" /> Options</translation> +<translation id="6221633008163990886">Unlock to export your passwords</translation> +<translation id="6232535412751077445">Enabling “Do Not Track” means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request and how the request is interpreted. + +For example, some websites may respond to this request by showing you ads that aren’t based on other websites that you’ve visited. Many websites will still collect and use your browsing data – for example to improve security, to provide content, ads and recommendations and to generate reporting statistics.</translation> +<translation id="6255999984061454636">Content suggestions</translation> +<translation id="6277522088822131679">There was a problem printing the page. Please try again.</translation> +<translation id="6295158916970320988">All sites</translation> +<translation id="629730747756840877">Account</translation> +<translation id="6303969859164067831">Sign out and turn off sync</translation> +<translation id="6320088164292336938">Vibrate</translation> +<translation id="6324034347079777476">Android system sync disabled</translation> +<translation id="6333140779060797560">Share via <ph name="APPLICATION" /></translation> +<translation id="6336451774241870485">New private tab</translation> +<translation id="6337234675334993532">Encryption</translation> +<translation id="6341580099087024258">Ask where to save files</translation> +<translation id="6343192674172527289">No downloads found</translation> +<translation id="6343495912647200061">{SHIPPING_ADDRESS,plural, =1{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}other{<ph name="SHIPPING_ADDRESS_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_ADDRESSES" /> more}}</translation> +<translation id="6364438453358674297">Remove suggestion from history?</translation> +<translation id="6378173571450987352">Details: Sorted by amount of data used</translation> +<translation id="6383961787135158834">Clear Site Storage…</translation> +<translation id="6388207532828177975">Clear & reset</translation> +<translation id="6393863479814692971">Chrome needs permission to access your camera and microphone for this site.</translation> +<translation id="6395288395575013217">LINK</translation> +<translation id="6404511346730675251">Edit bookmark</translation> +<translation id="6406506848690869874">Sync</translation> +<translation id="641643625718530986">Print…</translation> +<translation id="6416782512398055893">Downloaded <ph name="MBS" /> MB</translation> +<translation id="6433501201775827830">Choose your search engine</translation> +<translation id="6437478888915024427">Page info</translation> +<translation id="6447842834002726250">Cookies</translation> +<translation id="6448273550210938826">Search and URL suggestions</translation> +<translation id="6461962085415701688">Can’t open file</translation> +<translation id="6475951671322991020">Download video</translation> +<translation id="6482749332252372425"><ph name="FILE_NAME" /> download failed due to lack of storage space.</translation> +<translation id="6496823230996795692">To use <ph name="APP_NAME" /> for the first time, please connect to the Internet.</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6534565668554028783">Google took too long to respond</translation> +<translation id="6538442820324228105">Downloaded <ph name="GBS" /> GB</translation> +<translation id="654446541061731451">Select a tab to beam</translation> +<translation id="6545017243486555795">Clear All Data</translation> +<translation id="6556716549745717622">Block if site tends to show intrusive ads (recommended)</translation> +<translation id="6560414384669816528">Search with Sogou</translation> +<translation id="6566259936974865419">Chrome has saved you <ph name="GIGABYTES" /> GB</translation> +<translation id="6573096386450695060">Always allow</translation> +<translation id="6573431926118603307">Tabs that you've opened in Chrome on your other devices will appear here.</translation> +<translation id="6575643671698722332">Reset failed. Ensure that your device is online and try again.</translation> +<translation id="6583199322650523874">Bookmark the current page</translation> +<translation id="6584721918629302382">AR</translation> +<translation id="6593061639179217415">Desktop site</translation> +<translation id="6600954340915313787">Copied to Chrome</translation> +<translation id="6608650720463149374"><ph name="GIGABYTES" /> GB</translation> +<translation id="6610147964972079463">Close private tabs</translation> +<translation id="6612358246767739896">Protected content</translation> +<translation id="6627583120233659107">Edit folder</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6643649862576733715">Sort by amount of data saved</translation> +<translation id="6648977384226967773">{CONTACT,plural, =1{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}other{<ph name="CONTACT_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_CONTACTS" /> more}}</translation> +<translation id="6656545060687952787">Chrome needs location access to scan for devices. <ph name="BEGIN_LINK" />Update permissions<ph name="END_LINK" /></translation> +<translation id="6657585470893396449">Password</translation> +<translation id="6659594942844771486">Tab</translation> +<translation id="666268767214822976">Use a prediction service to show related queries and popular websites as you type in the address bar</translation> +<translation id="666731172850799929">Open in <ph name="APP_NAME" /></translation> +<translation id="666981079809192359">Chrome Privacy Notice</translation> +<translation id="6697492270171225480">Show suggestions for similar pages when a page can't be found</translation> +<translation id="6697947395630195233">Chrome needs access to your location to share your location with this site.</translation> +<translation id="6698801883190606802">Manage synced data</translation> +<translation id="6710213216561001401">Previous</translation> +<translation id="6712388303105732168">See more like this from Google using the More Like This button</translation> +<translation id="6738867403308150051">Downloading…</translation> +<translation id="6746124502594467657">Move down</translation> +<translation id="6762156594045689028">To change this setting, <ph name="BEGIN_LINK" />reset sync<ph name="END_LINK" /></translation> +<translation id="6766622839693428701">Swipe down to close.</translation> +<translation id="6770414673596662518">Chrome’s Safe Browsing system will also be used to detect malicious pages and protect you from phishing, malware and harmful downloads.</translation> +<translation id="6776813977906306442">Download videos to watch later using the Download button</translation> +<translation id="6790428901817661496">Play</translation> +<translation id="679325081238418596">Get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="6820607729870073286">You have no saved website settings.</translation> +<translation id="6820686453637990663">CVC</translation> +<translation id="6831043979455480757">Translate</translation> +<translation id="6846298663435243399">Loading…</translation> +<translation id="685040365210406336">Make no changes</translation> +<translation id="6850409657436465440">Your download is still in progress</translation> +<translation id="6850830437481525139"><ph name="TAB_COUNT" /> tabs closed</translation> +<translation id="6864459304226931083">Download image</translation> +<translation id="6865313869410766144">Autofill form data</translation> +<translation id="6868088497967843822">Sign in to get your bookmarks, history, passwords and other settings on all your devices</translation> +<translation id="688738109438487280">Add existing data to <ph name="TO_ACCOUNT" />.</translation> +<translation id="6891726759199484455">Unlock to copy your password</translation> +<translation id="6891858906296486776">{OPEN_TABS,plural, =1{%1$d open tab}other{%1$d open tabs}}</translation> +<translation id="6896758677409633944">Copy</translation> +<translation id="6910211073230771657">Deleted</translation> +<translation id="6912998170423641340">Block sites from reading text and images from the clipboard</translation> +<translation id="6914783257214138813">Your passwords will be visible to anyone who can see the exported file.</translation> +<translation id="6942665639005891494">Change the default download location at any time using the Settings menu option</translation> +<translation id="6945221475159498467">Select</translation> +<translation id="6963642900430330478">This page is dangerous. Site information</translation> +<translation id="6963766334940102469">Delete bookmarks</translation> +<translation id="6965382102122355670">OK</translation> +<translation id="6978479750597523876">Reset translate settings</translation> +<translation id="6979737339423435258">All time</translation> +<translation id="6981982820502123353">Accessibility</translation> +<translation id="6985347914332179298">No downloads here</translation> +<translation id="6990079615885386641">Get the app from the Google Play Store: <ph name="APP_ACTION" /></translation> +<translation id="699220179437400583">Automatically report details of possible security incidents to Google</translation> +<translation id="6992289844737586249">Ask first before allowing sites to use your microphone (recommended)</translation> +<translation id="7016516562562142042">Allowed for current search engine</translation> +<translation id="7021515813996758557"><ph name="FILE_NAME" /> downloaded</translation> +<translation id="7022756207310403729">Open in browser</translation> +<translation id="702463548815491781">Recommended when TalkBack or Switch Access are on</translation> +<translation id="7029809446516969842">Passwords</translation> +<translation id="7031882061095297553">Sync to</translation> +<translation id="7032663816368481562">When you tap More like this <ph name="ICON" /> in the address bar, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="7034608350006174882">Cards and addresses using Google Pay</translation> +<translation id="7053983685419859001">Block</translation> +<translation id="7055152154916055070">Redirect blocked:</translation> +<translation id="7062545763355031412">Accept and switch accounts</translation> +<translation id="7063006564040364415">Could not connect to the sync server.</translation> +<translation id="7066151586745993502">{NUM_SELECTED,plural, =1{1 selected}other{# selected}}</translation> +<translation id="7077143737582773186">SD Card</translation> +<translation id="7087918508125750058"><ph name="ITEM_COUNT" /> selected. Options available near top of the screen</translation> +<translation id="7108338896283013870">Hide</translation> +<translation id="7121362699166175603">Clears history and autocompletions in the address bar. 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="7128222689758636196">Allow for current search engine</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7139148793369023665">More like this closed</translation> +<translation id="7141896414559753902">Block sites from showing pop-ups and redirects (recommended)</translation> +<translation id="7149158118503947153"><ph name="BEGIN_LINK" />Load original page<ph name="END_LINK" /> from <ph name="DOMAIN_NAME" /></translation> +<translation id="7149893636342594995">Last 24 Hours</translation> +<translation id="7176368934862295254"><ph name="KILOBYTES" /> KB</translation> +<translation id="7177466738963138057">You can change this later in Settings</translation> +<translation id="7180611975245234373">Refresh</translation> +<translation id="7189372733857464326">Waiting for Google Play Services to finish updating</translation> +<translation id="7189598951263744875">Share...</translation> +<translation id="7191430249889272776">Tab opened in background.</translation> +<translation id="723171743924126238">Select images</translation> +<translation id="7243308994586599757">Options available near bottom of the screen</translation> +<translation id="7250468141469952378"><ph name="ITEM_COUNT" /> selected</translation> +<translation id="7251326866581677552">Blocked from some sites</translation> +<translation id="7253272406652746122">Add a Google account from the Accounts page in your device’s Settings app.</translation> +<translation id="7274013316676448362">Blocked site</translation> +<translation id="729975465115245577">Your device doesn’t have an app to store the passwords file.</translation> +<translation id="7302081693174882195">Details: Sorted by amount of data saved</translation> +<translation id="7333031090786104871">Still adding previous site</translation> +<translation id="7352939065658542140">VIDEO</translation> +<translation id="7353894246028566792">{NUM_SELECTED,plural, =1{Share 1 selected item}other{Share # selected items}}</translation> +<translation id="7359002509206457351">Access payment methods</translation> +<translation id="7366340029385295517">Casting to <ph name="SCREEN_NAME" /></translation> +<translation id="7375125077091615385">Type:</translation> +<translation id="7396940094317457632"><ph name="FILE_NAME" />.</translation> +<translation id="7400418766976504921">URL</translation> +<translation id="7403691278183511381">Chrome First Run Experience</translation> +<translation id="741204030948306876">Yes, I'm in</translation> +<translation id="7413229368719586778">Start date <ph name="DATE" /></translation> +<translation id="7423098979219808738">Ask first</translation> +<translation id="7423538860840206698">Blocked from reading clipboard</translation> +<translation id="7431991332293347422">Control how your browsing history is used to personalise Search and more</translation> +<translation id="7437998757836447326">Sign out of Chrome</translation> +<translation id="7444811645081526538">More categories</translation> +<translation id="7445411102860286510">Allow sites to automatically play muted videos (recommended)</translation> +<translation id="7454641608352164238">Not enough space</translation> +<translation id="7455923816558154057">Tap to view</translation> +<translation id="7465104139234185284">Close all private tabs</translation> +<translation id="7473891865547856676">No Thanks</translation> +<translation id="7475192538862203634">If you’re seeing this frequently, try these <ph name="BEGIN_LINK" />suggestions<ph name="END_LINK" />.</translation> +<translation id="7475688122056506577">SD card not found. Some of your files may be missing.</translation> +<translation id="748127970106343339">Confirm device credential deletion</translation> +<translation id="7481312909269577407">Forward</translation> +<translation id="7493994139787901920"><ph name="VERSION" /> (Updated <ph name="TIME_SINCE_UPDATE" />)</translation> +<translation id="7494879913343971937">Show passwords</translation> +<translation id="7494974237137038751">data saved</translation> +<translation id="7498271377022651285">Please wait…</translation> +<translation id="7514365320538308">Download</translation> +<translation id="751961395872307827">Can't connect to the site</translation> +<translation id="7521387064766892559">JavaScript</translation> +<translation id="7542481630195938534">Can’t get suggestions</translation> +<translation id="7562080006725997899">Clear browsing data</translation> +<translation id="756809126120519699">Cleared Chrome data</translation> +<translation id="757524316907819857">Block sites from playing protected content</translation> +<translation id="7589445247086920869">Block for current search engine</translation> +<translation id="7593557518625677601">Open Android settings and re-enable Android system sync to start Chrome sync</translation> +<translation id="7596558890252710462">Operating system</translation> +<translation id="7605594153474022051">Sync isn't working</translation> +<translation id="7612619742409846846">Signed in to Google as</translation> +<translation id="7619072057915878432"><ph name="FILE_NAME" /> download failed due to network failures.</translation> +<translation id="7624880197989616768"><ph name="BEGIN_LINK1" />Get help<ph name="END_LINK1" /> or <ph name="BEGIN_LINK2" />re-scan<ph name="END_LINK2" /></translation> +<translation id="7626032353295482388">Welcome to Chrome</translation> +<translation id="7638584964844754484">Incorrect passphrase</translation> +<translation id="7641339528570811325">Clear browsing data…</translation> +<translation id="7648422057306047504">Encrypt passwords with Google credentials</translation> +<translation id="7649070708921625228">Help</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7665369617277396874">Add account</translation> +<translation id="7682724950699840886">Try the following tips: make sure that there is enough space on your device; try to export again.</translation> +<translation id="7698359219371678927">Create email in <ph name="APP_NAME" /></translation> +<translation id="7704317875155739195">Auto-complete searches and URLs</translation> +<translation id="773466115871691567">Always translate pages in <ph name="SOURCE_LANGUAGE" /></translation> +<translation id="7735672056998735387"><ph name="SPACE_FREE" /> (<ph name="SPACE_OTHER" />)</translation> +<translation id="773905249182896430">Protects you and your device from dangerous sites</translation> +<translation id="7762668264895820836">SD Card <ph name="SD_CARD_NUMBER" /></translation> +<translation id="7764225426217299476">Add address</translation> +<translation id="7765158879357617694">Move</translation> +<translation id="7769602470925380267">Accept and sign out</translation> +<translation id="7772032839648071052">Confirm passphrase</translation> +<translation id="7774809984919390718">{PAYMENT_METHOD,plural, =1{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}other{<ph name="PAYMENT_METHOD_PREVIEW" />\u2026 and <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> more}}</translation> +<translation id="7781829728241885113">Yesterday</translation> +<translation id="7791543448312431591">Add</translation> +<translation id="780301667611848630">No, thank you</translation> +<translation id="7810647596859435254">Open with…</translation> +<translation id="7821588508402923572">Your data savings will appear here</translation> +<translation id="7832327313660264358">The data that you sync to Google and the features that you use will not change</translation> +<translation id="7837721118676387834">Allow auto-play of muted videos for a specific site.</translation> +<translation id="7846076177841592234">Cancel selection</translation> +<translation id="784934925303690534">Time range</translation> +<translation id="7851858861565204677">Other Devices</translation> +<translation id="7854964836418414587">Close more like this</translation> +<translation id="7875915731392087153">Create email</translation> +<translation id="7876243839304621966">Remove all</translation> +<translation id="7882131421121961860">No history found</translation> +<translation id="7882806643839505685">Allow sound for a specific site.</translation> +<translation id="7925590027513907933">{FILE_COUNT,plural, =1{Downloading file.}other{Downloading # files.}}</translation> +<translation id="7929962904089429003">Opening the menu</translation> +<translation id="7942131818088350342"><ph name="PRODUCT_NAME" /> is out of date.</translation> +<translation id="7947953824732555851">Accept and sign in</translation> +<translation id="7963646190083259054">Vendor:</translation> +<translation id="7981313251711023384">Preload pages for faster browsing and searching</translation> +<translation id="79859296434321399">To view augmented reality content, install ARCore</translation> +<translation id="7986741934819883144">Select a contact</translation> +<translation id="7987073022710626672">Chrome Terms of Service</translation> +<translation id="7987764905897278458">Get more Google smarts</translation> +<translation id="7998918019931843664">Re-open closed tab</translation> +<translation id="7999064672810608036">Are you sure that you want to clear all local data, including cookies, and reset all permissions for this website?</translation> +<translation id="8004582292198964060">Browser</translation> +<translation id="8007176423574883786">Turned off for this device</translation> +<translation id="8015452622527143194">Return everything on the page to default size</translation> +<translation id="802154636333426148">Download failed</translation> +<translation id="8026334261755873520">Clear browsing data</translation> +<translation id="8035133914807600019">New folder…</translation> +<translation id="8037411810184515274">VR</translation> +<translation id="8037686209485537503">More like this</translation> +<translation id="8037750541064988519"><ph name="DAYS" /> days left</translation> +<translation id="804335162455518893">SD card not found</translation> +<translation id="805047784848435650">Based on your browsing history</translation> +<translation id="8051695050440594747"><ph name="MEGABYTES" /> MB available</translation> +<translation id="8058746566562539958">Open in new Chrome tab</translation> +<translation id="8063895661287329888">Failed to add bookmark.</translation> +<translation id="806745655614357130">Keep my data separate</translation> +<translation id="8068648041423924542">Unable to select certificate.</translation> +<translation id="8073388330009372546">Open image in new tab</translation> +<translation id="8084114998886531721">Saved password</translation> +<translation id="8087000398470557479">This content is from <ph name="DOMAIN_NAME" />, delivered by Google.</translation> +<translation id="8103578431304235997">Incognito Tab</translation> +<translation id="8105951947646329362">Suggest related pages</translation> +<translation id="8109613176066109935">To get your bookmarks on all your devices, turn on sync</translation> +<translation id="8116925261070264013">Muted</translation> +<translation id="813082847718468539">View site information</translation> +<translation id="8156139159503939589">What languages do you read?</translation> +<translation id="8168435359814927499">Content</translation> +<translation id="8186512483418048923"><ph name="FILES" /> files left</translation> +<translation id="8190358571722158785">1 day left</translation> +<translation id="8200772114523450471">Resume</translation> +<translation id="8209050860603202033">Open image</translation> +<translation id="8220488350232498290"><ph name="GIGABYTES" /> GB downloaded</translation> +<translation id="8249310407154411074">Move to top</translation> +<translation id="8250920743982581267">Documents</translation> +<translation id="825412236959742607">This page uses too much memory, so Chrome removed some content.</translation> +<translation id="8260126382462817229">Try signing in again</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8266862848225348053">Download location</translation> +<translation id="8274165955039650276">See downloads</translation> +<translation id="8283853025636624853">Syncing to <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8310344678080805313">Standard tabs</translation> +<translation id="8313455859591948645">Edit startup page</translation> +<translation id="8316092324682955408"><ph name="DOMAIN_NAME" /> and more sites</translation> +<translation id="8339163506404995330">Pages in <ph name="LANGUAGE" /> will not be translated</translation> +<translation id="8349013245300336738">Sort by amount of data used</translation> +<translation id="8372893542064058268">Allow Background Sync for a specific site.</translation> +<translation id="8374821112118309944">You need to update TalkBack to a newer version.</translation> +<translation id="8393700583063109961">Send message</translation> +<translation id="8413126021676339697">Show full history</translation> +<translation id="8428213095426709021">Settings</translation> +<translation id="8438566539970814960">Make searches and browsing better</translation> +<translation id="8441146129660941386">Seek backward</translation> +<translation id="8445448999790540984">Can’t export passwords</translation> +<translation id="8447861592752582886">Revoke device permission</translation> +<translation id="8477071352266846533">Sync off for <ph name="SYNC_ACCOUNT_USER_NAME" /></translation> +<translation id="8487700953926739672">Available offline</translation> +<translation id="8489271220582375723">Open the history page</translation> +<translation id="8493948351860045254">Free up space</translation> +<translation id="8497726226069778601">Nothing to see here… yet</translation> +<translation id="8503559462189395349">Chrome Passwords</translation> +<translation id="8503813439785031346">Username</translation> +<translation id="8504988642345501642">When you scroll up, show quick links to related pages. The URLs of pages that you visit are sent to Google.</translation> +<translation id="8507520749471379845">Passwords available</translation> +<translation id="8514477925623180633">Export passwords stored with Chrome</translation> +<translation id="8514577642972634246">Enter incognito mode</translation> +<translation id="851751545965956758">Block sites from connecting to devices</translation> +<translation id="8523928698583292556">Delete stored password</translation> +<translation id="854522910157234410">Open this page:</translation> +<translation id="8558485628462305855">To view augmented reality content, update ARCore</translation> +<translation id="8559990750235505898">Offer to translate pages in other languages</translation> +<translation id="8562452229998620586">Your saved passwords will appear here.</translation> +<translation id="8569404424186215731">since <ph name="DATE" /></translation> +<translation id="8571213806525832805">Last 4 weeks</translation> +<translation id="857509777403223202">More articles will appear soon. Enjoy your evening!</translation> +<translation id="857943718398505171">Allowed (recommended)</translation> +<translation id="8583805026567836021">Clearing account data</translation> +<translation id="8609465669617005112">Move up</translation> +<translation id="8616006591992756292">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="8617240290563765734">Open the suggested URL specified in the downloaded content?</translation> +<translation id="862875433388403934">Content (films, music, etc.) downloaded in other applications may no longer be playable until those applications re-acquire licences based on a new device credential. To obtain new licences, connect to the Internet and play your downloaded content.</translation> +<translation id="8636825310635137004">To get your tabs from your other devices, turn on sync.</translation> +<translation id="8641930654639604085">Try to block mature sites</translation> +<translation id="8662811608048051533">Signs you out of most sites.</translation> +<translation id="8664979001105139458">File name already exists</translation> +<translation id="8676374126336081632">Clear input</translation> +<translation id="8687353297350450808">{N_BARS,plural, =1{Signal Strength Level: # bar}other{Signal Strength Level: # bars}}</translation> +<translation id="868929229000858085">Search your contacts</translation> +<translation id="869891660844655955">Expiry date</translation> +<translation id="8719023831149562936">Can’t beam current tab</translation> +<translation id="8725066075913043281">Try again</translation> +<translation id="8728487861892616501">By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8730621377337864115">Done</translation> +<translation id="8748850008226585750">Contents hidden</translation> +<translation id="8751914237388039244">Select an image</translation> +<translation id="8788968922598763114">Reopen the last closed tab</translation> +<translation id="8812260976093120287">On some websites, you can pay with above supported payment apps on your device.</translation> +<translation id="8816439037877937734"><ph name="APP_NAME" /> will open in Chrome. By continuing, you agree to Chrome's <ph name="BEGIN_LINK1" />Terms of Service<ph name="END_LINK1" /> and <ph name="BEGIN_LINK2" />Privacy Notice<ph name="END_LINK2" />, and the <ph name="BEGIN_LINK3" />Privacy Notice for Google Accounts Managed with Family Link<ph name="END_LINK3" />.</translation> +<translation id="8820817407110198400">Bookmarks</translation> +<translation id="8823704566850948458">Suggest password...</translation> +<translation id="8830904257167680355"><ph name="DESCRIPTION" /> – <ph name="FILE_SIZE" /></translation> +<translation id="883806473910249246">An error occurred while downloading the content.</translation> +<translation id="8840953339110955557">This page may differ from the online version.</translation> +<translation id="8847988622838149491">USB</translation> +<translation id="8853345339104747198"><ph name="TAB_TITLE" />, tab</translation> +<translation id="885701979325669005">Storage</translation> +<translation id="8901170036886848654">No bookmarks found</translation> +<translation id="8909135823018751308">Share…</translation> +<translation id="8912362522468806198">Google Account</translation> +<translation id="8920114477895755567">Waiting for details of parents.</translation> +<translation id="8922289737868596582">Download pages from the More Options button to use them offline</translation> +<translation id="8941729603749328384">www.example.com</translation> +<translation id="8942627711005830162">Open in other window</translation> +<translation id="8951232171465285730">Chrome has saved you <ph name="MEGABYTES" /> MB</translation> +<translation id="8959122750345127698">Navigation is unreachable: <ph name="URL" /></translation> +<translation id="8972098258593396643">Download to default folder?</translation> +<translation id="8979405271719829084">Download videos to watch later</translation> +<translation id="8981454092730389528">Google Activity Controls</translation> +<translation id="8983677657449185470">Help improve Safe Browsing</translation> +<translation id="8986494364107987395">Automatically send usage statistics and crash reports to Google</translation> +<translation id="8993760627012879038">Open a new tab in Incognito mode</translation> +<translation id="8998729206196772491">You are signing in with an account managed by <ph name="MANAGED_DOMAIN" /> and giving its administrator control over your Chrome data. Your data will become permanently tied to this account. Signing out of Chrome will delete your data from this device, but it will remain stored in your Google account.</translation> +<translation id="9019902583201351841">Managed by your parents</translation> +<translation id="9040142327097499898">Notifications are allowed. Location is off for this device.</translation> +<translation id="9050666287014529139">Passphrase</translation> +<translation id="9060538597317784206">View app <ph name="APP_NAME" /> on the Play Store. Rating: <ph name="APP_RATING" />.</translation> +<translation id="9063523880881406963">Turn off Request desktop site</translation> +<translation id="9065203028668620118">Edit</translation> +<translation id="9070377983101773829">Start voice search</translation> +<translation id="9071742570345586758">To view virtual reality content, install Google VR Services</translation> +<translation id="9074336505530349563">To get personalised content suggested by Google, sign in and turn on sync</translation> +<translation id="9080642952018487277">Enter private mode</translation> +<translation id="9086455579313502267">Unable to access the network</translation> +<translation id="9099018167121903954"><ph name="KILOBYTES" /> KB downloaded</translation> +<translation id="9100505651305367705">Offer to show articles in simplified view, when supported</translation> +<translation id="9100610230175265781">Passphrase required</translation> +<translation id="9100939710791843300">Tap the home button to load the new tab page and view suggested articles</translation> +<translation id="9133515669113036225">Reset device credentials</translation> +<translation id="9133703968756164531"><ph name="ITEM_NAME" /> (<ph name="ITEM_ID" />)</translation> +<translation id="9137013805542155359">Show original</translation> +<translation id="9139068048179869749">Ask before allowing sites to send notifications (recommended)</translation> +<translation id="9155898266292537608">You can also search with a quick tap on a word</translation> +<translation id="9188680907066685419">Sign out of managed account</translation> +<translation id="9204836675896933765">1 file left</translation> +<translation id="9206873250291191720">A</translation> +<translation id="9218033835049520260">Suggest strong password...</translation> +<translation id="9219103736887031265">Images</translation> +<translation id="932327136139879170">Home</translation> +<translation id="932599481871055447">Save data and browse faster</translation> +<translation id="938850635132480979">Error: <ph name="ERROR_CODE" /></translation> +<translation id="945522503751344254">Send feedback</translation> +<translation id="945632385593298557">Access your microphone</translation> +<translation id="951339005376969845">Delete existing data. You can retrieve it by switching back to <ph name="FROM_ACCOUNT" />.</translation> +<translation id="95817756606698420">Chrome can use <ph name="BEGIN_BOLD" />Sogou<ph name="END_BOLD" /> for search in China. You can change this in <ph name="BEGIN_LINK" />Settings<ph name="END_LINK" />.</translation> +<translation id="970715775301869095"><ph name="MINUTES" /> mins left</translation> +<translation id="974555521953189084">Enter your passphrase to start sync</translation> +<translation id="981121421437150478">Offline</translation> +<translation id="982182592107339124">This will clear data for all sites, including:</translation> +<translation id="983192555821071799">Close all tabs</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 04727a0..03644f8 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -367,6 +367,7 @@ "java/src/org/chromium/chrome/browser/cookies/CanonicalCookie.java", "java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java", "java/src/org/chromium/chrome/browser/coordinator/CoordinatorLayoutForPointer.java", + "java/src/org/chromium/chrome/browser/crash/ApplicationStatusTracker.java", "java/src/org/chromium/chrome/browser/crash/ChromeMinidumpUploadJobService.java", "java/src/org/chromium/chrome/browser/crash/ChromeMinidumpUploaderDelegate.java", "java/src/org/chromium/chrome/browser/crash/CrashKeys.java", @@ -1267,6 +1268,7 @@ "java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionProxyUma.java", "java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java", "java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionDataUseItem.java", + "java/src/org/chromium/chrome/browser/preferences/developer/DeveloperPreferences.java", "java/src/org/chromium/chrome/browser/preferences/download/DownloadDirectoryAdapter.java", "java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreference.java", "java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreferenceAdapter.java", @@ -2239,6 +2241,7 @@ "junit/src/org/chromium/chrome/browser/browserservices/ClientAppDataRecorderTest.java", "junit/src/org/chromium/chrome/browser/browserservices/ClientAppDataRegisterTest.java", "junit/src/org/chromium/chrome/browser/browserservices/OriginTest.java", + "junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java", "junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityDisclosureTest.java", "junit/src/org/chromium/chrome/browser/compositor/animation/CompositorAnimatorTest.java", "junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java index 2682606..6283c259 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java
@@ -7,14 +7,13 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; +import android.support.customtabs.trusted.TrustedWebActivityServiceConnectionManager; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.rule.ServiceTestRule; @@ -25,12 +24,11 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.CallbackHelper; -import org.chromium.base.test.util.DisableIf; import org.chromium.chrome.R; -import org.chromium.chrome.browser.notifications.NotificationBuilderBase; import org.chromium.chrome.browser.notifications.StandardNotificationBuilder; import java.util.concurrent.TimeoutException; @@ -71,7 +69,7 @@ private TrustedWebActivityClient mClient; private Context mTargetContext; - private SpyNotificationBuilder mBuilder; + private StandardNotificationBuilder mBuilder; /** * A Handler that MessengerService will send messages to, reporting actions on @@ -121,8 +119,9 @@ @Before public void setUp() throws TimeoutException, RemoteException, InterruptedException { mTargetContext = InstrumentationRegistry.getTargetContext(); - mBuilder = new SpyNotificationBuilder(mTargetContext); - mClient = new TrustedWebActivityClient(); + mBuilder = new StandardNotificationBuilder(mTargetContext); + mClient = new TrustedWebActivityClient(new TrustedWebActivityServiceConnectionManager( + ContextUtils.getApplicationContext())); // TestTrustedWebActivityService is in the test support apk. TrustedWebActivityClient.registerClient(mTargetContext, ORIGIN, TEST_SUPPORT_PACKAGE); @@ -159,7 +158,8 @@ throws TimeoutException, InterruptedException { postNotification(); - Assert.assertEquals(1, mResponseHandler.mGetSmallIconId.getCallCount()); + Assert.assertTrue(mResponseHandler.mGetSmallIconId.getCallCount() >= 1); + // getIconId() can be called directly and also indirectly via getIconBitmap(). Assert.assertEquals(mResponseHandler.mNotificationTag, NOTIFICATION_TAG); Assert.assertEquals(mResponseHandler.mNotificationId, NOTIFICATION_ID); @@ -168,61 +168,6 @@ R.string.notification_category_group_general)); } - @Test - @SmallTest - public void usesIconFromServiceIfSmallIconsNotSet() - throws TimeoutException, InterruptedException { - postNotification(); - Assert.assertEquals(TestTrustedWebActivityService.SMALL_ICON_ID, - mBuilder.iconIdForContent); - Assert.assertEquals(TestTrustedWebActivityService.SMALL_ICON_ID, - mBuilder.iconIdForStatusBar); - } - - /** - * Tests that #notifyNotification does not overwrite the small icon if a bitmap - * was already provided and is supported. - */ - @Test - @SmallTest - @DisableIf.Build(sdk_is_less_than = 23, - message = "Sdk < 23 doesn't support small icons as Bitmaps") - public void doesntUseIconFromServiceIfStatusBarBitmapsSupported() - throws TimeoutException, InterruptedException { - // Set a custom small icon. - mBuilder.setStatusBarIcon(createBitmap()); - postNotification(); - Assert.assertNotEquals(TestTrustedWebActivityService.SMALL_ICON_ID, - mBuilder.iconIdForStatusBar); - } - - - /** - * Tests that #notifyNotification falls back to client's notification if small icon as Bitmap - * is not supported. - */ - @Test - @SmallTest - @DisableIf.Build(sdk_is_greater_than = 22, - message = "Sdk < 23 doesn't support small icons as Bitmaps") - public void usesSmallIconFromServiceIfSmallIconAsBitmapIsNotSupported() - throws TimeoutException, InterruptedException { - mBuilder.setStatusBarIcon(createBitmap()); - postNotification(); - Assert.assertEquals(TestTrustedWebActivityService.SMALL_ICON_ID, - mBuilder.iconIdForStatusBar); - } - - @Test - @SmallTest - public void doesntUseIconFromServiceIfSmallIconForContentSet() - throws TimeoutException, InterruptedException { - mBuilder.setSmallIconForContent(createBitmap()); - postNotification(); - Assert.assertNotEquals(TestTrustedWebActivityService.SMALL_ICON_ID, - mBuilder.iconIdForContent); - } - private void postNotification() throws TimeoutException, InterruptedException { @@ -233,10 +178,6 @@ mResponseHandler.mNotifyNotification.waitForCallback(); } - private Bitmap createBitmap() { - return BitmapFactory.decodeResource(mTargetContext.getResources(), R.drawable.ic_chrome); - } - /** * Tests that #cancelNotification gets the service to cancel the notification, using the given * id and tag. @@ -253,28 +194,4 @@ Assert.assertEquals(mResponseHandler.mNotificationId, NOTIFICATION_ID); } - //TODO(pshmakov): separate unit tests for the TWAClient and instrumentation tests for the - // Service connection; use Mockito in unit tests instead of inheritance. - private static class SpyNotificationBuilder extends StandardNotificationBuilder { - public int iconIdForStatusBar; - public int iconIdForContent; - - public SpyNotificationBuilder(Context context) { - super(context); - } - - @Override - public NotificationBuilderBase setStatusBarIconForRemoteApp(int iconId, - String packageName) { - iconIdForStatusBar = iconId; - return super.setStatusBarIconForRemoteApp(iconId, packageName); - } - - @Override - public NotificationBuilderBase setContentSmallIconForRemoteApp(int iconId, - String packageName) { - iconIdForContent = iconId; - return super.setContentSmallIconForRemoteApp(iconId, packageName); - } - } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicyTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicyTest.java index 4c9520b..54d0513b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicyTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicyTest.java
@@ -88,7 +88,9 @@ for (int i = 0; i < activities.size(); i++) { Activity activity = activities.get(i).get(); if (activity == null) continue; - ApplicationStatus.onStateChangeForTesting(activity, ActivityState.DESTROYED); + ThreadUtils.runOnUiThreadBlocking( + () -> ApplicationStatus.onStateChangeForTesting( + activity, ActivityState.DESTROYED)); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java new file mode 100644 index 0000000..d38e3d8 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java
@@ -0,0 +1,131 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.browserservices; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.RemoteException; +import android.support.customtabs.trusted.TrustedWebActivityServiceConnectionManager; +import android.support.customtabs.trusted.TrustedWebActivityServiceConnectionManager.ExecutionCallback; +import android.support.customtabs.trusted.TrustedWebActivityServiceWrapper; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.stubbing.Answer; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.chrome.browser.notifications.NotificationBuilderBase; + +/** + * Unit tests for {@link TrustedWebActivityClient}. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class TrustedWebActivityClientTest { + + private static final int SERVICE_SMALL_ICON_ID = 1; + + @Mock + private TrustedWebActivityServiceConnectionManager mConnection; + @Mock + private TrustedWebActivityServiceWrapper mService; + @Mock + private NotificationBuilderBase mNotificationBuilder; + + @Mock + private Bitmap mServiceSmallIconBitmap; + + private TrustedWebActivityClient mClient; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + when(mConnection.execute(any(), anyString(), any())) + .thenAnswer((Answer<Boolean>) invocation -> { + ExecutionCallback callback = invocation.getArgument(2); + callback.onConnected(mService); + return true; + }); + + when(mService.getSmallIconId()).thenReturn(SERVICE_SMALL_ICON_ID); + when(mService.getSmallIconBitmap()).thenReturn(mServiceSmallIconBitmap); + + mClient = new TrustedWebActivityClient(mConnection); + } + + @Test + public void usesIconFromService_IfStatusBarIconNotSet() { + setHasStatusBarBitmap(false); + postNotification(); + verify(mNotificationBuilder).setStatusBarIconForUntrustedRemoteApp( + SERVICE_SMALL_ICON_ID, mServiceSmallIconBitmap); + } + + + @Test + public void doesntUseIconFromService_IfContentBarIconSet() { + setHasStatusBarBitmap(true); + postNotification(); + verify(mNotificationBuilder, never()) + .setStatusBarIconForUntrustedRemoteApp(anyInt(), any()); + } + + @Test + public void usesIconFromService_IfContentSmallIconNotSet() { + setHasContentBitmap(false); + postNotification(); + verify(mNotificationBuilder) + .setContentSmallIconForUntrustedRemoteApp(mServiceSmallIconBitmap); + } + + @Test + public void doesntUseIconFromService_IfContentSmallIconSet() { + setHasContentBitmap(true); + postNotification(); + verify(mNotificationBuilder, never()).setContentSmallIconForUntrustedRemoteApp(any()); + } + + + @Test + public void doesntFetchIconIdFromService_IfBothIconsAreSet() throws RemoteException { + setHasContentBitmap(true); + setHasStatusBarBitmap(true); + postNotification(); + verify(mService, never()).getSmallIconId(); + } + + @Test + public void doesntFetchIconBitmapFromService_IfIconsIdIs() throws RemoteException { + setHasContentBitmap(false); + when(mService.getSmallIconId()).thenReturn(-1); + postNotification(); + verify(mService, never()).getSmallIconBitmap(); + } + + + private void setHasStatusBarBitmap(boolean hasBitmap) { + when(mNotificationBuilder.hasStatusBarIconBitmap()).thenReturn(hasBitmap); + } + + private void setHasContentBitmap(boolean hasBitmap) { + when(mNotificationBuilder.hasSmallIconForContent()).thenReturn(hasBitmap); + } + + private void postNotification() { + mClient.notifyNotification(Uri.parse(""), "tag", 1, mNotificationBuilder); + } +}
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index b6ce752..c546a5ab 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-72.0.3590.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-72.0.3591.0_rc-r1.afdo.bz2 \ No newline at end of file
diff --git a/chrome/android/webapk/strings/android_webapk_strings.grd b/chrome/android/webapk/strings/android_webapk_strings.grd index b94d0c7..d651ab8 100644 --- a/chrome/android/webapk/strings/android_webapk_strings.grd +++ b/chrome/android/webapk/strings/android_webapk_strings.grd
@@ -50,6 +50,7 @@ <file lang="am" path="translations/android_webapk_strings_am.xtb" /> <file lang="ar" path="translations/android_webapk_strings_ar.xtb" /> <file lang="bg" path="translations/android_webapk_strings_bg.xtb" /> + <file lang="bn" path="translations/android_webapk_strings_bn.xtb" /> <file lang="ca" path="translations/android_webapk_strings_ca.xtb" /> <file lang="cs" path="translations/android_webapk_strings_cs.xtb" /> <file lang="da" path="translations/android_webapk_strings_da.xtb" /> @@ -58,10 +59,12 @@ <file lang="en-GB" path="translations/android_webapk_strings_en-GB.xtb" /> <file lang="es" path="translations/android_webapk_strings_es.xtb" /> <file lang="es-419" path="translations/android_webapk_strings_es-419.xtb" /> + <file lang="et" path="translations/android_webapk_strings_et.xtb" /> <file lang="fa" path="translations/android_webapk_strings_fa.xtb" /> <file lang="fi" path="translations/android_webapk_strings_fi.xtb" /> <file lang="fil" path="translations/android_webapk_strings_fil.xtb" /> <file lang="fr" path="translations/android_webapk_strings_fr.xtb" /> + <file lang="gu" path="translations/android_webapk_strings_gu.xtb" /> <file lang="hi" path="translations/android_webapk_strings_hi.xtb" /> <file lang="hr" path="translations/android_webapk_strings_hr.xtb" /> <file lang="hu" path="translations/android_webapk_strings_hu.xtb" /> @@ -70,8 +73,12 @@ <file lang="iw" path="translations/android_webapk_strings_iw.xtb" /> <file lang="ja" path="translations/android_webapk_strings_ja.xtb" /> <file lang="ko" path="translations/android_webapk_strings_ko.xtb" /> + <file lang="kn" path="translations/android_webapk_strings_kn.xtb" /> <file lang="lt" path="translations/android_webapk_strings_lt.xtb" /> <file lang="lv" path="translations/android_webapk_strings_lv.xtb" /> + <file lang="ml" path="translations/android_webapk_strings_ml.xtb" /> + <file lang="mr" path="translations/android_webapk_strings_mr.xtb" /> + <file lang="ms" path="translations/android_webapk_strings_ms.xtb" /> <file lang="nl" path="translations/android_webapk_strings_nl.xtb" /> <file lang="no" path="translations/android_webapk_strings_no.xtb" /> <file lang="pl" path="translations/android_webapk_strings_pl.xtb" /> @@ -84,6 +91,8 @@ <file lang="sr" path="translations/android_webapk_strings_sr.xtb" /> <file lang="sv" path="translations/android_webapk_strings_sv.xtb" /> <file lang="sw" path="translations/android_webapk_strings_sw.xtb" /> + <file lang="ta" path="translations/android_webapk_strings_ta.xtb" /> + <file lang="te" path="translations/android_webapk_strings_te.xtb" /> <file lang="th" path="translations/android_webapk_strings_th.xtb" /> <file lang="tr" path="translations/android_webapk_strings_tr.xtb" /> <file lang="uk" path="translations/android_webapk_strings_uk.xtb" />
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_bn.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_bn.xtb new file mode 100644 index 0000000..591d67e --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_bn.xtb
@@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="bn"> +<translation id="1700971771753530690"><ph name="APP_NAME" /> requires the following app:</translation> +<translation id="2697679025356221813"><ph name="APP_NAME" /> requires a web browser</translation> +<translation id="3858759029325727987">Choose a browser that supports this app:</translation> +<translation id="6377677440246641805"><ph name="BROWSER_NAME" />\nUnsupported</translation> +<translation id="7671141431838911305">INSTALL</translation> +<translation id="8252328707312954493">CLOSE</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_et.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_et.xtb new file mode 100644 index 0000000..311f7f2 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_et.xtb
@@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="et"> +<translation id="1700971771753530690"><ph name="APP_NAME" /> requires the following app:</translation> +<translation id="2697679025356221813"><ph name="APP_NAME" /> requires a web browser</translation> +<translation id="3858759029325727987">Choose a browser that supports this app:</translation> +<translation id="6377677440246641805"><ph name="BROWSER_NAME" />\nUnsupported</translation> +<translation id="7671141431838911305">INSTALL</translation> +<translation id="8252328707312954493">CLOSE</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_gu.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_gu.xtb new file mode 100644 index 0000000..612e48fe --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_gu.xtb
@@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="gu"> +<translation id="1700971771753530690"><ph name="APP_NAME" /> requires the following app:</translation> +<translation id="2697679025356221813"><ph name="APP_NAME" /> requires a web browser</translation> +<translation id="3858759029325727987">Choose a browser that supports this app:</translation> +<translation id="6377677440246641805"><ph name="BROWSER_NAME" />\nUnsupported</translation> +<translation id="7671141431838911305">INSTALL</translation> +<translation id="8252328707312954493">CLOSE</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_kn.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_kn.xtb new file mode 100644 index 0000000..f5bbf48 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_kn.xtb
@@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="kn"> +<translation id="1700971771753530690"><ph name="APP_NAME" /> requires the following app:</translation> +<translation id="2697679025356221813"><ph name="APP_NAME" /> requires a web browser</translation> +<translation id="3858759029325727987">Choose a browser that supports this app:</translation> +<translation id="6377677440246641805"><ph name="BROWSER_NAME" />\nUnsupported</translation> +<translation id="7671141431838911305">INSTALL</translation> +<translation id="8252328707312954493">CLOSE</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_ml.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_ml.xtb new file mode 100644 index 0000000..59e2b78d --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_ml.xtb
@@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ml"> +<translation id="1700971771753530690"><ph name="APP_NAME" /> requires the following app:</translation> +<translation id="2697679025356221813"><ph name="APP_NAME" /> requires a web browser</translation> +<translation id="3858759029325727987">Choose a browser that supports this app:</translation> +<translation id="6377677440246641805"><ph name="BROWSER_NAME" />\nUnsupported</translation> +<translation id="7671141431838911305">INSTALL</translation> +<translation id="8252328707312954493">CLOSE</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_mr.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_mr.xtb new file mode 100644 index 0000000..3a055565 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_mr.xtb
@@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="mr"> +<translation id="1700971771753530690"><ph name="APP_NAME" /> requires the following app:</translation> +<translation id="2697679025356221813"><ph name="APP_NAME" /> requires a web browser</translation> +<translation id="3858759029325727987">Choose a browser that supports this app:</translation> +<translation id="6377677440246641805"><ph name="BROWSER_NAME" />\nUnsupported</translation> +<translation id="7671141431838911305">INSTALL</translation> +<translation id="8252328707312954493">CLOSE</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_ms.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_ms.xtb new file mode 100644 index 0000000..2745996 --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_ms.xtb
@@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ms"> +<translation id="1700971771753530690"><ph name="APP_NAME" /> requires the following app:</translation> +<translation id="2697679025356221813"><ph name="APP_NAME" /> requires a web browser</translation> +<translation id="3858759029325727987">Choose a browser that supports this app:</translation> +<translation id="6377677440246641805"><ph name="BROWSER_NAME" />\nUnsupported</translation> +<translation id="7671141431838911305">INSTALL</translation> +<translation id="8252328707312954493">CLOSE</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_ta.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_ta.xtb new file mode 100644 index 0000000..a4f9bbb --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_ta.xtb
@@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ta"> +<translation id="1700971771753530690"><ph name="APP_NAME" /> requires the following app:</translation> +<translation id="2697679025356221813"><ph name="APP_NAME" /> requires a web browser</translation> +<translation id="3858759029325727987">Choose a browser that supports this app:</translation> +<translation id="6377677440246641805"><ph name="BROWSER_NAME" />\nUnsupported</translation> +<translation id="7671141431838911305">INSTALL</translation> +<translation id="8252328707312954493">CLOSE</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/android/webapk/strings/translations/android_webapk_strings_te.xtb b/chrome/android/webapk/strings/translations/android_webapk_strings_te.xtb new file mode 100644 index 0000000..a645a2f --- /dev/null +++ b/chrome/android/webapk/strings/translations/android_webapk_strings_te.xtb
@@ -0,0 +1,11 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="te"> +<translation id="1700971771753530690"><ph name="APP_NAME" /> requires the following app:</translation> +<translation id="2697679025356221813"><ph name="APP_NAME" /> requires a web browser</translation> +<translation id="3858759029325727987">Choose a browser that supports this app:</translation> +<translation id="6377677440246641805"><ph name="BROWSER_NAME" />\nUnsupported</translation> +<translation id="7671141431838911305">INSTALL</translation> +<translation id="8252328707312954493">CLOSE</translation> +<translation id="987264212798334818">General</translation> +</translationbundle> \ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index a7a32ec..e1ee297 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -8299,6 +8299,9 @@ <message name="IDS_SEARCH_BOX_HINT_FULLSCREEN" desc="Hint text for the search box in fullscreen app list window."> Search your device, apps, web... </message> + <message name="IDS_APP_ACTION_SHORTCUT_ACCESSIBILITY_NAME" desc="Hint text for the search result that performs a specific action with an app."> + <ph name="ACTION_NAME">$1<ex>Compose</ex></ph> with <ph name="APP_NAME">$2<ex>GMail</ex></ph>. + </message> <if expr="not use_titlecase"> <message name="IDS_APP_LIST_CONTEXT_MENU_NEW_TAB" desc="Title text for the 'open new' context menu item of an app list item configured to open in a tab"> New tab
diff --git a/chrome/app/generated_resources_grd/IDS_APP_ACTION_SHORTCUT_ACCESSIBILITY_NAME.png.sha1 b/chrome/app/generated_resources_grd/IDS_APP_ACTION_SHORTCUT_ACCESSIBILITY_NAME.png.sha1 new file mode 100644 index 0000000..4025a04 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_APP_ACTION_SHORTCUT_ACCESSIBILITY_NAME.png.sha1
@@ -0,0 +1 @@ +310f356b8cecac26beaf425ac85516c5bf8ccf29 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index f5cc05b..3b32909 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -3180,6 +3180,7 @@ "//chromeos/strings", "//components/services/font:lib", "//components/services/font/public/interfaces", + "//components/sync_wifi", "//services/ws:lib", "//services/ws/public/cpp/input_devices", "//services/ws/public/cpp/input_devices:input_device_controller",
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 84890b07..907706ee 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -105,6 +105,7 @@ &kContextualSearchUnityIntegration, &kCustomContextMenu, &kCustomFeedbackUi, + &kDeveloperPreferences, &kDontPrefetchLibraries, &kDownloadProgressInfoBar, &kDownloadHomeV2, @@ -285,6 +286,9 @@ const base::Feature kCustomFeedbackUi{"CustomFeedbackUi", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kDeveloperPreferences{"DeveloperPreferences", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kDontPrefetchLibraries{"DontPrefetchLibraries", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index 2c51f93..aaa8a99 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -43,6 +43,7 @@ extern const base::Feature kContextualSearchUnityIntegration; extern const base::Feature kCustomContextMenu; extern const base::Feature kCustomFeedbackUi; +extern const base::Feature kDeveloperPreferences; extern const base::Feature kDontPrefetchLibraries; extern const base::Feature kDownloadAutoResumptionThrottling; extern const base::Feature kDownloadProgressInfoBar;
diff --git a/chrome/browser/android/crash/crash_keys_android.cc b/chrome/browser/android/crash/crash_keys_android.cc index c228458..dfd065c 100644 --- a/chrome/browser/android/crash/crash_keys_android.cc +++ b/chrome/browser/android/crash/crash_keys_android.cc
@@ -18,6 +18,7 @@ static JavaCrashKey crash_keys[] = { {"loaded_dynamic_module", JavaCrashKey::Tag::kArray}, {"active_dynamic_module", JavaCrashKey::Tag::kArray}, + {"application_status", JavaCrashKey::Tag::kArray}, }; static_assert( base::size(crash_keys) == static_cast<size_t>(CrashKeyIndex::NUM_KEYS),
diff --git a/chrome/browser/android/crash/crash_keys_android.h b/chrome/browser/android/crash/crash_keys_android.h index c2c0f66..25636e0 100644 --- a/chrome/browser/android/crash/crash_keys_android.h +++ b/chrome/browser/android/crash/crash_keys_android.h
@@ -13,6 +13,7 @@ enum class CrashKeyIndex { LOADED_DYNAMIC_MODULE = 0, ACTIVE_DYNAMIC_MODULE, + APPLICATION_STATUS, NUM_KEYS };
diff --git a/chrome/browser/apps/platform_apps/api/BUILD.gn b/chrome/browser/apps/platform_apps/api/BUILD.gn index dd943ce..9389f8ac 100644 --- a/chrome/browser/apps/platform_apps/api/BUILD.gn +++ b/chrome/browser/apps/platform_apps/api/BUILD.gn
@@ -67,6 +67,10 @@ "easy_unlock_private/easy_unlock_private_connection.h", "easy_unlock_private/easy_unlock_private_connection_manager.cc", "easy_unlock_private/easy_unlock_private_connection_manager.h", + "webstore_widget_private/app_installer.cc", + "webstore_widget_private/app_installer.h", + "webstore_widget_private/webstore_widget_private_api.cc", + "webstore_widget_private/webstore_widget_private_api.h", ] deps += [
diff --git a/chrome/browser/extensions/api/webstore_widget_private/OWNERS b/chrome/browser/apps/platform_apps/api/webstore_widget_private/OWNERS similarity index 100% rename from chrome/browser/extensions/api/webstore_widget_private/OWNERS rename to chrome/browser/apps/platform_apps/api/webstore_widget_private/OWNERS
diff --git a/chrome/browser/extensions/api/webstore_widget_private/app_installer.cc b/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.cc similarity index 95% rename from chrome/browser/extensions/api/webstore_widget_private/app_installer.cc rename to chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.cc index 025bfdb..5d51766 100644 --- a/chrome/browser/extensions/api/webstore_widget_private/app_installer.cc +++ b/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.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/webstore_widget_private/app_installer.h" +#include "chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.h" #include "base/macros.h" #include "chrome/common/extensions/webstore_install_result.h" @@ -45,8 +45,7 @@ DCHECK(web_contents_); } -AppInstaller::~AppInstaller() { -} +AppInstaller::~AppInstaller() {} bool AppInstaller::CheckRequestorAlive() const { // The tab may have gone away - cancel installation in that case.
diff --git a/chrome/browser/extensions/api/webstore_widget_private/app_installer.h b/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.h similarity index 85% rename from chrome/browser/extensions/api/webstore_widget_private/app_installer.h rename to chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.h index 7f379fe..a2d6188 100644 --- a/chrome/browser/extensions/api/webstore_widget_private/app_installer.h +++ b/chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_EXTENSIONS_API_WEBSTORE_WIDGET_PRIVATE_APP_INSTALLER_H_ -#define CHROME_BROWSER_EXTENSIONS_API_WEBSTORE_WIDGET_PRIVATE_APP_INSTALLER_H_ +#ifndef CHROME_BROWSER_APPS_PLATFORM_APPS_API_WEBSTORE_WIDGET_PRIVATE_APP_INSTALLER_H_ +#define CHROME_BROWSER_APPS_PLATFORM_APPS_API_WEBSTORE_WIDGET_PRIVATE_APP_INSTALLER_H_ #include <string> @@ -56,4 +56,4 @@ } // namespace webstore_widget -#endif // CHROME_BROWSER_EXTENSIONS_API_WEBSTORE_WIDGET_PRIVATE_APP_INSTALLER_H_ +#endif // CHROME_BROWSER_APPS_PLATFORM_APPS_API_WEBSTORE_WIDGET_PRIVATE_APP_INSTALLER_H_
diff --git a/chrome/browser/extensions/api/webstore_widget_private/webstore_widget_private_api.cc b/chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.cc similarity index 80% rename from chrome/browser/extensions/api/webstore_widget_private/webstore_widget_private_api.cc rename to chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.cc index c2b6589..da79b489 100644 --- a/chrome/browser/extensions/api/webstore_widget_private/webstore_widget_private_api.cc +++ b/chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.cc
@@ -2,18 +2,18 @@ // 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/webstore_widget_private/webstore_widget_private_api.h" +#include "chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.h" #include <memory> #include <utility> +#include "chrome/browser/apps/platform_apps/api/webstore_widget_private/app_installer.h" #include "chrome/browser/chromeos/file_manager/app_id.h" -#include "chrome/browser/extensions/api/webstore_widget_private/app_installer.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/common/extensions/api/webstore_widget_private.h" +#include "chrome/common/apps/platform_apps/api/webstore_widget_private.h" #include "extensions/browser/extension_function_constants.h" -namespace extensions { +namespace chrome_apps { namespace api { namespace { @@ -23,12 +23,10 @@ } // namespace WebstoreWidgetPrivateInstallWebstoreItemFunction:: - WebstoreWidgetPrivateInstallWebstoreItemFunction() { -} + WebstoreWidgetPrivateInstallWebstoreItemFunction() {} WebstoreWidgetPrivateInstallWebstoreItemFunction:: - ~WebstoreWidgetPrivateInstallWebstoreItemFunction() { -} + ~WebstoreWidgetPrivateInstallWebstoreItemFunction() {} ExtensionFunction::ResponseAction WebstoreWidgetPrivateInstallWebstoreItemFunction::Run() { @@ -53,7 +51,7 @@ content::WebContents* web_contents = GetSenderWebContents(); if (!web_contents) { return RespondNow( - Error(function_constants::kCouldNotFindSenderWebContents)); + Error(extensions::function_constants::kCouldNotFindSenderWebContents)); } scoped_refptr<webstore_widget::AppInstaller> installer( new webstore_widget::AppInstaller( @@ -74,4 +72,4 @@ } } // namespace api -} // namespace extensions +} // namespace chrome_apps
diff --git a/chrome/browser/extensions/api/webstore_widget_private/webstore_widget_private_api.h b/chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.h similarity index 74% rename from chrome/browser/extensions/api/webstore_widget_private/webstore_widget_private_api.h rename to chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.h index 715bd08..6187b2f2 100644 --- a/chrome/browser/extensions/api/webstore_widget_private/webstore_widget_private_api.h +++ b/chrome/browser/apps/platform_apps/api/webstore_widget_private/webstore_widget_private_api.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_EXTENSIONS_API_WEBSTORE_WIDGET_PRIVATE_WEBSTORE_WIDGET_PRIVATE_API_H_ -#define CHROME_BROWSER_EXTENSIONS_API_WEBSTORE_WIDGET_PRIVATE_WEBSTORE_WIDGET_PRIVATE_API_H_ +#ifndef CHROME_BROWSER_APPS_PLATFORM_APPS_API_WEBSTORE_WIDGET_PRIVATE_WEBSTORE_WIDGET_PRIVATE_API_H_ +#define CHROME_BROWSER_APPS_PLATFORM_APPS_API_WEBSTORE_WIDGET_PRIVATE_WEBSTORE_WIDGET_PRIVATE_API_H_ #include <string> @@ -11,7 +11,7 @@ #include "chrome/common/extensions/webstore_install_result.h" #include "extensions/browser/extension_function.h" -namespace extensions { +namespace chrome_apps { namespace api { class WebstoreWidgetPrivateInstallWebstoreItemFunction @@ -37,6 +37,6 @@ }; } // namespace api -} // namespace extensions +} // namespace chrome_apps -#endif // CHROME_BROWSER_EXTENSIONS_API_WEBSTORE_WIDGET_PRIVATE_WEBSTORE_WIDGET_PRIVATE_API_H_ +#endif // CHROME_BROWSER_APPS_PLATFORM_APPS_API_WEBSTORE_WIDGET_PRIVATE_WEBSTORE_WIDGET_PRIVATE_API_H_
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index ee657e1..6018469 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -157,7 +157,6 @@ "//components/startup_metric_utils/browser:lib", "//components/storage_monitor", "//components/sync_preferences", - "//components/sync_wifi", "//components/toolbar", "//components/tracing:startup_tracing", "//components/translate/core/browser:browser",
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc index 2f66ac38..cc9c50f 100644 --- a/chrome/browser/chromeos/policy/device_status_collector.cc +++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -81,6 +81,7 @@ #include "components/user_manager/user_manager.h" #include "components/user_manager/user_type.h" #include "components/version_info/version_info.h" +#include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" #include "storage/browser/fileapi/external_mount_points.h" @@ -300,6 +301,8 @@ } void ReadTpmStatus(policy::DeviceStatusCollector::TpmStatusReceiver callback) { + // D-Bus calls are allowed only on the UI thread. + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->GetTpmStatus( cryptohome::GetTpmStatusRequest(), base::BindOnce( @@ -442,15 +445,10 @@ base::Bind(&GetStatusState::OnAndroidInfoReceived, this)); } - // Queues an async callback to query TPM status information. void FetchTpmStatus(const policy::DeviceStatusCollector::TpmStatusFetcher& tpm_status_fetcher) { - // Call out to the blocking pool to get TPM status information. - base::PostTaskWithTraits( - FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::BindOnce( - tpm_status_fetcher, - base::BindOnce(&GetStatusState::OnTpmStatusReceived, this))); + tpm_status_fetcher.Run( + base::BindOnce(&GetStatusState::OnTpmStatusReceived, this)); } private: @@ -490,12 +488,14 @@ } void OnTpmStatusReceived(const TpmStatusInfo& tpm_status_struct) { + // Make sure we edit the state on the right thread. + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); em::TpmStatusInfo* const tpm_status_proto = device_status_->mutable_tpm_status_info(); tpm_status_proto->set_enabled(tpm_status_struct.enabled); tpm_status_proto->set_owned(tpm_status_struct.owned); - tpm_status_proto->set_initialized(tpm_status_struct.initialized); + tpm_status_proto->set_tpm_initialized(tpm_status_struct.initialized); tpm_status_proto->set_attestation_prepared( tpm_status_struct.attestation_prepared); tpm_status_proto->set_attestation_enrolled( @@ -1391,6 +1391,27 @@ return anything_reported; } +bool DeviceStatusCollector::GetWriteProtectSwitch( + em::DeviceStatusReportRequest* status) { + std::string firmware_write_protect; + if (!statistics_provider_->GetMachineStatistic( + chromeos::system::kFirmwareWriteProtectBootKey, + &firmware_write_protect)) { + return false; + } + + if (firmware_write_protect == + chromeos::system::kFirmwareWriteProtectBootValueOff) { + status->set_write_protect_switch(false); + } else if (firmware_write_protect == + chromeos::system::kFirmwareWriteProtectBootValueOn) { + status->set_write_protect_switch(true); + } else { + return false; + } + return true; +} + bool DeviceStatusCollector::GetNetworkInterfaces( em::DeviceStatusReportRequest* status) { // Maps shill device type strings to proto enum constants. @@ -1704,8 +1725,10 @@ if (report_users_) anything_reported |= GetUsers(status); - if (report_hardware_status_) + if (report_hardware_status_) { anything_reported |= GetHardwareStatus(status, state); + anything_reported |= GetWriteProtectSwitch(status); + } if (report_os_update_status_) anything_reported |= GetOsUpdateStatus(status);
diff --git a/chrome/browser/chromeos/policy/device_status_collector.h b/chrome/browser/chromeos/policy/device_status_collector.h index f2289bf6..48b8ec0 100644 --- a/chrome/browser/chromeos/policy/device_status_collector.h +++ b/chrome/browser/chromeos/policy/device_status_collector.h
@@ -253,6 +253,8 @@ enterprise_management::DeviceStatusReportRequest* status); bool GetVersionInfo(enterprise_management::DeviceStatusReportRequest* status); bool GetBootMode(enterprise_management::DeviceStatusReportRequest* status); + bool GetWriteProtectSwitch( + enterprise_management::DeviceStatusReportRequest* status); bool GetNetworkInterfaces( enterprise_management::DeviceStatusReportRequest* status); bool GetUsers(enterprise_management::DeviceStatusReportRequest* status);
diff --git a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc index 151c23d..ae4f546 100644 --- a/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_status_collector_browsertest.cc
@@ -1095,6 +1095,48 @@ EXPECT_EQ("Dev", device_status_.boot_mode()); } +TEST_F(DeviceStatusCollectorTest, WriteProtectSwitch) { + // Test that write protect switch is reported by default. + fake_statistics_provider_.SetMachineStatistic( + chromeos::system::kFirmwareWriteProtectBootKey, + chromeos::system::kFirmwareWriteProtectBootValueOn); + GetStatus(); + EXPECT_TRUE(device_status_.write_protect_switch()); + + // Test that write protect switch is not reported if the hardware report pref + // is off. + settings_helper_.SetBoolean(chromeos::kReportDeviceHardwareStatus, false); + + GetStatus(); + EXPECT_FALSE(device_status_.has_write_protect_switch()); + + // Turn the pref on, and check that the status is reported iff the + // statistics provider returns valid data. + settings_helper_.SetBoolean(chromeos::kReportDeviceHardwareStatus, true); + + fake_statistics_provider_.SetMachineStatistic( + chromeos::system::kFirmwareWriteProtectBootKey, "(error)"); + GetStatus(); + EXPECT_FALSE(device_status_.has_write_protect_switch()); + + fake_statistics_provider_.SetMachineStatistic( + chromeos::system::kFirmwareWriteProtectBootKey, " "); + GetStatus(); + EXPECT_FALSE(device_status_.has_write_protect_switch()); + + fake_statistics_provider_.SetMachineStatistic( + chromeos::system::kFirmwareWriteProtectBootKey, + chromeos::system::kFirmwareWriteProtectBootValueOn); + GetStatus(); + EXPECT_TRUE(device_status_.write_protect_switch()); + + fake_statistics_provider_.SetMachineStatistic( + chromeos::system::kFirmwareWriteProtectBootKey, + chromeos::system::kFirmwareWriteProtectBootValueOff); + GetStatus(); + EXPECT_FALSE(device_status_.write_protect_switch()); +} + TEST_F(DeviceStatusCollectorTest, VersionInfo) { // Expect the version info to be reported by default. GetStatus(); @@ -1517,7 +1559,7 @@ EXPECT_EQ(kFakeTpmStatus.enabled, device_status_.tpm_status_info().enabled()); EXPECT_EQ(kFakeTpmStatus.owned, device_status_.tpm_status_info().owned()); EXPECT_EQ(kFakeTpmStatus.initialized, - device_status_.tpm_status_info().initialized()); + device_status_.tpm_status_info().tpm_initialized()); EXPECT_EQ(kFakeTpmStatus.attestation_prepared, device_status_.tpm_status_info().attestation_prepared()); EXPECT_EQ(kFakeTpmStatus.attestation_enrolled, @@ -2364,6 +2406,17 @@ EXPECT_EQ("Verified", device_status_.boot_mode()); } +TEST_F(ConsumerDeviceStatusCollectorTimeLimitDisabledTest, + NotReportingWriteProtectSwitch) { + fake_statistics_provider_.SetMachineStatistic( + chromeos::system::kFirmwareWriteProtectBootKey, + chromeos::system::kFirmwareWriteProtectBootValueOn); + + GetStatus(); + + EXPECT_FALSE(device_status_.has_write_protect_switch()); +} + TEST_F(ConsumerDeviceStatusCollectorTimeLimitDisabledTest, ReportingArcStatus) { RestartStatusCollector( base::BindRepeating(&GetEmptyVolumeInfo),
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.cc b/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.cc index 258997c0..11042a6 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.cc +++ b/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.cc
@@ -10,7 +10,6 @@ #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "content/public/browser/notification_source.h" #include "google_apis/gaia/gaia_constants.h" -#include "services/identity/public/cpp/identity_manager.h" namespace policy { @@ -35,12 +34,13 @@ void UserCloudPolicyTokenForwarder::Shutdown() { request_.reset(); - token_service_->RemoveObserver(this); + identity_manager_->RemoveObserver(this); manager_->core()->service()->RemoveObserver(this); } -void UserCloudPolicyTokenForwarder::OnRefreshTokenAvailable( - const std::string& account_id) { +void UserCloudPolicyTokenForwarder::OnRefreshTokenUpdatedForAccount( + const AccountInfo& account_info, + bool is_valid) { RequestAccessToken(); } @@ -82,7 +82,7 @@ if (identity_manager_->HasPrimaryAccountWithRefreshToken()) RequestAccessToken(); else - token_service_->AddObserver(this); + identity_manager_->AddObserver(this); } void UserCloudPolicyTokenForwarder::RequestAccessToken() {
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.h b/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.h index dd0e855..3a43b79 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.h +++ b/chrome/browser/chromeos/policy/user_cloud_policy_token_forwarder.h
@@ -9,13 +9,10 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/policy/core/common/cloud/cloud_policy_service.h" #include "google_apis/gaia/oauth2_token_service.h" +#include "services/identity/public/cpp/identity_manager.h" class ProfileOAuth2TokenService; -namespace identity { -class IdentityManager; -} - namespace policy { class UserCloudPolicyManagerChromeOS; @@ -25,10 +22,11 @@ // ready. This service decouples the UserCloudPolicyManagerChromeOS from // depending directly on the ProfileOAuth2TokenService, since it is initialized // much earlier. -class UserCloudPolicyTokenForwarder : public KeyedService, - public OAuth2TokenService::Observer, - public OAuth2TokenService::Consumer, - public CloudPolicyService::Observer { +class UserCloudPolicyTokenForwarder + : public KeyedService, + public identity::IdentityManager::Observer, + public OAuth2TokenService::Consumer, + public CloudPolicyService::Observer { public: // The factory of this PKS depends on the factories of these two arguments, // so this object will be Shutdown() first and these pointers can be used @@ -41,8 +39,9 @@ // KeyedService: void Shutdown() override; - // OAuth2TokenService::Observer: - void OnRefreshTokenAvailable(const std::string& account_id) override; + // IdentityManager::Observer: + void OnRefreshTokenUpdatedForAccount(const AccountInfo& account_info, + bool is_valid) override; // OAuth2TokenService::Consumer: void OnGetTokenSuccess(
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index f6221cf..7bd008a 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -940,10 +940,6 @@ "api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc", "api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.h", "api/vpn_provider/vpn_service_factory.cc", - "api/webstore_widget_private/app_installer.cc", - "api/webstore_widget_private/app_installer.h", - "api/webstore_widget_private/webstore_widget_private_api.cc", - "api/webstore_widget_private/webstore_widget_private_api.h", "chrome_kiosk_delegate_chromeos.cc", "updater/chromeos_extension_cache_delegate.cc", "updater/chromeos_extension_cache_delegate.h",
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest.cc b/chrome/browser/media/webrtc/webrtc_browsertest.cc index a88de924..a0e9975 100644 --- a/chrome/browser/media/webrtc/webrtc_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_browsertest.cc
@@ -33,12 +33,19 @@ static const char kKeygenAlgorithmEcdsa[] = "{ name: \"ECDSA\", namedCurve: \"P-256\" }"; +// TODO(crbug.com/898546): Many WebRtcBrowserTests flakily leak. +#if defined(ADDRESS_SANITIZER) +#define MAYBE_WebRtcBrowserTest DISABLED_WebRtcBrowserTest +#else +#define MAYBE_WebRtcBrowserTest WebRtcBrowserTest +#endif + // Top-level integration test for WebRTC. It always uses fake devices; see // WebRtcWebcamBrowserTest for a test that acquires any real webcam on the // system. -class WebRtcBrowserTest : public WebRtcTestBase { +class MAYBE_WebRtcBrowserTest : public WebRtcTestBase { public: - WebRtcBrowserTest() : left_tab_(nullptr), right_tab_(nullptr) {} + MAYBE_WebRtcBrowserTest() : left_tab_(nullptr), right_tab_(nullptr) {} void SetUpInProcessBrowserTestFixture() override { DetectErrorsInJavaScript(); // Look for errors in our rather complex js. @@ -122,19 +129,19 @@ content::WebContents* right_tab_; }; -IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsVP8) { RunsAudioVideoWebRTCCallInTwoTabs("VP8"); } -IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsVP9) { RunsAudioVideoWebRTCCallInTwoTabs("VP9"); } #if BUILDFLAG(RTC_USE_H264) -IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsH264) { // Only run test if run-time feature corresponding to |rtc_use_h264| is on. if (!base::FeatureList::IsEnabled(content::kWebRtcH264WithOpenH264FFmpeg)) { @@ -157,7 +164,7 @@ #endif // BUILDFLAG(RTC_USE_H264) -IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, TestWebAudioMediaStream) { +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, TestWebAudioMediaStream) { // This tests against crash regressions for the WebAudio-MediaStream // integration. ASSERT_TRUE(embedded_test_server()->Start()); @@ -172,14 +179,14 @@ ASSERT_FALSE(tab->IsCrashed()); } -IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsOfferRsaAnswerRsa) { RunsAudioVideoWebRTCCallInTwoTabs(WebRtcTestBase::kUseDefaultVideoCodec, false /* prefer_hw_video_codec */, kKeygenAlgorithmRsa, kKeygenAlgorithmRsa); } -IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsOfferEcdsaAnswerEcdsa) { RunsAudioVideoWebRTCCallInTwoTabs( WebRtcTestBase::kUseDefaultVideoCodec, false /* prefer_hw_video_codec */, @@ -187,32 +194,32 @@ } IN_PROC_BROWSER_TEST_F( - WebRtcBrowserTest, + MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsWithClonedCertificateRsa) { RunsAudioVideoWebRTCCallInTwoTabsWithClonedCertificate(kKeygenAlgorithmRsa); } IN_PROC_BROWSER_TEST_F( - WebRtcBrowserTest, + MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsWithClonedCertificateEcdsa) { RunsAudioVideoWebRTCCallInTwoTabsWithClonedCertificate(kKeygenAlgorithmEcdsa); } -IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsOfferRsaAnswerEcdsa) { RunsAudioVideoWebRTCCallInTwoTabs(WebRtcTestBase::kUseDefaultVideoCodec, false /* prefer_hw_video_codec */, kKeygenAlgorithmRsa, kKeygenAlgorithmEcdsa); } -IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsOfferEcdsaAnswerRsa) { RunsAudioVideoWebRTCCallInTwoTabs(WebRtcTestBase::kUseDefaultVideoCodec, false /* prefer_hw_video_codec */, kKeygenAlgorithmEcdsa, kKeygenAlgorithmRsa); } -IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsGetStatsCallback) { StartServerAndOpenTabs(); SetupPeerconnectionWithLocalStream(left_tab_); @@ -231,7 +238,7 @@ #define MAYBE_RunsAudioVideoWebRTCCallInTwoTabsGetStatsPromise \ RunsAudioVideoWebRTCCallInTwoTabsGetStatsPromise #endif -IN_PROC_BROWSER_TEST_F(WebRtcBrowserTest, +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcBrowserTest, MAYBE_RunsAudioVideoWebRTCCallInTwoTabsGetStatsPromise) { StartServerAndOpenTabs(); SetupPeerconnectionWithLocalStream(left_tab_); @@ -255,7 +262,7 @@ } IN_PROC_BROWSER_TEST_F( - WebRtcBrowserTest, + MAYBE_WebRtcBrowserTest, RunsAudioVideoWebRTCCallInTwoTabsEmitsGatheringStateChange) { StartServerAndOpenTabs(); SetupPeerconnectionWithLocalStream(left_tab_);
diff --git a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc index 1a6068f..0248cfe 100644 --- a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
@@ -56,12 +56,12 @@ // Real desktop capture is flaky on below platforms. #if defined(OS_CHROMEOS) || defined(OS_WIN) -#define MAYBE_MANUAL_GetDisplayMediaVideo DISABLED_MANUAL_GetDisplayMediaVideo +#define MAYBE_GetDisplayMediaVideo DISABLED_GetDisplayMediaVideo #else -#define MAYBE_MANUAL_GetDisplayMediaVideo MANUAL_GetDisplayMediaVideo +#define MAYBE_GetDisplayMediaVideo GetDisplayMediaVideo #endif IN_PROC_BROWSER_TEST_F(WebRtcGetDisplayMediaBrowserTestWithPicker, - MAYBE_MANUAL_GetDisplayMediaVideo) { + MAYBE_GetDisplayMediaVideo) { ASSERT_TRUE(embedded_test_server()->Start()); content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage); @@ -94,7 +94,7 @@ }; IN_PROC_BROWSER_TEST_P(WebRtcGetDisplayMediaBrowserTestWithFakeUI, - MANUAL_GetDisplayMedia) { + GetDisplayMedia) { ASSERT_TRUE(embedded_test_server()->Start()); content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage); @@ -115,6 +115,28 @@ EXPECT_EQ(result, test_config_.cursor); } +IN_PROC_BROWSER_TEST_P(WebRtcGetDisplayMediaBrowserTestWithFakeUI, + GetDisplayMediaWithConstraints) { + ASSERT_TRUE(embedded_test_server()->Start()); + + content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage); + const int kMaxWidth = 200; + const int kMaxFrameRate = 6; + const std::string& constraints = + base::StringPrintf("{video: {width: {max: %d}, frameRate: {max: %d}}}", + kMaxWidth, kMaxFrameRate); + RunGetDisplayMedia(tab, constraints); + + std::string result; + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + tab->GetMainFrame(), "getWidthSetting();", &result)); + EXPECT_EQ(result, base::StringPrintf("%d", kMaxWidth)); + + EXPECT_TRUE(content::ExecuteScriptAndExtractString( + tab->GetMainFrame(), "getFrameRateSetting();", &result)); + EXPECT_EQ(result, base::StringPrintf("%d", kMaxFrameRate)); +} + INSTANTIATE_TEST_CASE_P(, WebRtcGetDisplayMediaBrowserTestWithFakeUI, testing::Values(TestConfig{"monitor", "true", "never"},
diff --git a/chrome/browser/notifications/win/notification_image_retainer.cc b/chrome/browser/notifications/win/notification_image_retainer.cc index ed18fa5a..6c25548 100644 --- a/chrome/browser/notifications/win/notification_image_retainer.cc +++ b/chrome/browser/notifications/win/notification_image_retainer.cc
@@ -45,7 +45,7 @@ // excluding those present in |registered_names|. std::vector<base::FilePath> GetFilesFromPrevSessions( const base::FilePath& dir, - const std::set<base::string16>& registered_names) { + const std::set<base::FilePath>& registered_names) { // |dir| may have sub-dirs, created by the old implementation. base::FileEnumerator file_enumerator( dir, /*recursive=*/false, @@ -56,7 +56,7 @@ for (base::FilePath current = file_enumerator.Next(); !current.empty(); current = file_enumerator.Next()) { // Exclude any new file created in this session. - if (!base::ContainsKey(registered_names, current.BaseName().value())) + if (!base::ContainsKey(registered_names, current.BaseName())) files.push_back(std::move(current)); } @@ -103,7 +103,7 @@ // Store all file names from registered_images in an ordered set for quick // search. - std::set<base::string16> registered_names; + std::set<base::FilePath> registered_names; for (const auto& pair : registered_images_) registered_names.insert(pair.first); @@ -138,7 +138,7 @@ const base::TimeTicks now = tick_clock_->NowTicks(); DCHECK(registered_images_.empty() || now >= registered_images_.back().second); - registered_images_.emplace_back(temp_file.BaseName().value(), now); + registered_images_.emplace_back(temp_file.BaseName(), now); // At this point, a temp file is already created. We need to clean it up even // if it fails to write the image data to this file. @@ -173,7 +173,7 @@ const base::TimeTicks then = tick_clock_->NowTicks() - kDeletionDelay; const auto end = std::upper_bound(registered_images_.begin(), registered_images_.end(), - std::make_pair(base::string16(), then), + std::make_pair(base::FilePath(), then), [](const NameAndTime& a, const NameAndTime& b) { return a.second < b.second; });
diff --git a/chrome/browser/notifications/win/notification_image_retainer.h b/chrome/browser/notifications/win/notification_image_retainer.h index 645f4af..c1c8f17 100644 --- a/chrome/browser/notifications/win/notification_image_retainer.h +++ b/chrome/browser/notifications/win/notification_image_retainer.h
@@ -15,7 +15,6 @@ #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/sequenced_task_runner.h" -#include "base/strings/string16.h" #include "base/time/tick_clock.h" #include "base/time/time.h" #include "base/timer/timer.h" @@ -61,18 +60,19 @@ const base::FilePath& image_dir() { return image_dir_; } private: - using NameAndTime = std::pair<base::string16, base::TimeTicks>; + using NameAndTime = std::pair<base::FilePath, base::TimeTicks>; using NamesAndTimes = std::vector<NameAndTime>; // Deletes expired (older than a pre-defined threshold) files. void DeleteExpiredFiles(); - // A collection of names to registered image files in image_dir_, each of - // which must stay valid for a short time while the Notification Center - // processes them. Each file has a corresponding registration timestamp. Files - // in this collection that have outlived the required minimum lifespan are - // scheduled for deletion periodically by |deletion_timer_|. The items in this - // collection are sorted by increasing registration time. + // A collection of names (note: not full paths) to registered image files + // in image_dir_, each of which must stay valid for a short time while the + // Notification Center processes them. Each file has a corresponding + // registration timestamp. Files in this collection that have outlived the + // required minimum lifespan are scheduled for deletion periodically by + // |deletion_timer_|. The items in this collection are sorted by increasing + // registration time. NamesAndTimes registered_images_; // The task runner used to handle file deletion.
diff --git a/chrome/browser/offline_pages/offline_page_auto_fetcher_unittest.cc b/chrome/browser/offline_pages/offline_page_auto_fetcher_unittest.cc index ec3a501..110190e 100644 --- a/chrome/browser/offline_pages/offline_page_auto_fetcher_unittest.cc +++ b/chrome/browser/offline_pages/offline_page_auto_fetcher_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/offline_pages/offline_page_auto_fetcher.h" +#include "base/bind.h" #include "base/test/bind_test_util.h" #include "base/test/mock_callback.h" #include "chrome/browser/offline_pages/request_coordinator_factory.h" @@ -25,7 +26,7 @@ void SetUp() override { RequestCoordinator* coordinator = static_cast<RequestCoordinator*>( RequestCoordinatorFactory::GetInstance()->SetTestingFactoryAndUse( - &profile_, BuildTestRequestCoordinator)); + &profile_, base::BindRepeating(&BuildTestRequestCoordinator))); queue_store_ = static_cast<TestRequestQueueStore*>( coordinator->queue_for_testing()->GetStoreForTesting()); }
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service.cc b/chrome/browser/policy/cloud/user_policy_signin_service.cc index af04c43..ee49ef3 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service.cc +++ b/chrome/browser/policy/cloud/user_policy_signin_service.cc
@@ -13,13 +13,11 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_util.h" #include "components/account_id/account_id.h" #include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h" #include "components/policy/core/common/cloud/user_cloud_policy_manager.h" #include "components/signin/core/browser/account_info.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_source.h" #include "content/public/browser/storage_partition.h" @@ -34,21 +32,18 @@ DeviceManagementService* device_management_service, UserCloudPolicyManager* policy_manager, identity::IdentityManager* identity_manager, - scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory, - ProfileOAuth2TokenService* token_service) + scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory) : UserPolicySigninServiceBase(profile, local_state, device_management_service, policy_manager, identity_manager, system_url_loader_factory), - profile_(profile), - oauth2_token_service_(token_service) { - // ProfileOAuth2TokenService should not yet have loaded its tokens since this + profile_(profile) { + // IdentityManager should not yet have loaded its tokens since this // happens in the background after PKS initialization - so this service // should always be created before the oauth token is available. - DCHECK(!oauth2_token_service_->RefreshTokenIsAvailable( - identity_manager->GetPrimaryAccountId())); + DCHECK(!identity_manager->HasPrimaryAccountWithRefreshToken()); } UserPolicySigninService::~UserPolicySigninService() { @@ -116,7 +111,7 @@ policy_client.get(), enterprise_management::DeviceRegisterRequest::BROWSER); registration_helper_->StartRegistration( - oauth2_token_service_, account_id, + identity_manager(), account_id, base::Bind(&UserPolicySigninService::CallPolicyRegistrationCallback, base::Unretained(this), base::Passed(&policy_client), callback)); @@ -131,7 +126,7 @@ void UserPolicySigninService::OnPrimaryAccountSet( const AccountInfo& account_info) { - if (!oauth2_token_service_->RefreshTokenIsAvailable(account_info.account_id)) + if (!identity_manager()->HasAccountWithRefreshToken(account_info.account_id)) return; // ProfileOAuth2TokenService now has a refresh token for the primary account @@ -142,7 +137,7 @@ void UserPolicySigninService::OnRefreshTokenUpdatedForAccount( const AccountInfo& account_info, bool is_valid) { - // Ignore invalid OAuth tokens or those for any account but the primary one. + // Ignore OAuth tokens or those for any account but the primary one. if (account_info.account_id != identity_manager()->GetPrimaryAccountId()) return; @@ -195,9 +190,8 @@ DVLOG_IF(1, manager->IsClientRegistered()) << "Client already registered - not fetching DMToken"; if (!manager->IsClientRegistered()) { - if (!oauth2_token_service_->RefreshTokenIsAvailable( - identity_manager()->GetPrimaryAccountId())) { - // No token yet - this class listens for OnRefreshTokenAvailable() + if (!identity_manager()->HasPrimaryAccountWithRefreshToken()) { + // No token yet - this class listens for OnRefreshTokenUpdatedForAccount() // and will re-attempt registration once the token is available. DLOG(WARNING) << "No OAuth Refresh Token - delaying policy download"; return; @@ -221,7 +215,7 @@ policy_manager()->core()->client(), enterprise_management::DeviceRegisterRequest::BROWSER)); registration_helper_->StartRegistration( - oauth2_token_service_, identity_manager()->GetPrimaryAccountId(), + identity_manager(), identity_manager()->GetPrimaryAccountId(), base::Bind(&UserPolicySigninService::OnRegistrationComplete, base::Unretained(this))); }
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service.h b/chrome/browser/policy/cloud/user_policy_signin_service.h index 63afb6b5..ae27dcb5 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service.h +++ b/chrome/browser/policy/cloud/user_policy_signin_service.h
@@ -16,7 +16,6 @@ class AccountId; class Profile; -class ProfileOAuth2TokenService; namespace network { class SharedURLLoaderFactory; @@ -38,8 +37,7 @@ DeviceManagementService* device_management_service, UserCloudPolicyManager* policy_manager, identity::IdentityManager* identity_manager, - scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory, - ProfileOAuth2TokenService* oauth2_token_service); + scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory); ~UserPolicySigninService() override; // Registers a CloudPolicyClient for fetching policy for a user. The @@ -107,10 +105,6 @@ std::unique_ptr<CloudPolicyClientRegistrationHelper> registration_helper_; - // Weak pointer to the token service we use to authenticate during - // CloudPolicyClient registration. - ProfileOAuth2TokenService* oauth2_token_service_; - DISALLOW_COPY_AND_ASSIGN(UserPolicySigninService); };
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc b/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc index 7259e11..57d5d7c 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc +++ b/chrome/browser/policy/cloud/user_policy_signin_service_factory.cc
@@ -12,7 +12,6 @@ #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/common/pref_names.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/policy/core/browser/browser_policy_connector.h" @@ -40,7 +39,6 @@ : BrowserContextKeyedServiceFactory( "UserPolicySigninService", BrowserContextDependencyManager::GetInstance()) { - DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); DependsOn(IdentityManagerFactory::GetInstance()); DependsOn(UserCloudPolicyManagerFactory::GetInstance()); } @@ -78,8 +76,7 @@ profile, g_browser_process->local_state(), device_management_service, UserCloudPolicyManagerFactory::GetForBrowserContext(context), IdentityManagerFactory::GetForProfile(profile), - g_browser_process->shared_url_loader_factory(), - ProfileOAuth2TokenServiceFactory::GetForProfile(profile)); + g_browser_process->shared_url_loader_factory()); return service; }
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc index f3182fc..dcb1998 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc +++ b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.cc
@@ -14,14 +14,12 @@ #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/common/pref_names.h" #include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h" #include "components/policy/core/common/cloud/user_cloud_policy_manager.h" #include "components/policy/core/common/policy_switches.h" #include "components/policy/proto/device_management_backend.pb.h" #include "components/prefs/pref_service.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "net/base/network_change_notifier.h" #include "net/url_request/url_request_context_getter.h" #include "services/identity/public/cpp/identity_manager.h" @@ -48,15 +46,13 @@ DeviceManagementService* device_management_service, UserCloudPolicyManager* policy_manager, identity::IdentityManager* identity_manager, - scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory, - ProfileOAuth2TokenService* token_service) + scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory) : UserPolicySigninServiceBase(profile, local_state, device_management_service, policy_manager, identity_manager, system_url_loader_factory), - oauth2_token_service_(token_service), profile_prefs_(profile->GetPrefs()), weak_factory_(this) {} @@ -92,7 +88,7 @@ auto registration_callback = base::Bind( &UserPolicySigninService::CallPolicyRegistrationCallback, base::Unretained(this), base::Passed(&policy_client), callback); - registration_helper_->StartRegistration(oauth2_token_service_, account_id, + registration_helper_->StartRegistration(identity_manager(), account_id, registration_callback); } @@ -164,7 +160,7 @@ policy_manager()->core()->client(), kCloudPolicyRegistrationType)); registration_helper_->StartRegistration( - oauth2_token_service_, identity_manager()->GetPrimaryAccountId(), + identity_manager(), identity_manager()->GetPrimaryAccountId(), base::Bind(&UserPolicySigninService::OnRegistrationDone, base::Unretained(this))); }
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h index d1046815..5abaf58b 100644 --- a/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h +++ b/chrome/browser/policy/cloud/user_policy_signin_service_mobile.h
@@ -16,7 +16,6 @@ #include "build/build_config.h" #include "chrome/browser/policy/cloud/user_policy_signin_service_base.h" -class ProfileOAuth2TokenService; class Profile; namespace identity { @@ -41,8 +40,7 @@ DeviceManagementService* device_management_service, UserCloudPolicyManager* policy_manager, identity::IdentityManager* identity_manager, - scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory, - ProfileOAuth2TokenService* token_service); + scoped_refptr<network::SharedURLLoaderFactory> system_url_loader_factory); ~UserPolicySigninService() override; // Registers a CloudPolicyClient for fetching policy for |username|. @@ -86,10 +84,6 @@ std::unique_ptr<CloudPolicyClientRegistrationHelper> registration_helper_; - // Weak pointer to the token service used to authenticate the - // CloudPolicyClient during registration. - ProfileOAuth2TokenService* oauth2_token_service_; - // The PrefService associated with the profile. PrefService* profile_prefs_;
diff --git a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc index 5627e82..bc7e6e5 100644 --- a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc +++ b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
@@ -74,7 +74,10 @@ const char kPrefetchMetaCSP[] = "/prerender/prefetch_meta_csp.html"; const char kPrefetchPage[] = "/prerender/prefetch_page.html"; const char kPrefetchPage2[] = "/prerender/prefetch_page2.html"; +const char kPrefetchPageBigger[] = "/prerender/prefetch_page_bigger.html"; const char kPrefetchPng[] = "/prerender/image.png"; +const char kPrefetchPng2[] = "/prerender/image2.png"; +const char kPrefetchPngRedirect[] = "/prerender/image-redirect.png"; const char kPrefetchResponseHeaderCSP[] = "/prerender/prefetch_response_csp.html"; const char kPrefetchScript[] = "/prerender/prefetch.js"; @@ -203,6 +206,37 @@ WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0); } +// Checks that prefetching is not stopped forever by aggressive background load +// limits. +IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, PrefetchBigger) { + std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile( + kPrefetchPageBigger, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); + + WaitForRequestCount(src_server()->GetURL(kPrefetchPageBigger), 1); + WaitForRequestCount(src_server()->GetURL(kPrefetchJpeg), 1); + // The |kPrefetchPng| is requested twice because the |kPrefetchPngRedirect| + // redirects to it. + WaitForRequestCount(src_server()->GetURL(kPrefetchPng), 2); + WaitForRequestCount(src_server()->GetURL(kPrefetchPng2), 1); + WaitForRequestCount(src_server()->GetURL(kPrefetchPngRedirect), 1); +} + +// Checks that a page load following a prefetch reuses preload-scanned +// resources from cache without failing over to network. +IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, LoadAfterPrefetch) { + { + std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile( + kPrefetchPageBigger, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); + WaitForRequestCount(src_server()->GetURL(kPrefetchJpeg), 1); + WaitForRequestCount(src_server()->GetURL(kPrefetchPng2), 1); + } + ui_test_utils::NavigateToURL(current_browser(), + src_server()->GetURL(kPrefetchPageBigger)); + // Check that the request counts did not increase. + WaitForRequestCount(src_server()->GetURL(kPrefetchJpeg), 1); + WaitForRequestCount(src_server()->GetURL(kPrefetchPng2), 1); +} + void GetCookieCallback(base::RepeatingClosure callback, const net::CookieList& cookie_list) { bool found_chocolate = false;
diff --git a/chrome/browser/signin/force_signin_verifier_unittest.cc b/chrome/browser/signin/force_signin_verifier_unittest.cc index 578e6aca..a74e8610 100644 --- a/chrome/browser/signin/force_signin_verifier_unittest.cc +++ b/chrome/browser/signin/force_signin_verifier_unittest.cc
@@ -39,10 +39,12 @@ public: void SetUp() override { TestingProfile::Builder builder; - builder.AddTestingFactory(SigninManagerFactory::GetInstance(), - BuildFakeSigninManagerForTesting); - builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(), - BuildFakeProfileOAuth2TokenService); + builder.AddTestingFactory( + SigninManagerFactory::GetInstance(), + base::BindRepeating(&BuildFakeSigninManagerForTesting)); + builder.AddTestingFactory( + ProfileOAuth2TokenServiceFactory::GetInstance(), + base::BindRepeating(&BuildFakeProfileOAuth2TokenService)); profile_ = builder.Build(); FakeSigninManager* signin_manager_ = static_cast<FakeSigninManager*>( SigninManagerFactory::GetForProfile(profile_.get()));
diff --git a/chrome/browser/tracing/background_tracing_field_trial.cc b/chrome/browser/tracing/background_tracing_field_trial.cc index 2bba058..ba82d227 100644 --- a/chrome/browser/tracing/background_tracing_field_trial.cc +++ b/chrome/browser/tracing/background_tracing_field_trial.cc
@@ -7,12 +7,17 @@ #include <string> #include <utility> +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/json/json_reader.h" #include "base/metrics/field_trial.h" #include "base/trace_event/trace_log.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/tracing/crash_service_uploader.h" +#include "chrome/common/chrome_switches.h" +#include "components/tracing/common/tracing_switches.h" #include "components/variations/variations_associated_data.h" #include "content/public/browser/background_tracing_config.h" #include "content/public/browser/background_tracing_manager.h" @@ -89,6 +94,33 @@ return content::BackgroundTracingConfig::FromDict(dict); } +void SetupBackgroundTracingFromConfigFile(const base::FilePath& config_file, + const std::string& upload_url) { + std::string config_text; + if (upload_url.empty() || + !base::ReadFileToString(config_file, &config_text) || + config_text.empty()) { + return; + } + + std::unique_ptr<base::Value> value = base::JSONReader::Read(config_text); + if (!value) { + LOG(ERROR) << "Background tracing has incorrect config: " << config_text; + return; + } + + const base::DictionaryValue* dict = nullptr; + if (!value->GetAsDictionary(&dict)) + return; + + std::unique_ptr<content::BackgroundTracingConfig> config = + content::BackgroundTracingConfig::FromDict(dict); + content::BackgroundTracingManager::GetInstance()->SetActiveScenario( + std::move(config), + base::BindRepeating(&BackgroundTracingUploadCallback, upload_url), + content::BackgroundTracingManager::NO_DATA_FILTERING); +} + } // namespace void SetConfigTextFilterForTesting(ConfigTextFilterForTesting predicate) { @@ -96,6 +128,15 @@ } void SetupBackgroundTracingFieldTrial() { + auto* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kEnableBackgroundTracing) && + command_line->HasSwitch(switches::kTraceUploadURL)) { + tracing::SetupBackgroundTracingFromConfigFile( + command_line->GetSwitchValuePath(switches::kEnableBackgroundTracing), + command_line->GetSwitchValueASCII(switches::kTraceUploadURL)); + return; + } + std::unique_ptr<content::BackgroundTracingConfig> config = GetBackgroundTracingConfig();
diff --git a/chrome/browser/tracing/background_tracing_field_trial_unittest.cc b/chrome/browser/tracing/background_tracing_field_trial_unittest.cc index d1f20a4..82361d11 100644 --- a/chrome/browser/tracing/background_tracing_field_trial_unittest.cc +++ b/chrome/browser/tracing/background_tracing_field_trial_unittest.cc
@@ -4,13 +4,17 @@ #include "chrome/browser/tracing/background_tracing_field_trial.h" +#include "base/files/file_util.h" #include "base/metrics/field_trial.h" #include "base/metrics/field_trial_params.h" +#include "base/test/scoped_command_line.h" #include "base/test/scoped_task_environment.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/tracing/common/trace_startup.h" #include "components/tracing/common/tracing_switches.h" +#include "content/public/browser/background_tracing_config.h" +#include "content/public/browser/background_tracing_manager.h" #include "content/public/test/test_browser_thread.h" #include "testing/gtest/include/gtest/gtest.h" @@ -23,6 +27,10 @@ base::ThreadTaskRunnerHandle::Get()) {} ~BackgroundTracingTest() override {} + void TearDown() override { + content::BackgroundTracingManager::GetInstance()->AbortScenario(); + } + private: base::test::ScopedTaskEnvironment scoped_task_environment_; content::TestBrowserThread ui_thread_; @@ -33,6 +41,23 @@ const char kTestConfig[] = "test"; bool g_test_config_loaded = false; +const char kUploadUrl[] = "http://localhost:8080"; +const char kInvalidTracingConfig[] = "{][}"; +const char kValidTracingConfig[] = R"( + { + "scenario_name": "BrowserProcess", + "configs": [ + { + "category": "BENCHMARK_NAVIGATION", + "rule": "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE", + "histogram_name": "Omnibox.CharTypedToRepaintLatency.ToPaint", + "histogram_lower_value": 1 + } + ], + "mode": "REACTIVE_TRACING_MODE" + } +)"; + void CheckConfig(std::string* config) { if (*config == kTestConfig) g_test_config_loaded = true; @@ -60,3 +85,65 @@ tracing::SetupBackgroundTracingFieldTrial(); EXPECT_TRUE(g_test_config_loaded); } + +TEST_F(BackgroundTracingTest, SetupBackgroundTracingFromConfigFileFailed) { + TestingProfileManager testing_profile_manager( + TestingBrowserProcess::GetGlobal()); + ASSERT_TRUE(testing_profile_manager.SetUp()); + ASSERT_FALSE( + content::BackgroundTracingManager::GetInstance()->HasActiveScenario()); + + base::test::ScopedCommandLine scoped_command_line; + base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine(); + command_line->AppendSwitchASCII(switches::kTraceUploadURL, kUploadUrl); + command_line->AppendSwitchASCII(switches::kEnableBackgroundTracing, ""); + + tracing::SetupBackgroundTracingFieldTrial(); + EXPECT_FALSE( + content::BackgroundTracingManager::GetInstance()->HasActiveScenario()); +} + +TEST_F(BackgroundTracingTest, + SetupBackgroundTracingFromConfigFileInvalidConfig) { + TestingProfileManager testing_profile_manager( + TestingBrowserProcess::GetGlobal()); + ASSERT_TRUE(testing_profile_manager.SetUp()); + ASSERT_FALSE( + content::BackgroundTracingManager::GetInstance()->HasActiveScenario()); + + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + base::FilePath file_path = temp_dir.GetPath().AppendASCII("config.json"); + base::WriteFile(file_path, kInvalidTracingConfig, + sizeof(kInvalidTracingConfig) - 1); + + base::test::ScopedCommandLine scoped_command_line; + base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine(); + command_line->AppendSwitchASCII(switches::kTraceUploadURL, kUploadUrl); + command_line->AppendSwitchPath(switches::kEnableBackgroundTracing, file_path); + + tracing::SetupBackgroundTracingFieldTrial(); + EXPECT_FALSE( + content::BackgroundTracingManager::GetInstance()->HasActiveScenario()); +} + +TEST_F(BackgroundTracingTest, SetupBackgroundTracingFromConfigFile) { + TestingProfileManager testing_profile_manager( + TestingBrowserProcess::GetGlobal()); + ASSERT_TRUE(testing_profile_manager.SetUp()); + + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + base::FilePath file_path = temp_dir.GetPath().AppendASCII("config.json"); + base::WriteFile(file_path, kValidTracingConfig, + sizeof(kValidTracingConfig) - 1); + + base::test::ScopedCommandLine scoped_command_line; + base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine(); + command_line->AppendSwitchASCII(switches::kTraceUploadURL, kUploadUrl); + command_line->AppendSwitchPath(switches::kEnableBackgroundTracing, file_path); + + tracing::SetupBackgroundTracingFieldTrial(); + EXPECT_TRUE( + content::BackgroundTracingManager::GetInstance()->HasActiveScenario()); +}
diff --git a/chrome/browser/tracing/chrome_tracing_delegate.cc b/chrome/browser/tracing/chrome_tracing_delegate.cc index 2f4141f..eec27fb 100644 --- a/chrome/browser/tracing/chrome_tracing_delegate.cc +++ b/chrome/browser/tracing/chrome_tracing_delegate.cc
@@ -8,6 +8,7 @@ #include <utility> #include <vector> +#include "base/command_line.h" #include "base/strings/string_piece.h" #include "base/time/time.h" #include "base/values.h" @@ -24,6 +25,7 @@ #include "components/metrics/metrics_pref_names.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" +#include "components/tracing/common/tracing_switches.h" #include "components/variations/active_field_trials.h" #include "components/version_info/version_info.h" #include "content/public/browser/background_tracing_config.h" @@ -103,6 +105,14 @@ bool ProfileAllowsScenario(const content::BackgroundTracingConfig& config, PermitMissingProfile profile_permission) { + // If the background tracing is specified on the command-line, we allow + // any scenario to be traced. + auto* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kEnableBackgroundTracing) && + command_line->HasSwitch(switches::kTraceUploadURL)) { + return true; + } + // If the profile hasn't loaded or been created yet, we allow the scenario // to start up, but not be finalized. Profile* profile = GetProfile();
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 1ff39b21..7aeed97a 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -2369,6 +2369,8 @@ "views/autofill/local_card_migration_dialog_view.h", "views/autofill/local_card_migration_icon_view.cc", "views/autofill/local_card_migration_icon_view.h", + "views/autofill/local_card_migration_offer_view.cc", + "views/autofill/local_card_migration_offer_view.h", "views/autofill/migratable_card_view.cc", "views/autofill/migratable_card_view.h", "views/autofill/save_card_bubble_views.cc",
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcut_search_result.cc b/chrome/browser/ui/app_list/search/arc/arc_app_shortcut_search_result.cc index 051d677..6aed6ddf 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcut_search_result.cc +++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcut_search_result.cc
@@ -16,6 +16,8 @@ #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" #include "chrome/browser/ui/app_list/search/search_util.h" +#include "chrome/grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" namespace app_list { @@ -33,6 +35,7 @@ SetTitle(base::UTF8ToUTF16(data_->short_label)); set_id(kAppShortcutSearchPrefix + GetAppId() + "/" + data_->shortcut_id); SetDisplayType(ash::SearchResultDisplayType::kTile); + SetAccessibleName(ComputeAccessibleName()); const int icon_dimension = app_list::AppListConfig::instance().search_tile_icon_dimension(); @@ -71,4 +74,17 @@ return arc_prefs->GetAppIdByPackageName(data_->package_name.value()); } +base::string16 ArcAppShortcutSearchResult::ComputeAccessibleName() const { + const ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile_); + DCHECK(arc_prefs); + std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = + arc_prefs->GetApp(GetAppId()); + if (!app_info.get()) + return base::string16(); + + return l10n_util::GetStringFUTF16(IDS_APP_ACTION_SHORTCUT_ACCESSIBILITY_NAME, + base::UTF8ToUTF16(data_->short_label), + base::UTF8ToUTF16(app_info->name)); +} + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_shortcut_search_result.h b/chrome/browser/ui/app_list/search/arc/arc_app_shortcut_search_result.h index 1e89a5f0..1783891 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_app_shortcut_search_result.h +++ b/chrome/browser/ui/app_list/search/arc/arc_app_shortcut_search_result.h
@@ -43,6 +43,9 @@ // Gets app id of the app that publishes this app shortcut. std::string GetAppId() const; + // Gets accessible name for this app shortcut. + base::string16 ComputeAccessibleName() const; + arc::mojom::AppShortcutItemPtr data_; std::unique_ptr<arc::IconDecodeRequest> icon_decode_request_;
diff --git a/chrome/browser/ui/app_list/search/chrome_search_result.cc b/chrome/browser/ui/app_list/search/chrome_search_result.cc index d3faca5c..c9fa34b 100644 --- a/chrome/browser/ui/app_list/search/chrome_search_result.cc +++ b/chrome/browser/ui/app_list/search/chrome_search_result.cc
@@ -65,6 +65,13 @@ updater->SetSearchResultMetadata(id(), CloneMetadata()); } +void ChromeSearchResult::SetAccessibleName(const base::string16& name) { + metadata_->accessible_name = name; + AppListModelUpdater* updater = model_updater(); + if (updater) + updater->SetSearchResultMetadata(id(), CloneMetadata()); +} + void ChromeSearchResult::SetRating(float rating) { metadata_->rating = rating; AppListModelUpdater* updater = model_updater();
diff --git a/chrome/browser/ui/app_list/search/chrome_search_result.h b/chrome/browser/ui/app_list/search/chrome_search_result.h index cee15db..dfc575d 100644 --- a/chrome/browser/ui/app_list/search/chrome_search_result.h +++ b/chrome/browser/ui/app_list/search/chrome_search_result.h
@@ -65,6 +65,7 @@ void SetTitleTags(const Tags& tags); void SetDetails(const base::string16& details); void SetDetailsTags(const Tags& tags); + void SetAccessibleName(const base::string16& name); void SetRating(float rating); void SetFormattedPrice(const base::string16& formatted_price); void SetDisplayType(DisplayType display_type);
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index cb2b2af..cb6812d 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -821,8 +821,11 @@ }; bool BrowserCommandController::IsShowingMainUI() { - bool should_hide_ui = window() && window()->ShouldHideUIForFullscreen(); - return browser_->is_type_tabbed() && !should_hide_ui; + return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP); +} + +bool BrowserCommandController::IsShowingLocationBar() { + return browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR); } void BrowserCommandController::InitCommandState() { @@ -1155,6 +1158,8 @@ const bool is_fullscreen = window() && window()->IsFullscreen(); const bool show_main_ui = IsShowingMainUI(); + const bool show_location_bar = IsShowingLocationBar(); + const bool main_not_fullscreen = show_main_ui && !is_fullscreen; // Navigation commands @@ -1167,7 +1172,7 @@ // Focus various bits of UI command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui); - command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui); + command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_location_bar); command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui); command_updater_.UpdateCommandEnabled( IDC_FOCUS_MENU_BAR, main_not_fullscreen);
diff --git a/chrome/browser/ui/browser_command_controller.h b/chrome/browser/ui/browser_command_controller.h index 211d343..ec45cf4 100644 --- a/chrome/browser/ui/browser_command_controller.h +++ b/chrome/browser/ui/browser_command_controller.h
@@ -110,6 +110,10 @@ // functionality anywhere else. bool IsShowingMainUI(); + // Returns true if the location bar is shown or is currently hidden, but can + // be shown. Used for updating window command states only. + bool IsShowingLocationBar(); + // Initialize state for all browser commands. void InitCommandState();
diff --git a/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc b/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc index a259833..73bc5f0 100644 --- a/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc +++ b/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.cc
@@ -9,59 +9,24 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/autofill/local_card_migration_dialog_factory.h" #include "chrome/browser/ui/autofill/local_card_migration_dialog_state.h" -#include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/views/autofill/migratable_card_view.h" -#include "chrome/browser/ui/views/autofill/view_util.h" +#include "chrome/browser/ui/views/autofill/local_card_migration_offer_view.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" -#include "chrome/browser/ui/views/chrome_typography.h" -#include "chrome/common/url_constants.h" -#include "components/autofill/core/browser/legal_message_line.h" #include "components/autofill/core/browser/local_card_migration_manager.h" #include "components/autofill/core/browser/ui/local_card_migration_dialog_controller.h" -#include "components/autofill/core/common/autofill_features.h" #include "components/constrained_window/constrained_window_views.h" -#include "components/grit/components_scaled_resources.h" #include "components/strings/grit/components_strings.h" #include "components/web_modal/web_contents_modal_dialog_host.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" -#include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/color_palette.h" -#include "ui/gfx/geometry/insets.h" -#include "ui/gfx/geometry/safe_integer_conversions.h" -#include "ui/gfx/paint_vector_icon.h" -#include "ui/native_theme/native_theme.h" -#include "ui/views/background.h" -#include "ui/views/border.h" #include "ui/views/controls/button/checkbox.h" #include "ui/views/controls/image_view.h" -#include "ui/views/controls/label.h" -#include "ui/views/controls/link.h" -#include "ui/views/controls/scroll_view.h" -#include "ui/views/controls/separator.h" -#include "ui/views/controls/styled_label.h" -#include "ui/views/controls/textfield/textfield.h" -#include "ui/views/controls/throbber.h" -#include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" -#include "ui/views/layout/grid_layout.h" -#include "ui/views/style/typography.h" #include "ui/views/widget/widget.h" #include "ui/views/window/dialog_client_view.h" namespace autofill { -namespace { - -MigratableCardView* AsMigratableCardView(views::View* view) { - DCHECK_EQ(MigratableCardView::kViewClassName, view->GetClassName()); - return static_cast<MigratableCardView*>(view); -} - -} // namespace - LocalCardMigrationDialogView::LocalCardMigrationDialogView( LocalCardMigrationDialogController* controller, content::WebContents* web_contents) @@ -82,18 +47,6 @@ // TODO(crbug/867194): Add feedback and tip value prompt. } -const std::vector<std::string> -LocalCardMigrationDialogView::GetSelectedCardGuids() const { - std::vector<std::string> selected_cards; - for (int index = 0; index < card_list_view_->child_count(); ++index) { - MigratableCardView* card = - AsMigratableCardView(card_list_view_->child_at(index)); - if (card->IsSelected()) - selected_cards.push_back(card->GetGuid()); - } - return selected_cards; -} - gfx::Size LocalCardMigrationDialogView::CalculatePreferredSize() const { const int width = ChromeLayoutProvider::Get()->GetDistanceMetric( DISTANCE_LARGE_MODAL_DIALOG_PREFERRED_WIDTH) - @@ -121,19 +74,22 @@ : GetCancelButtonLabel(); } +// TODO(crbug.com/867194): Update this method when adding feedback. bool LocalCardMigrationDialogView::IsDialogButtonEnabled( ui::DialogButton button) const { // If all checkboxes are unchecked, disable the save button. - if (button == ui::DIALOG_BUTTON_OK) - return !GetSelectedCardGuids().empty(); - + if (button == ui::DIALOG_BUTTON_OK) { + DCHECK(offer_view_); + return !offer_view_->GetSelectedCardGuids().empty(); + } return true; } bool LocalCardMigrationDialogView::Accept() { switch (controller_->GetViewState()) { case LocalCardMigrationDialogState::kOffered: - controller_->OnSaveButtonClicked(GetSelectedCardGuids()); + DCHECK(offer_view_); + controller_->OnSaveButtonClicked(offer_view_->GetSelectedCardGuids()); return true; case LocalCardMigrationDialogState::kFinished: case LocalCardMigrationDialogState::kActionRequired: @@ -161,152 +117,20 @@ // TODO(crbug/867194): Add button pressed logic for kDeleteCardButtonTag. void LocalCardMigrationDialogView::ButtonPressed(views::Button* sender, const ui::Event& event) { - // The button clicked is a checkbox just clicked. Enable/disable the save + // The button clicked is a checkbox. Enable/disable the save // button if needed. DCHECK_EQ(sender->GetClassName(), views::Checkbox::kViewClassName); DialogModelChanged(); } -void LocalCardMigrationDialogView::StyledLabelLinkClicked( - views::StyledLabel* label, - const gfx::Range& range, - int event_flags) { - if (!controller_) - return; - - controller_->OnLegalMessageLinkClicked(); - // TODO(crbug.com/867194): Should be controller's responsibility to open - // links. - legal_message_container_->OnLinkClicked(label, range, web_contents_); -} - void LocalCardMigrationDialogView::Init() { if (has_children()) return; - ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + SetLayoutManager(std::make_unique<views::FillLayout>()); - - // Set up main contents container. - std::unique_ptr<views::View> main_container = std::make_unique<views::View>(); - constexpr int kMainContainerChildSpacing = 24; - main_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), kMainContainerChildSpacing)); - - std::unique_ptr<views::View> image_container = - std::make_unique<views::View>(); - image_container->SetLayoutManager( - std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); - constexpr int kImageBorderBottom = 8; - image_container->SetBorder( - views::CreateEmptyBorder(0, 0, kImageBorderBottom, 0)); - std::unique_ptr<views::ImageView> image = - std::make_unique<views::ImageView>(); - image->SetImage(rb.GetImageSkiaNamed(GetHeaderImageId())); - image->SetAccessibleName( - l10n_util::GetStringUTF16(IDS_AUTOFILL_GOOGLE_PAY_LOGO_ACCESSIBLE_NAME)); - image_container->AddChildView(image.release()); - main_container->AddChildView(image_container.release()); - - title_ = new views::Label(GetDialogTitle()); - constexpr int kMigrationDialogTitleFontSize = 8; - title_->SetFontList(gfx::FontList().Derive(kMigrationDialogTitleFontSize, - gfx::Font::NORMAL, - gfx::Font::Weight::MEDIUM)); - title_->SetEnabledColor(gfx::kGoogleGrey900); - constexpr int kMigrationDialogTitleLineHeight = 20; - title_->SetLineHeight(kMigrationDialogTitleLineHeight); - main_container->AddChildView(title_); - - std::unique_ptr<views::View> contents_container = - std::make_unique<views::View>(); - contents_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), - provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); - constexpr int kMigrationDialogInsets = 24; - gfx::Insets migration_dialog_insets = gfx::Insets(0, kMigrationDialogInsets); - contents_container->SetBorder( - views::CreateEmptyBorder(migration_dialog_insets)); - - explanation_text_ = - new views::Label(GetDialogInstruction(), CONTEXT_BODY_TEXT_LARGE, - ChromeTextStyle::STYLE_SECONDARY); - explanation_text_->SetMultiLine(true); - explanation_text_->SetHorizontalAlignment(gfx::ALIGN_LEFT); - contents_container->AddChildView(explanation_text_); - - card_list_view_ = new views::View(); - const std::vector<MigratableCreditCard>& migratable_credit_cards = - controller_->GetCardList(); - views::BoxLayout* card_list_view_layout_ = - card_list_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), - provider->GetDistanceMetric( - views::DISTANCE_RELATED_CONTROL_VERTICAL))); - card_list_view_layout_->set_main_axis_alignment( - views::BoxLayout::MAIN_AXIS_ALIGNMENT_START); - for (size_t index = 0; index < migratable_credit_cards.size(); index++) { - card_list_view_->AddChildView( - new MigratableCardView(migratable_credit_cards[index], this, - migratable_credit_cards.size() != 1)); - } - - std::unique_ptr<views::ScrollView> card_list_scroll_bar = - std::make_unique<views::ScrollView>(); - card_list_scroll_bar->set_hide_horizontal_scrollbar(true); - card_list_scroll_bar->SetContents(card_list_view_); - card_list_scroll_bar->set_draw_overflow_indicator(false); - constexpr int kCardListScrollViewHeight = 140; - card_list_scroll_bar->ClipHeightTo(0, kCardListScrollViewHeight); - contents_container->AddChildView(card_list_scroll_bar.release()); - main_container->AddChildView(contents_container.release()); - - separator_ = new views::Separator(); - main_container->AddChildView(separator_); - - legal_message_container_ = - new LegalMessageView(controller_->GetLegalMessageLines(), this); - constexpr int kContentBottomMargin = 48; - legal_message_container_->SetBorder(views::CreateEmptyBorder( - 0, migration_dialog_insets.left(), kContentBottomMargin, - migration_dialog_insets.right())); - main_container->AddChildView(legal_message_container_); - - AddChildView(main_container.release()); -} - -base::string16 LocalCardMigrationDialogView::GetDialogTitle() const { - switch (controller_->GetViewState()) { - case LocalCardMigrationDialogState::kOffered: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_OFFER); - case LocalCardMigrationDialogState::kFinished: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_DONE); - case LocalCardMigrationDialogState::kActionRequired: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_FIX); - } -} - -base::string16 LocalCardMigrationDialogView::GetDialogInstruction() const { - switch (controller_->GetViewState()) { - case LocalCardMigrationDialogState::kOffered: - return l10n_util::GetPluralStringFUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_OFFER, - controller_->GetCardList().size()); - case LocalCardMigrationDialogState::kFinished: - return l10n_util::GetPluralStringFUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_DONE, - controller_->GetCardList().size()); - case LocalCardMigrationDialogState::kActionRequired: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_FIX); - } -} - -int LocalCardMigrationDialogView::GetHeaderImageId() const { - return IDR_AUTOFILL_MIGRATION_DIALOG_HEADER; + offer_view_ = + new LocalCardMigrationOfferView(controller_, this, web_contents_); + AddChildView(offer_view_); } base::string16 LocalCardMigrationDialogView::GetOkButtonLabel() const {
diff --git a/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.h b/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.h index 451e7bf..3d1af5a7 100644 --- a/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.h +++ b/chrome/browser/ui/views/autofill/local_card_migration_dialog_view.h
@@ -6,12 +6,9 @@ #define CHROME_BROWSER_UI_VIEWS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_VIEW_H_ #include "base/macros.h" -#include "base/timer/timer.h" #include "chrome/browser/ui/autofill/local_card_migration_dialog.h" #include "chrome/browser/ui/views/autofill/dialog_view_ids.h" -#include "chrome/browser/ui/views/autofill/view_util.h" #include "ui/views/controls/button/button.h" -#include "ui/views/controls/styled_label_listener.h" #include "ui/views/view.h" #include "ui/views/widget/widget_observer.h" #include "ui/views/window/dialog_delegate.h" @@ -20,19 +17,13 @@ class WebContents; } // namespace content -namespace views { -class Label; -class Separator; -} // namespace views - namespace autofill { class LocalCardMigrationDialogController; -class MigratableCardView; +class LocalCardMigrationOfferView; class LocalCardMigrationDialogView : public LocalCardMigrationDialog, public views::ButtonListener, - public views::StyledLabelListener, public views::DialogDelegateView, public views::WidgetObserver { public: @@ -61,37 +52,18 @@ // views::ButtonListener void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // views::StyledLabelListener: - void StyledLabelLinkClicked(views::StyledLabel* label, - const gfx::Range& range, - int event_flags) override; - private: void Init(); - base::string16 GetDialogTitle() const; - base::string16 GetDialogInstruction() const; - int GetHeaderImageId() const; base::string16 GetOkButtonLabel() const; base::string16 GetCancelButtonLabel() const; - const std::vector<std::string> GetSelectedCardGuids() const; LocalCardMigrationDialogController* controller_; content::WebContents* web_contents_; - views::Label* title_ = nullptr; - - views::Label* explanation_text_ = nullptr; - - // A list of MigratableCardView. - views::View* card_list_view_ = nullptr; - - // Separates the card scroll bar view and the legal message. - views::Separator* separator_ = nullptr; - - // The view that contains legal message and handles legal message links - // clicking. - LegalMessageView* legal_message_container_ = nullptr; + // Pointer points to the LocalCardMigrationOfferView. Can be null when the + // dialog is not in the 'offer' state. + LocalCardMigrationOfferView* offer_view_ = nullptr; DISALLOW_COPY_AND_ASSIGN(LocalCardMigrationDialogView); };
diff --git a/chrome/browser/ui/views/autofill/local_card_migration_offer_view.cc b/chrome/browser/ui/views/autofill/local_card_migration_offer_view.cc new file mode 100644 index 0000000..9ab5fe9 --- /dev/null +++ b/chrome/browser/ui/views/autofill/local_card_migration_offer_view.cc
@@ -0,0 +1,188 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/autofill/local_card_migration_offer_view.h" + +#include "base/location.h" +#include "base/macros.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/ui/autofill/local_card_migration_dialog_state.h" +#include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/views/autofill/migratable_card_view.h" +#include "chrome/browser/ui/views/autofill/view_util.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_typography.h" +#include "chrome/common/url_constants.h" +#include "components/autofill/core/browser/local_card_migration_manager.h" +#include "components/autofill/core/browser/ui/local_card_migration_dialog_controller.h" +#include "components/autofill/core/common/autofill_features.h" +#include "components/constrained_window/constrained_window_views.h" +#include "components/grit/components_scaled_resources.h" +#include "components/strings/grit/components_strings.h" +#include "components/web_modal/web_contents_modal_dialog_host.h" +#include "components/web_modal/web_contents_modal_dialog_manager.h" +#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/color_palette.h" +#include "ui/gfx/geometry/insets.h" +#include "ui/gfx/geometry/safe_integer_conversions.h" +#include "ui/views/background.h" +#include "ui/views/border.h" +#include "ui/views/controls/button/checkbox.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/controls/link.h" +#include "ui/views/controls/scroll_view.h" +#include "ui/views/controls/separator.h" +#include "ui/views/controls/styled_label.h" +#include "ui/views/controls/textfield/textfield.h" +#include "ui/views/layout/box_layout.h" +#include "ui/views/layout/fill_layout.h" +#include "ui/views/layout/grid_layout.h" +#include "ui/views/style/typography.h" + +namespace autofill { + +namespace { + +MigratableCardView* AsMigratableCardView(views::View* view) { + DCHECK_EQ(MigratableCardView::kViewClassName, view->GetClassName()); + return static_cast<MigratableCardView*>(view); +} + +} // namespace + +LocalCardMigrationOfferView::LocalCardMigrationOfferView( + LocalCardMigrationDialogController* controller, + views::ButtonListener* listener, + content::WebContents* web_contents) + : controller_(controller), web_contents_(web_contents) { + Init(listener); +} + +LocalCardMigrationOfferView::~LocalCardMigrationOfferView() {} + +void LocalCardMigrationOfferView::StyledLabelLinkClicked( + views::StyledLabel* label, + const gfx::Range& range, + int event_flags) { + if (!controller_) + return; + + controller_->OnLegalMessageLinkClicked(); + // TODO(crbug.com/867194): Should be controller's responsibility to open + // links. + legal_message_container_->OnLinkClicked(label, range, web_contents_); +} + +void LocalCardMigrationOfferView::Init(views::ButtonListener* listener) { + ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + // Set up main contents container. + constexpr int kMainContainerChildSpacing = 24; + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::kVertical, gfx::Insets(), kMainContainerChildSpacing)); + + // TODO(siyua@): Move image_container to LocalCardMigrationDialogView after + // introducing other feedback child views since it is shared between them. + std::unique_ptr<views::View> image_container = + std::make_unique<views::View>(); + image_container->SetLayoutManager( + std::make_unique<views::BoxLayout>(views::BoxLayout::kVertical)); + constexpr int kImageBorderBottom = 8; + image_container->SetBorder( + views::CreateEmptyBorder(0, 0, kImageBorderBottom, 0)); + std::unique_ptr<views::ImageView> image = + std::make_unique<views::ImageView>(); + image->SetImage(rb.GetImageSkiaNamed(IDR_AUTOFILL_MIGRATION_DIALOG_HEADER)); + image->SetAccessibleName( + l10n_util::GetStringUTF16(IDS_AUTOFILL_GOOGLE_PAY_LOGO_ACCESSIBLE_NAME)); + image_container->AddChildView(image.release()); + AddChildView(image_container.release()); + + // TODO(siyua@): Move title to LocalCardMigrationDialogView. + std::unique_ptr<views::Label> title = + std::make_unique<views::Label>(l10n_util::GetStringUTF16( + IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_OFFER)); + constexpr int kMigrationDialogTitleFontSize = 8; + title->SetFontList(gfx::FontList().Derive(kMigrationDialogTitleFontSize, + gfx::Font::NORMAL, + gfx::Font::Weight::MEDIUM)); + title->SetEnabledColor(gfx::kGoogleGrey900); + constexpr int kMigrationDialogTitleLineHeight = 20; + title->SetLineHeight(kMigrationDialogTitleLineHeight); + AddChildView(title.release()); + + std::unique_ptr<views::View> contents_container = + std::make_unique<views::View>(); + contents_container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::kVertical, gfx::Insets(), + provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); + constexpr int kMigrationDialogInsets = 24; + gfx::Insets migration_dialog_insets = gfx::Insets(0, kMigrationDialogInsets); + contents_container->SetBorder( + views::CreateEmptyBorder(migration_dialog_insets)); + + std::unique_ptr<views::Label> explanation_text = + std::make_unique<views::Label>( + l10n_util::GetPluralStringFUTF16( + IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_OFFER, + controller_->GetCardList().size()), + CONTEXT_BODY_TEXT_LARGE, ChromeTextStyle::STYLE_SECONDARY); + explanation_text->SetMultiLine(true); + explanation_text->SetHorizontalAlignment(gfx::ALIGN_LEFT); + contents_container->AddChildView(explanation_text.release()); + + card_list_view_ = new views::View(); + views::BoxLayout* card_list_view_layout = + card_list_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::kVertical, gfx::Insets(), + provider->GetDistanceMetric( + views::DISTANCE_RELATED_CONTROL_VERTICAL))); + card_list_view_layout->set_main_axis_alignment( + views::BoxLayout::MAIN_AXIS_ALIGNMENT_START); + const std::vector<MigratableCreditCard>& migratable_credit_cards = + controller_->GetCardList(); + for (size_t index = 0; index < migratable_credit_cards.size(); index++) { + card_list_view_->AddChildView( + new MigratableCardView(migratable_credit_cards[index], listener, + migratable_credit_cards.size() != 1)); + } + + std::unique_ptr<views::ScrollView> card_list_scroll_bar = + std::make_unique<views::ScrollView>(); + card_list_scroll_bar->set_hide_horizontal_scrollbar(true); + card_list_scroll_bar->SetContents(card_list_view_); + card_list_scroll_bar->set_draw_overflow_indicator(false); + constexpr int kCardListScrollViewHeight = 140; + card_list_scroll_bar->ClipHeightTo(0, kCardListScrollViewHeight); + contents_container->AddChildView(card_list_scroll_bar.release()); + AddChildView(contents_container.release()); + + AddChildView(new views::Separator()); + + legal_message_container_ = + new LegalMessageView(controller_->GetLegalMessageLines(), this); + constexpr int kContentBottomMargin = 48; + legal_message_container_->SetBorder(views::CreateEmptyBorder( + 0, migration_dialog_insets.left(), kContentBottomMargin, + migration_dialog_insets.right())); + AddChildView(legal_message_container_); +} + +const std::vector<std::string> +LocalCardMigrationOfferView::GetSelectedCardGuids() const { + std::vector<std::string> selected_cards; + for (int index = 0; index < card_list_view_->child_count(); ++index) { + MigratableCardView* card = + AsMigratableCardView(card_list_view_->child_at(index)); + if (card->IsSelected()) + selected_cards.push_back(card->GetGuid()); + } + return selected_cards; +} + +} // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/local_card_migration_offer_view.h b/chrome/browser/ui/views/autofill/local_card_migration_offer_view.h new file mode 100644 index 0000000..50a1098 --- /dev/null +++ b/chrome/browser/ui/views/autofill/local_card_migration_offer_view.h
@@ -0,0 +1,59 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_LOCAL_CARD_MIGRATION_OFFER_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_LOCAL_CARD_MIGRATION_OFFER_VIEW_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/views/autofill/view_util.h" +#include "ui/views/controls/button/button.h" +#include "ui/views/controls/styled_label_listener.h" + +namespace content { +class WebContents; +} // namespace content + +namespace autofill { + +class LocalCardMigrationDialogController; + +// A view composed of the main contents for local card migration dialog +// including title, explanatory message, migratable credit card list, +// horizontal separator, and legal message. It is used by +// LocalCardMigrationDialogView class when it offers the user the +// option to upload all browser-saved credit cards. +class LocalCardMigrationOfferView : public views::View, + public views::StyledLabelListener { + public: + LocalCardMigrationOfferView(LocalCardMigrationDialogController* controller, + views::ButtonListener* listener, + content::WebContents* web_contents); + ~LocalCardMigrationOfferView() override; + + // views::StyledLabelListener: + void StyledLabelLinkClicked(views::StyledLabel* label, + const gfx::Range& range, + int event_flags) override; + + const std::vector<std::string> GetSelectedCardGuids() const; + + private: + void Init(views::ButtonListener* listener); + + LocalCardMigrationDialogController* controller_; + + content::WebContents* web_contents_; + + views::View* card_list_view_ = nullptr; + + // The view that contains legal message and handles legal message links + // clicking. + LegalMessageView* legal_message_container_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(LocalCardMigrationOfferView); +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_LOCAL_CARD_MIGRATION_OFFER_VIEW_H_
diff --git a/chrome/browser/ui/webui/profile_info_watcher.cc b/chrome/browser/ui/webui/profile_info_watcher.cc index 422472e..a4f62d8 100644 --- a/chrome/browser/ui/webui/profile_info_watcher.cc +++ b/chrome/browser/ui/webui/profile_info_watcher.cc
@@ -9,11 +9,11 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" -#include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_pref_names.h" +#include "services/identity/public/cpp/identity_manager.h" ProfileInfoWatcher::ProfileInfoWatcher( Profile* profile, const base::Closure& callback) @@ -44,17 +44,17 @@ std::string ProfileInfoWatcher::GetAuthenticatedUsername() const { std::string username; - SigninManagerBase* signin_manager = GetSigninManager(); - if (signin_manager) - username = signin_manager->GetAuthenticatedAccountInfo().email; + auto* identity_manager = GetIdentityManager(); + if (identity_manager) + username = identity_manager->GetPrimaryAccountInfo().email; return username; } -SigninManagerBase* ProfileInfoWatcher::GetSigninManager() const { - return SigninManagerFactory::GetForProfile(profile_); +identity::IdentityManager* ProfileInfoWatcher::GetIdentityManager() const { + return IdentityManagerFactory::GetForProfile(profile_); } void ProfileInfoWatcher::RunCallback() { - if (GetSigninManager()) + if (GetIdentityManager()) callback_.Run(); }
diff --git a/chrome/browser/ui/webui/profile_info_watcher.h b/chrome/browser/ui/webui/profile_info_watcher.h index 114282d6..9849315 100644 --- a/chrome/browser/ui/webui/profile_info_watcher.h +++ b/chrome/browser/ui/webui/profile_info_watcher.h
@@ -13,7 +13,10 @@ #include "components/prefs/pref_member.h" class Profile; -class SigninManagerBase; + +namespace identity { +class IdentityManager; +} // Watches profiles for changes in their cached info (e.g. the authenticated // username changes). @@ -29,10 +32,10 @@ // ProfileAttributesStorage::Observer: void OnProfileAuthInfoChanged(const base::FilePath& profile_path) override; - // Gets the SigninManagerBase for |profile_|. - SigninManagerBase* GetSigninManager() const; + // Gets the IdentityManager for |profile_|. + identity::IdentityManager* GetIdentityManager() const; - // Runs |callback_| when a profile changes. No-ops if |GetSigninManager()| + // Runs |callback_| when a profile changes. No-ops if |GetIdentityManager()| // returns nullptr. void RunCallback();
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc index 0d5c6fa..01c56a49 100644 --- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc +++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
@@ -127,20 +127,17 @@ static std::unique_ptr<KeyedService> Build(content::BrowserContext* context) { Profile* profile = Profile::FromBrowserContext(context); return std::make_unique<FakeUserPolicySigninService>( - profile, IdentityManagerFactory::GetForProfile(profile), - ProfileOAuth2TokenServiceFactory::GetForProfile(profile)); + profile, IdentityManagerFactory::GetForProfile(profile)); } FakeUserPolicySigninService(Profile* profile, - identity::IdentityManager* identity_manager, - ProfileOAuth2TokenService* oauth2_token_service) + identity::IdentityManager* identity_manager) : UserPolicySigninService(profile, nullptr, nullptr, nullptr, identity_manager, - nullptr, - oauth2_token_service) {} + nullptr) {} void set_dm_token(const std::string& dm_token) { dm_token_ = dm_token; } void set_client_id(const std::string& client_id) { client_id_ = client_id; }
diff --git a/chrome/chrome_cleaner/components/BUILD.gn b/chrome/chrome_cleaner/components/BUILD.gn index 3a9bf1fb..1b81bd1 100644 --- a/chrome/chrome_cleaner/components/BUILD.gn +++ b/chrome/chrome_cleaner/components/BUILD.gn
@@ -2,18 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -source_set("crx_file") { - sources = [ - "crx_file.cc", - "crx_file.h", - ] - - deps = [ - "//base", - "//components/chrome_cleaner/public/constants:constants", - ] -} - source_set("components") { sources = [ "component_api.h", @@ -30,7 +18,6 @@ ] deps = [ - ":crx_file", "//base:base", "//chrome/chrome_cleaner/chrome_utils:chrome_util_lib", "//chrome/chrome_cleaner/chrome_utils:extensions_util_lib", @@ -46,6 +33,7 @@ "//chrome/chrome_cleaner/os:common_os", "//chrome/chrome_cleaner/pup_data:pup_data_base", "//components/chrome_cleaner/public/constants:constants", + "//components/crx_file", "//crypto:crypto", "//third_party/zlib/google:zip", "//url:url",
diff --git a/chrome/chrome_cleaner/components/DEPS b/chrome/chrome_cleaner/components/DEPS index 4394973..89d0873 100644 --- a/chrome/chrome_cleaner/components/DEPS +++ b/chrome/chrome_cleaner/components/DEPS
@@ -1,3 +1,4 @@ include_rules = [ + "+components/crx_file", "+third_party/zlib/google", ]
diff --git a/chrome/chrome_cleaner/components/component_unpacker.cc b/chrome/chrome_cleaner/components/component_unpacker.cc index 7989b63..1cd0531 100644 --- a/chrome/chrome_cleaner/components/component_unpacker.cc +++ b/chrome/chrome_cleaner/components/component_unpacker.cc
@@ -8,80 +8,11 @@ #include <memory> #include <vector> -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_file.h" -#include "base/logging.h" -#include "chrome/chrome_cleaner/components/crx_file.h" -#include "chrome/chrome_cleaner/os/file_path_sanitization.h" -#include "crypto/secure_hash.h" -#include "crypto/signature_verifier.h" +#include "components/crx_file/crx_verifier.h" #include "third_party/zlib/google/zip.h" -using crypto::SecureHash; - namespace chrome_cleaner { -namespace { - -// This class makes sure that the CRX digital signature is valid and well -// formed. -class CRXValidator { - public: - explicit CRXValidator(FILE* crx_file) : valid_(false) { - CrxFile::Header header; - size_t len = fread(&header, 1, sizeof(header), crx_file); - if (len < sizeof(header)) - return; - - CrxFile::Error error; - std::unique_ptr<CrxFile> crx(CrxFile::Parse(header, &error)); - if (!crx.get()) - return; - DCHECK(!CrxFile::HeaderIsDelta(header)); - - std::vector<uint8_t> key(header.key_size); - len = fread(&key[0], sizeof(uint8_t), header.key_size, crx_file); - if (len < header.key_size) - return; - - std::vector<uint8_t> signature(header.signature_size); - len = - fread(&signature[0], sizeof(uint8_t), header.signature_size, crx_file); - if (len < header.signature_size) - return; - - crypto::SignatureVerifier verifier; - if (!verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1, - signature, key)) { - // Signature verification initialization failed. This is most likely - // caused by a public key in the wrong format (should encode algorithm). - return; - } - - const size_t kBufSize = 8 * 1024; - std::vector<uint8_t> buf(kBufSize); - while ((len = fread(buf.data(), 1, kBufSize, crx_file)) > 0) - verifier.VerifyUpdate(buf); - - if (!verifier.VerifyFinal()) - return; - - public_key_.swap(key); - valid_ = true; - } - - bool valid() const { return valid_; } - - const std::vector<uint8_t>& public_key() const { return public_key_; } - - private: - bool valid_; - std::vector<uint8_t> public_key_; -}; - -} // namespace - ComponentUnpacker::ComponentUnpacker(const std::vector<uint8_t>& pk_hash, const base::FilePath& path) : pk_hash_(pk_hash), path_(path) {} @@ -91,30 +22,9 @@ } bool ComponentUnpacker::Verify() { - if (pk_hash_.empty() || path_.empty()) - return false; - // First, validate the CRX header and signature. As of today this is SHA1 with - // RSA 1024. - base::ScopedFILE file(base::OpenFile(path_, "rb")); - if (!file.get()) - return false; - CRXValidator validator(file.get()); - file.reset(); - if (!validator.valid()) - return false; - - // File is valid and the digital signature matches. Now make sure the public - // key hash matches the expected hash. If they do we fully trust this CRX. - uint8_t hash[32] = {}; - std::unique_ptr<SecureHash> sha256(SecureHash::Create(SecureHash::SHA256)); - sha256->Update(&(validator.public_key()[0]), validator.public_key().size()); - sha256->Finish(hash, base::size(hash)); - - if (!std::equal(pk_hash_.begin(), pk_hash_.end(), hash)) { - LOG(WARNING) << "Hash mismatch: " << SanitizePath(path_); - return false; - } - return true; + return crx_file::Verify(path_, crx_file::VerifierFormat::CRX2_OR_CRX3, + {pk_hash_}, std::vector<uint8_t>(), nullptr, + nullptr) == crx_file::VerifierResult::OK_FULL; } ComponentUnpacker::~ComponentUnpacker() {}
diff --git a/chrome/chrome_cleaner/components/crx_file.cc b/chrome/chrome_cleaner/components/crx_file.cc deleted file mode 100644 index abad50a..0000000 --- a/chrome/chrome_cleaner/components/crx_file.cc +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Stolen from extensions/common/crx_file.cc -// TODO(crbug.com/889575): The above file no longer exists. It's been -// refactored and now lives in components/crx_file. Should pull in that -// component directly. - -#include "chrome/chrome_cleaner/components/crx_file.h" - -#include "base/memory/ptr_util.h" - -namespace chrome_cleaner { - -namespace { - -// The current version of the crx format. -static const uint32_t kCurrentVersion = 2; - -// The current version of the crx diff format. -static const uint32_t kCurrentDiffVersion = 0; - -// The maximum size the crx parser will tolerate for a public key. -static const uint32_t kMaxPublicKeySize = 1 << 16; - -// The maximum size the crx parser will tolerate for a signature. -static const uint32_t kMaxSignatureSize = 1 << 16; - -} // namespace - -// The magic string embedded in the header. -const char kCrxFileHeaderMagic[] = "Cr24"; -const char kCrxDiffFileHeaderMagic[] = "CrOD"; - -std::unique_ptr<CrxFile> CrxFile::Parse(const CrxFile::Header& header, - CrxFile::Error* error) { - if (HeaderIsValid(header, error)) - return base::WrapUnique<CrxFile>(new CrxFile(header)); - return nullptr; -} - -std::unique_ptr<CrxFile> CrxFile::Create(const uint32_t key_size, - const uint32_t signature_size, - CrxFile::Error* error) { - CrxFile::Header header; - memcpy(&header.magic, kCrxFileHeaderMagic, kCrxFileHeaderMagicSize); - header.version = kCurrentVersion; - header.key_size = key_size; - header.signature_size = signature_size; - if (HeaderIsValid(header, error)) - return base::WrapUnique<CrxFile>(new CrxFile(header)); - return nullptr; -} - -CrxFile::CrxFile(const Header& header) : header_(header) {} - -bool CrxFile::HeaderIsDelta(const CrxFile::Header& header) { - return !strncmp(kCrxDiffFileHeaderMagic, header.magic, sizeof(header.magic)); -} - -bool CrxFile::HeaderIsValid(const CrxFile::Header& header, - CrxFile::Error* error) { - bool valid = false; - bool diffCrx = false; - if (!strncmp(kCrxDiffFileHeaderMagic, header.magic, sizeof(header.magic))) - diffCrx = true; - if (strncmp(kCrxFileHeaderMagic, header.magic, sizeof(header.magic)) && - !diffCrx) - *error = kWrongMagic; - else if (header.version != kCurrentVersion && - !(diffCrx && header.version == kCurrentDiffVersion)) - *error = kInvalidVersion; - else if (header.key_size > kMaxPublicKeySize) - *error = kInvalidKeyTooLarge; - else if (header.key_size == 0) - *error = kInvalidKeyTooSmall; - else if (header.signature_size > kMaxSignatureSize) - *error = kInvalidSignatureTooLarge; - else if (header.signature_size == 0) - *error = kInvalidSignatureTooSmall; - else - valid = true; - return valid; -} - -} // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/components/crx_file.h b/chrome/chrome_cleaner/components/crx_file.h deleted file mode 100644 index 363586ac..0000000 --- a/chrome/chrome_cleaner/components/crx_file.h +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// Stolen from extensions/common/crx_file.h - -#ifndef CHROME_CHROME_CLEANER_COMPONENTS_CRX_FILE_H_ -#define CHROME_CHROME_CLEANER_COMPONENTS_CRX_FILE_H_ - -#include <stdint.h> -#include <sys/types.h> - -#include <memory> - -namespace chrome_cleaner { - -// CRX files have a header that includes a magic key, version number, and -// some signature sizing information. Use CrxFile object to validate whether -// the header is valid or not. -class CrxFile { - public: - // The size of the magic character sequence at the beginning of each crx - // file, in bytes. This should be a multiple of 4. - static const size_t kCrxFileHeaderMagicSize = 4; - - // This header is the first data at the beginning of an extension. Its - // contents are purposely 32-bit aligned so that it can just be slurped into - // a struct without manual parsing. - struct Header { - char magic[kCrxFileHeaderMagicSize]; - uint32_t version; - uint32_t key_size; // The size of the public key, in bytes. - uint32_t signature_size; // The size of the signature, in bytes. - // An ASN.1-encoded PublicKeyInfo structure follows. - // The signature follows. - }; - - enum Error { - kWrongMagic, - kInvalidVersion, - kInvalidKeyTooLarge, - kInvalidKeyTooSmall, - kInvalidSignatureTooLarge, - kInvalidSignatureTooSmall, - }; - - // Construct a new CRX file header object with bytes of a header - // read from a CRX file. If a null std::unique_ptr is returned, |error| - // contains an error code with additional information. - static std::unique_ptr<CrxFile> Parse(const Header& header, Error* error); - - // Construct a new header for the given key and signature sizes. - // Returns a null std::unique_ptr if erroneous values of |key_size| and/or - // |signature_size| are provided. |error| contains an error code with - // additional information. - // Use this constructor and then .header() to obtain the Header - // for writing out to a CRX file. - static std::unique_ptr<CrxFile> Create(const uint32_t key_size, - const uint32_t signature_size, - Error* error); - - // Returns the header structure for writing out to a CRX file. - const Header& header() const { return header_; } - - // Checks a valid |header| to determine whether or not the CRX represents a - // differential CRX. - static bool HeaderIsDelta(const Header& header); - - private: - Header header_; - - // Constructor is private. Clients should use static factory methods above. - explicit CrxFile(const Header& header); - - // Checks the |header| for validity and returns true if the values are valid. - // If false is returned, more detailed error code is returned in |error|. - static bool HeaderIsValid(const Header& header, Error* error); -}; - -} // namespace chrome_cleaner - -#endif // CHROME_CHROME_CLEANER_COMPONENTS_CRX_FILE_H_
diff --git a/chrome/common/apps/platform_apps/api/_api_features.json b/chrome/common/apps/platform_apps/api/_api_features.json index 4517920..7c6d60c 100644 --- a/chrome/common/apps/platform_apps/api/_api_features.json +++ b/chrome/common/apps/platform_apps/api/_api_features.json
@@ -26,5 +26,9 @@ "syncFileSystem": { "dependencies": ["permission:syncFileSystem"], "contexts": ["blessed_extension"] + }, + "webstoreWidgetPrivate": { + "dependencies": ["permission:webstoreWidgetPrivate"], + "contexts": ["blessed_extension"] } }
diff --git a/chrome/common/apps/platform_apps/api/_permission_features.json b/chrome/common/apps/platform_apps/api/_permission_features.json index de6b298..80841e4 100644 --- a/chrome/common/apps/platform_apps/api/_permission_features.json +++ b/chrome/common/apps/platform_apps/api/_permission_features.json
@@ -59,5 +59,15 @@ "syncFileSystem": { "channel": "stable", "extension_types": ["platform_app"] + }, + "webstoreWidgetPrivate": { + "channel": "stable", + "extension_types": ["platform_app"], + "platforms": ["chromeos"], + "whitelist": [ + "A948368FC53BE437A55FEB414106E207925482F5", // Files app + "8C726564C6DBE7380BAB388DE6CC7EC93EB44B06", // Video player + "5065C83E84321221675D20FBE4DC43C655CC8C6F" // Files app tests + ] } }
diff --git a/chrome/common/apps/platform_apps/api/api_sources.gni b/chrome/common/apps/platform_apps/api/api_sources.gni index ea084ff..05eb549 100644 --- a/chrome/common/apps/platform_apps/api/api_sources.gni +++ b/chrome/common/apps/platform_apps/api/api_sources.gni
@@ -11,6 +11,10 @@ "browser.idl", "media_galleries.idl", "sync_file_system.idl", + + # TODO(devlin): This API is only available on ChromeOS. We should only + # generate sources for it on CrOS as well. + "webstore_widget_private.idl", ] if (is_chromeos) {
diff --git a/chrome/common/extensions/api/webstore_widget_private.idl b/chrome/common/apps/platform_apps/api/webstore_widget_private.idl similarity index 100% rename from chrome/common/extensions/api/webstore_widget_private.idl rename to chrome/common/apps/platform_apps/api/webstore_widget_private.idl
diff --git a/chrome/common/apps/platform_apps/chrome_apps_api_permissions.cc b/chrome/common/apps/platform_apps/chrome_apps_api_permissions.cc index b0b8ecc..21aa4aa 100644 --- a/chrome/common/apps/platform_apps/chrome_apps_api_permissions.cc +++ b/chrome/common/apps/platform_apps/chrome_apps_api_permissions.cc
@@ -27,6 +27,8 @@ extensions::APIPermissionInfo::kFlagNone, &CreateAPIPermission<chrome_apps::MediaGalleriesPermission>}, {extensions::APIPermission::kSyncFileSystem, "syncFileSystem"}, + {extensions::APIPermission::kWebstoreWidgetPrivate, "webstoreWidgetPrivate", + extensions::APIPermissionInfo::kFlagCannotBeOptional}, }; } // namespace
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 32d6c08..5d7fbcb 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json
@@ -791,10 +791,6 @@ // given the blessed_extension denomination. Confusing. "contexts": ["blessed_extension"] }, - "webstoreWidgetPrivate": { - "dependencies": ["permission:webstoreWidgetPrivate"], - "contexts": ["blessed_extension"] - }, "webviewTag": { "internal": true, "channel": "stable",
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index 013ccbd..b3cf0512 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json
@@ -854,15 +854,5 @@ "B44D08FD98F1523ED5837D78D0A606EA9D6206E5", // Web Store "2653F6F6C39BC6EEBD36A09AFB92A19782FF7EB4" // Enterprise Web Store ] - }, - "webstoreWidgetPrivate": { - "channel": "stable", - "extension_types": ["platform_app"], - "platforms": ["chromeos"], - "whitelist": [ - "A948368FC53BE437A55FEB414106E207925482F5", // Files app - "8C726564C6DBE7380BAB388DE6CC7EC93EB44B06", // Video player - "5065C83E84321221675D20FBE4DC43C655CC8C6F" // Files app tests - ] } }
diff --git a/chrome/common/extensions/api/api_sources.gni b/chrome/common/extensions/api/api_sources.gni index 4c035694..e9589f14 100644 --- a/chrome/common/extensions/api/api_sources.gni +++ b/chrome/common/extensions/api/api_sources.gni
@@ -72,7 +72,6 @@ "webrtc_logging_private.idl", "webstore_private.json", - "webstore_widget_private.idl", "windows.json", ]
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc index 69ecf6fe..a77f6173 100644 --- a/chrome/common/extensions/permissions/chrome_api_permissions.cc +++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -166,8 +166,6 @@ APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kAutofillPrivate, "autofillPrivate", APIPermissionInfo::kFlagCannotBeOptional}, - {APIPermission::kWebstoreWidgetPrivate, "webstoreWidgetPrivate", - APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kPasswordsPrivate, "passwordsPrivate", APIPermissionInfo::kFlagCannotBeOptional}, {APIPermission::kUsersPrivate, "usersPrivate",
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index f99687d..b21db56 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -5353,7 +5353,6 @@ "../browser/sync/test/integration/migration_test.cc", "../browser/sync/test/integration/single_client_app_list_sync_test.cc", "../browser/sync/test/integration/single_client_apps_sync_test.cc", - "../browser/sync/test/integration/single_client_arc_package_sync_test.cc", "../browser/sync/test/integration/single_client_bookmarks_sync_test.cc", "../browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc", "../browser/sync/test/integration/single_client_dictionary_sync_test.cc", @@ -5363,7 +5362,6 @@ "../browser/sync/test/integration/single_client_passwords_sync_test.cc", "../browser/sync/test/integration/single_client_polling_sync_test.cc", "../browser/sync/test/integration/single_client_preferences_sync_test.cc", - "../browser/sync/test/integration/single_client_printers_sync_test.cc", "../browser/sync/test/integration/single_client_search_engines_sync_test.cc", "../browser/sync/test/integration/single_client_secondary_account_sync_test.cc", "../browser/sync/test/integration/single_client_sessions_sync_test.cc", @@ -5373,13 +5371,11 @@ "../browser/sync/test/integration/single_client_user_consents_sync_test.cc", "../browser/sync/test/integration/single_client_user_events_sync_test.cc", "../browser/sync/test/integration/single_client_wallet_sync_test.cc", - "../browser/sync/test/integration/single_client_wifi_credentials_sync_test.cc", "../browser/sync/test/integration/sync_auth_test.cc", "../browser/sync/test/integration/sync_errors_test.cc", "../browser/sync/test/integration/sync_exponential_backoff_test.cc", "../browser/sync/test/integration/two_client_app_list_sync_test.cc", "../browser/sync/test/integration/two_client_apps_sync_test.cc", - "../browser/sync/test/integration/two_client_arc_package_sync_test.cc", "../browser/sync/test/integration/two_client_autocomplete_sync_test.cc", "../browser/sync/test/integration/two_client_autofill_sync_test.cc", "../browser/sync/test/integration/two_client_bookmarks_sync_test.cc", @@ -5390,13 +5386,11 @@ "../browser/sync/test/integration/two_client_passwords_sync_test.cc", "../browser/sync/test/integration/two_client_polling_sync_test.cc", "../browser/sync/test/integration/two_client_preferences_sync_test.cc", - "../browser/sync/test/integration/two_client_printers_sync_test.cc", "../browser/sync/test/integration/two_client_search_engines_sync_test.cc", "../browser/sync/test/integration/two_client_sessions_sync_test.cc", "../browser/sync/test/integration/two_client_themes_sync_test.cc", "../browser/sync/test/integration/two_client_typed_urls_sync_test.cc", "../browser/sync/test/integration/two_client_uss_sync_test.cc", - "../browser/sync/test/integration/two_client_wifi_credentials_sync_test.cc", "data/resource.rc", ] @@ -5473,8 +5467,8 @@ } else { sources -= [ "../app/chrome_version.rc.version" ] } - if (!is_chromeos) { - sources -= [ + if (is_chromeos) { + sources += [ "../browser/sync/test/integration/single_client_arc_package_sync_test.cc", "../browser/sync/test/integration/single_client_printers_sync_test.cc", "../browser/sync/test/integration/single_client_wifi_credentials_sync_test.cc", @@ -5482,6 +5476,7 @@ "../browser/sync/test/integration/two_client_printers_sync_test.cc", "../browser/sync/test/integration/two_client_wifi_credentials_sync_test.cc", ] + deps += [ "//components/sync_wifi" ] } if (toolkit_views) {
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index fe8be1a9..6540321e 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -26,6 +26,10 @@ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2532 'SlowLoadingPageTest.testRefreshShouldBlockUntilPageLoads', 'PageLoadingTest.testShouldTimeoutIfAPageTakesTooLongToRefresh', + + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2629 + 'FrameSwitchingTest.*', + 'GetLogsTest.*', ] _OS_NEGATIVE_FILTER = {}
diff --git a/chrome/test/data/prerender/image2.png b/chrome/test/data/prerender/image2.png new file mode 100644 index 0000000..48af4d55 --- /dev/null +++ b/chrome/test/data/prerender/image2.png Binary files differ
diff --git a/chrome/test/data/prerender/prefetch_page_bigger.html b/chrome/test/data/prerender/prefetch_page_bigger.html new file mode 100644 index 0000000..bbbab63d0 --- /dev/null +++ b/chrome/test/data/prerender/prefetch_page_bigger.html
@@ -0,0 +1,8 @@ +<html> +<body> + <img src="image.jpeg"/> + <img src="image.png"/> + <img src="image2.png"/> + <img src="image-redirect.png"/> +</body> +</html>
diff --git a/chrome/test/data/webrtc/webrtc_getdisplaymedia_test.html b/chrome/test/data/webrtc/webrtc_getdisplaymedia_test.html index c124a82..e936818 100644 --- a/chrome/test/data/webrtc/webrtc_getdisplaymedia_test.html +++ b/chrome/test/data/webrtc/webrtc_getdisplaymedia_test.html
@@ -38,6 +38,14 @@ function getCursorSetting() { returnToTest(settings.cursor); } + + function getWidthSetting() { + returnToTest(settings.width.toString()); + } + + function getFrameRateSetting() { + returnToTest(settings.frameRate.toString()); + } </script> </head> <body>
diff --git a/chromeos/system/statistics_provider.cc b/chromeos/system/statistics_provider.cc index d1c1ef2..add44c7 100644 --- a/chromeos/system/statistics_provider.cc +++ b/chromeos/system/statistics_provider.cc
@@ -187,6 +187,9 @@ const char kDevSwitchBootKey[] = "devsw_boot"; const char kDevSwitchBootValueDev[] = "1"; const char kDevSwitchBootValueVerified[] = "0"; +const char kFirmwareWriteProtectBootKey[] = "wpsw_boot"; +const char kFirmwareWriteProtectBootValueOn[] = "1"; +const char kFirmwareWriteProtectBootValueOff[] = "0"; const char kFirmwareTypeKey[] = "mainfw_type"; const char kFirmwareTypeValueDeveloper[] = "developer"; const char kFirmwareTypeValueNonchrome[] = "nonchrome";
diff --git a/chromeos/system/statistics_provider.h b/chromeos/system/statistics_provider.h index 120921e..6ebf124 100644 --- a/chromeos/system/statistics_provider.h +++ b/chromeos/system/statistics_provider.h
@@ -39,6 +39,11 @@ CHROMEOS_EXPORT extern const char kDevSwitchBootValueDev[]; CHROMEOS_EXPORT extern const char kDevSwitchBootValueVerified[]; +// Firmware write protect switch value. +CHROMEOS_EXPORT extern const char kFirmwareWriteProtectBootKey[]; +CHROMEOS_EXPORT extern const char kFirmwareWriteProtectBootValueOn[]; +CHROMEOS_EXPORT extern const char kFirmwareWriteProtectBootValueOff[]; + // Firmware type and associated values. The values are from crossystem output // for the mainfw_type key. Normal and developer correspond to Chrome OS // firmware with MP and developer keys respectively, nonchrome indicates the
diff --git a/components/arc/arc_browser_context_keyed_service_factory_base.h b/components/arc/arc_browser_context_keyed_service_factory_base.h index 5b34b73..86b664ba 100644 --- a/components/arc/arc_browser_context_keyed_service_factory_base.h +++ b/components/arc/arc_browser_context_keyed_service_factory_base.h
@@ -96,11 +96,11 @@ static Service* GetForBrowserContextForTesting( content::BrowserContext* context) { Factory::GetInstance()->SetTestingFactoryAndUse( - context, - [](content::BrowserContext* context) -> std::unique_ptr<KeyedService> { + context, base::BindRepeating([](content::BrowserContext* context) + -> std::unique_ptr<KeyedService> { return std::make_unique<Service>( context, ArcServiceManager::Get()->arc_bridge_service()); - }); + })); return GetForBrowserContext(context); }
diff --git a/components/arc/common/video_encode_accelerator.mojom b/components/arc/common/video_encode_accelerator.mojom index df1c7a0..18d00f6 100644 --- a/components/arc/common/video_encode_accelerator.mojom +++ b/components/arc/common/video_encode_accelerator.mojom
@@ -9,6 +9,8 @@ import "components/arc/common/video_common.mojom"; +// Next MinVersion: 2 + [Extensible] enum VideoPixelFormat { // The values must match to the values in media::VideoPixelFormat @@ -24,6 +26,14 @@ uint32 max_framerate_denominator; }; + +// The input buffer storage type. +[Extensible] +enum VideoFrameStorageType { + SHMEM = 0, + DMABUF = 1, +}; + // The encoder parameter set which matches to // media::VideoEncodeAccelerator::Config. // |input_format| is the pixel format of the input frames. @@ -35,6 +45,7 @@ // valid when |has_initial_framerate| is true. // |h264_output_level| is H264 level of encoded output stream. It is optional, // only valid when |has_h264_output_level| is true. +// |storage_type| is the storage type of video frame provided on Encode(). struct VideoEncodeAcceleratorConfig { VideoPixelFormat input_format; Size input_visible_size; @@ -44,16 +55,38 @@ bool has_initial_framerate; uint8 h264_output_level; bool has_h264_output_level; + [MinVersion=1] VideoFrameStorageType storage_type; +}; + + +// The encoder parameter set which matches to +// media::VideoEncodeAccelerator::Config. +// |input_format| is the pixel format of the input frames. +// |input_visible_size| is the resolution of the input frames. +// |output_profile| is the codec profile of the encoded output stream. +// |initial_bitrate| is the initial bitrate of the encoded output stream, +// in bits per second. +// |initial_framerate| is the initial requested framerate. It is optional, only +// valid when |has_initial_framerate| is true. +// |h264_output_level| is H264 level of encoded output stream. It is optional, +// only valid when |has_h264_output_level| is true. +struct VideoEncodeAcceleratorConfigDeprecated { + VideoPixelFormat input_format; + Size input_visible_size; + VideoCodecProfile output_profile; + uint32 initial_bitrate; + uint32 initial_framerate; + bool has_initial_framerate; + uint8 h264_output_level; + bool has_h264_output_level; }; // Video encoder IPC interface. -// Next MinVersion: 1 -// Next Method ID: 7 +// Next Method ID: 8 interface VideoEncodeAccelerator { - // The input buffer storage type. [Extensible] - enum StorageType { + enum StorageTypeDeprecated { SHARED_MEMORY, DMABUF, }; @@ -81,15 +114,28 @@ // encoder construction. // Parameters: // |config| is the parameter set for encoder initialization. + // |client| is the client of this video encoder. The client must be valid + // during the lifetime of this accelerator. + // Callback: + // Called with true iff initialization is successful. The client should not + // invoke any other methods before the callback. + [MinVersion=1] + Initialize@7(VideoEncodeAcceleratorConfig config, + VideoEncodeClient client) => (bool success); + + // Initializes the video encoder with specific configuration. Called once per + // encoder construction. + // Parameters: + // |config| is the parameter set for encoder initialization. // |input_storage| the type of the input buffer. // |client| is the client of this video encoder. The client must be valid // during the lifetime of this accelerator. // Callback: // Called with true iff initialization is successful. The client should not // invoke any other methods before the callback. - Initialize@6(VideoEncodeAcceleratorConfig config, - StorageType input_storage, - VideoEncodeClient client) => (bool success); + InitializeDeprecated@6(VideoEncodeAcceleratorConfigDeprecated config, + StorageTypeDeprecated input_storage, + VideoEncodeClient client) => (bool success); // Encodes the given frame. // Parameters:
diff --git a/components/arc/common/video_encode_accelerator.typemap b/components/arc/common/video_encode_accelerator.typemap index 93c80939..57d485f 100644 --- a/components/arc/common/video_encode_accelerator.typemap +++ b/components/arc/common/video_encode_accelerator.typemap
@@ -17,8 +17,10 @@ "//base", ] type_mappings = [ + "arc.mojom.VideoFrameStorageType=media::VideoEncodeAccelerator::Config::StorageType", "arc.mojom.VideoEncodeAccelerator.Error=media::VideoEncodeAccelerator::Error", "arc.mojom.VideoPixelFormat=media::VideoPixelFormat", "arc.mojom.VideoEncodeProfile=media::VideoEncodeAccelerator::SupportedProfile", "arc.mojom.VideoEncodeAcceleratorConfig=media::VideoEncodeAccelerator::Config", + "arc.mojom.VideoEncodeAcceleratorConfigDeprecated=media::VideoEncodeAccelerator::Config", ]
diff --git a/components/arc/common/video_encode_accelerator_struct_traits.cc b/components/arc/common/video_encode_accelerator_struct_traits.cc index 2bbcc8e..9601ca3 100644 --- a/components/arc/common/video_encode_accelerator_struct_traits.cc +++ b/components/arc/common/video_encode_accelerator_struct_traits.cc
@@ -25,6 +25,30 @@ #undef CHECK_ERROR_ENUM // static +arc::mojom::VideoFrameStorageType +EnumTraits<arc::mojom::VideoFrameStorageType, + media::VideoEncodeAccelerator::Config::StorageType>:: + ToMojom(media::VideoEncodeAccelerator::Config::StorageType input) { + NOTIMPLEMENTED(); + return arc::mojom::VideoFrameStorageType::SHMEM; +} + +bool EnumTraits<arc::mojom::VideoFrameStorageType, + media::VideoEncodeAccelerator::Config::StorageType>:: + FromMojom(arc::mojom::VideoFrameStorageType input, + media::VideoEncodeAccelerator::Config::StorageType* output) { + switch (input) { + case arc::mojom::VideoFrameStorageType::SHMEM: + *output = media::VideoEncodeAccelerator::Config::StorageType::kShmem; + return true; + case arc::mojom::VideoFrameStorageType::DMABUF: + *output = media::VideoEncodeAccelerator::Config::StorageType::kDmabuf; + return true; + } + return false; +} + +// static arc::mojom::VideoEncodeAccelerator::Error EnumTraits<arc::mojom::VideoEncodeAccelerator::Error, media::VideoEncodeAccelerator::Error>:: @@ -101,6 +125,43 @@ h264_output_level = input.h264_output_level(); } + media::VideoEncodeAccelerator::Config::StorageType storage_type; + if (!input.ReadStorageType(&storage_type)) + return false; + + *output = media::VideoEncodeAccelerator::Config( + input_format, input_visible_size, output_profile, input.initial_bitrate(), + initial_framerate, h264_output_level, storage_type); + return true; +} + +// static +bool StructTraits<arc::mojom::VideoEncodeAcceleratorConfigDeprecatedDataView, + media::VideoEncodeAccelerator::Config>:: + Read(arc::mojom::VideoEncodeAcceleratorConfigDeprecatedDataView input, + media::VideoEncodeAccelerator::Config* output) { + media::VideoPixelFormat input_format; + if (!input.ReadInputFormat(&input_format)) + return false; + + gfx::Size input_visible_size; + if (!input.ReadInputVisibleSize(&input_visible_size)) + return false; + + media::VideoCodecProfile output_profile; + if (!input.ReadOutputProfile(&output_profile)) + return false; + + base::Optional<uint32_t> initial_framerate; + if (input.has_initial_framerate()) { + initial_framerate = input.initial_framerate(); + } + + base::Optional<uint8_t> h264_output_level; + if (input.has_h264_output_level()) { + h264_output_level = input.h264_output_level(); + } + *output = media::VideoEncodeAccelerator::Config( input_format, input_visible_size, output_profile, input.initial_bitrate(), initial_framerate, h264_output_level);
diff --git a/components/arc/common/video_encode_accelerator_struct_traits.h b/components/arc/common/video_encode_accelerator_struct_traits.h index f56a0d60..e0fdbd52 100644 --- a/components/arc/common/video_encode_accelerator_struct_traits.h +++ b/components/arc/common/video_encode_accelerator_struct_traits.h
@@ -11,6 +11,16 @@ namespace mojo { template <> +struct EnumTraits<arc::mojom::VideoFrameStorageType, + media::VideoEncodeAccelerator::Config::StorageType> { + static arc::mojom::VideoFrameStorageType ToMojom( + media::VideoEncodeAccelerator::Config::StorageType input); + static bool FromMojom( + arc::mojom::VideoFrameStorageType input, + media::VideoEncodeAccelerator::Config::StorageType* output); +}; + +template <> struct EnumTraits<arc::mojom::VideoEncodeAccelerator::Error, media::VideoEncodeAccelerator::Error> { static arc::mojom::VideoEncodeAccelerator::Error ToMojom( @@ -98,10 +108,70 @@ return input.h264_output_level.has_value(); } + static arc::mojom::VideoFrameStorageType storage_type( + const media::VideoEncodeAccelerator::Config& input) { + auto storage_type = input.storage_type.value_or( + media::VideoEncodeAccelerator::Config::StorageType::kShmem); + switch (storage_type) { + case media::VideoEncodeAccelerator::Config::StorageType::kShmem: + return arc::mojom::VideoFrameStorageType::SHMEM; + case media::VideoEncodeAccelerator::Config::StorageType::kDmabuf: + return arc::mojom::VideoFrameStorageType::DMABUF; + } + } + static bool Read(arc::mojom::VideoEncodeAcceleratorConfigDataView input, media::VideoEncodeAccelerator::Config* output); }; +template <> +struct StructTraits<arc::mojom::VideoEncodeAcceleratorConfigDeprecatedDataView, + media::VideoEncodeAccelerator::Config> { + static media::VideoPixelFormat input_format( + const media::VideoEncodeAccelerator::Config& input) { + return input.input_format; + } + + static const gfx::Size& input_visible_size( + const media::VideoEncodeAccelerator::Config& input) { + return input.input_visible_size; + } + + static media::VideoCodecProfile output_profile( + const media::VideoEncodeAccelerator::Config& input) { + return input.output_profile; + } + + static uint32_t initial_bitrate( + const media::VideoEncodeAccelerator::Config& input) { + return input.initial_bitrate; + } + + static uint32_t initial_framerate( + const media::VideoEncodeAccelerator::Config& input) { + return input.initial_framerate.value_or(0); + } + + static bool has_initial_framerate( + const media::VideoEncodeAccelerator::Config& input) { + return input.initial_framerate.has_value(); + } + + static uint8_t h264_output_level( + const media::VideoEncodeAccelerator::Config& input) { + return input.h264_output_level.value_or(0); + } + + static bool has_h264_output_level( + const media::VideoEncodeAccelerator::Config& input) { + return input.h264_output_level.has_value(); + } + + static bool Read( + arc::mojom::VideoEncodeAcceleratorConfigDeprecatedDataView input, + media::VideoEncodeAccelerator::Config* output); +}; + } // namespace mojo #endif // COMPONENTS_ARC_COMMON_VIDEO_ENCODE_ACCELERATOR_STRUCT_TRAITS_H_
diff --git a/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc b/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc index 44469c6..68069cb 100644 --- a/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc +++ b/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.cc
@@ -82,7 +82,6 @@ void GpuArcVideoEncodeAccelerator::Initialize( const media::VideoEncodeAccelerator::Config& config, - VideoEncodeAccelerator::StorageType input_storage, VideoEncodeClientPtr client, InitializeCallback callback) { DVLOGF(2) << config.AsHumanReadableString(); @@ -100,6 +99,15 @@ std::move(callback).Run(true); } +void GpuArcVideoEncodeAccelerator::InitializeDeprecated( + const media::VideoEncodeAccelerator::Config& config, + VideoEncodeAccelerator::StorageTypeDeprecated input_storage, + VideoEncodeClientPtr client, + InitializeCallback callback) { + // Intentionally ignore input_storage. It has never been used since now. + Initialize(config, std::move(client), std::move(callback)); +} + static void DropShareMemoryAndVideoFrameDoneNotifier( std::unique_ptr<base::SharedMemory> shm, std::unique_ptr<VideoFrameDoneNotifier> notifier) {
diff --git a/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.h b/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.h index 43502a6..4038d15 100644 --- a/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.h +++ b/components/arc/video_accelerator/gpu_arc_video_encode_accelerator.h
@@ -46,9 +46,13 @@ // ::arc::mojom::VideoEncodeAccelerator implementation. void GetSupportedProfiles(GetSupportedProfilesCallback callback) override; void Initialize(const media::VideoEncodeAccelerator::Config& config, - VideoEncodeAccelerator::StorageType input_storage, VideoEncodeClientPtr client, InitializeCallback callback) override; + void InitializeDeprecated( + const media::VideoEncodeAccelerator::Config& config, + VideoEncodeAccelerator::StorageTypeDeprecated input_storage, + VideoEncodeClientPtr client, + InitializeCallback callback) override; void Encode(mojo::ScopedHandle fd, std::vector<::arc::VideoFramePlane> planes, int64_t timestamp,
diff --git a/components/autofill/android/java/strings/autofill_strings.grd b/components/autofill/android/java/strings/autofill_strings.grd index 3ad4a44..cd32dec 100644 --- a/components/autofill/android/java/strings/autofill_strings.grd +++ b/components/autofill/android/java/strings/autofill_strings.grd
@@ -52,6 +52,7 @@ <file lang="am" path="translations/autofill_strings_am.xtb" /> <file lang="ar" path="translations/autofill_strings_ar.xtb" /> <file lang="bg" path="translations/autofill_strings_bg.xtb" /> + <file lang="bn" path="translations/autofill_strings_bn.xtb" /> <file lang="ca" path="translations/autofill_strings_ca.xtb" /> <file lang="cs" path="translations/autofill_strings_cs.xtb" /> <file lang="da" path="translations/autofill_strings_da.xtb" /> @@ -60,10 +61,12 @@ <file lang="en-GB" path="translations/autofill_strings_en-GB.xtb" /> <file lang="es" path="translations/autofill_strings_es.xtb" /> <file lang="es-419" path="translations/autofill_strings_es-419.xtb" /> + <file lang="et" path="translations/autofill_strings_et.xtb" /> <file lang="fa" path="translations/autofill_strings_fa.xtb" /> <file lang="fi" path="translations/autofill_strings_fi.xtb" /> <file lang="fil" path="translations/autofill_strings_fil.xtb" /> <file lang="fr" path="translations/autofill_strings_fr.xtb" /> + <file lang="gu" path="translations/autofill_strings_gu.xtb" /> <file lang="hi" path="translations/autofill_strings_hi.xtb" /> <file lang="hr" path="translations/autofill_strings_hr.xtb" /> <file lang="hu" path="translations/autofill_strings_hu.xtb" /> @@ -72,8 +75,12 @@ <file lang="iw" path="translations/autofill_strings_iw.xtb" /> <file lang="ja" path="translations/autofill_strings_ja.xtb" /> <file lang="ko" path="translations/autofill_strings_ko.xtb" /> + <file lang="kn" path="translations/autofill_strings_kn.xtb" /> <file lang="lt" path="translations/autofill_strings_lt.xtb" /> <file lang="lv" path="translations/autofill_strings_lv.xtb" /> + <file lang="ml" path="translations/autofill_strings_ml.xtb" /> + <file lang="mr" path="translations/autofill_strings_mr.xtb" /> + <file lang="ms" path="translations/autofill_strings_ms.xtb" /> <file lang="nl" path="translations/autofill_strings_nl.xtb" /> <file lang="no" path="translations/autofill_strings_no.xtb" /> <file lang="pl" path="translations/autofill_strings_pl.xtb" /> @@ -86,6 +93,8 @@ <file lang="sr" path="translations/autofill_strings_sr.xtb" /> <file lang="sv" path="translations/autofill_strings_sv.xtb" /> <file lang="sw" path="translations/autofill_strings_sw.xtb" /> + <file lang="ta" path="translations/autofill_strings_ta.xtb" /> + <file lang="te" path="translations/autofill_strings_te.xtb" /> <file lang="th" path="translations/autofill_strings_th.xtb" /> <file lang="tr" path="translations/autofill_strings_tr.xtb" /> <file lang="uk" path="translations/autofill_strings_uk.xtb" />
diff --git a/components/autofill/android/java/strings/translations/autofill_strings_bn.xtb b/components/autofill/android/java/strings/translations/autofill_strings_bn.xtb new file mode 100644 index 0000000..deae4a2 --- /dev/null +++ b/components/autofill/android/java/strings/translations/autofill_strings_bn.xtb
@@ -0,0 +1,5 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="bn"> +<translation id="1112374155460533568">Showing AutoFill pop-up</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/autofill/android/java/strings/translations/autofill_strings_et.xtb b/components/autofill/android/java/strings/translations/autofill_strings_et.xtb new file mode 100644 index 0000000..f721c36 --- /dev/null +++ b/components/autofill/android/java/strings/translations/autofill_strings_et.xtb
@@ -0,0 +1,5 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="et"> +<translation id="1112374155460533568">Showing AutoFill pop-up</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/autofill/android/java/strings/translations/autofill_strings_gu.xtb b/components/autofill/android/java/strings/translations/autofill_strings_gu.xtb new file mode 100644 index 0000000..5bcc506 --- /dev/null +++ b/components/autofill/android/java/strings/translations/autofill_strings_gu.xtb
@@ -0,0 +1,5 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="gu"> +<translation id="1112374155460533568">Showing AutoFill pop-up</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/autofill/android/java/strings/translations/autofill_strings_kn.xtb b/components/autofill/android/java/strings/translations/autofill_strings_kn.xtb new file mode 100644 index 0000000..09599c5 --- /dev/null +++ b/components/autofill/android/java/strings/translations/autofill_strings_kn.xtb
@@ -0,0 +1,5 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="kn"> +<translation id="1112374155460533568">Showing AutoFill pop-up</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/autofill/android/java/strings/translations/autofill_strings_ml.xtb b/components/autofill/android/java/strings/translations/autofill_strings_ml.xtb new file mode 100644 index 0000000..0f0bd005 --- /dev/null +++ b/components/autofill/android/java/strings/translations/autofill_strings_ml.xtb
@@ -0,0 +1,5 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ml"> +<translation id="1112374155460533568">Showing AutoFill pop-up</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/autofill/android/java/strings/translations/autofill_strings_mr.xtb b/components/autofill/android/java/strings/translations/autofill_strings_mr.xtb new file mode 100644 index 0000000..81bf14c4 --- /dev/null +++ b/components/autofill/android/java/strings/translations/autofill_strings_mr.xtb
@@ -0,0 +1,5 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="mr"> +<translation id="1112374155460533568">Showing AutoFill pop-up</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/autofill/android/java/strings/translations/autofill_strings_ms.xtb b/components/autofill/android/java/strings/translations/autofill_strings_ms.xtb new file mode 100644 index 0000000..6696ba2 --- /dev/null +++ b/components/autofill/android/java/strings/translations/autofill_strings_ms.xtb
@@ -0,0 +1,5 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ms"> +<translation id="1112374155460533568">Showing AutoFill pop-up</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/autofill/android/java/strings/translations/autofill_strings_ta.xtb b/components/autofill/android/java/strings/translations/autofill_strings_ta.xtb new file mode 100644 index 0000000..2987fed --- /dev/null +++ b/components/autofill/android/java/strings/translations/autofill_strings_ta.xtb
@@ -0,0 +1,5 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ta"> +<translation id="1112374155460533568">Showing AutoFill pop-up</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/autofill/android/java/strings/translations/autofill_strings_te.xtb b/components/autofill/android/java/strings/translations/autofill_strings_te.xtb new file mode 100644 index 0000000..c6ed0f7 --- /dev/null +++ b/components/autofill/android/java/strings/translations/autofill_strings_te.xtb
@@ -0,0 +1,5 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="te"> +<translation id="1112374155460533568">Showing AutoFill pop-up</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/autofill_assistant_strings.grdp b/components/autofill_assistant_strings.grdp index b9e0da1..b32a546 100644 --- a/components/autofill_assistant_strings.grdp +++ b/components/autofill_assistant_strings.grdp
@@ -7,5 +7,8 @@ <message name="IDS_AUTOFILL_ASSISTANT_LOADING" desc="Text label that is shown during the loading of the first page, right after being triggered."> Loading <ph name="SITE_NAME">$1<ex>google.com</ex></ph>… </message> + <message name="IDS_AUTOFILL_ASSISTANT_PAYMENT_INFO_CONFIRM" desc="Text on the payment request primary button to confirm payment information [CHAR-LIMIT=32]" formatter_data="android_java"> + Confirm + </message> </if> </grit-part>
diff --git a/components/background_task_scheduler/BUILD.gn b/components/background_task_scheduler/BUILD.gn index 244584d..47c114364 100644 --- a/components/background_task_scheduler/BUILD.gn +++ b/components/background_task_scheduler/BUILD.gn
@@ -68,6 +68,7 @@ deps = [ ":background_task_scheduler_java", + ":background_task_scheduler_task_ids_java", "$google_play_services_package:google_play_services_base_java", "$google_play_services_package:google_play_services_basement_java", "$google_play_services_package:google_play_services_gcm_java",
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn index 604ffdf..b4e5204 100644 --- a/components/cronet/android/BUILD.gn +++ b/components/cronet/android/BUILD.gn
@@ -339,6 +339,7 @@ deps = [ ":cronet_api_java", ":cronet_impl_common_base_java", + "//net/android:net_thread_stats_uid_java", "//third_party/android_deps:android_support_annotations_java", "//third_party/jsr-305:jsr_305_javalib", ] @@ -507,6 +508,7 @@ ":package_api_java", ":package_impl_common_java", ":repackage_extracted_native_jars", + "//third_party/android_deps:android_support_v4_java", "//third_party/jsr-305:jsr_305_javalib", ] } @@ -1030,7 +1032,9 @@ deps = [ ":cronet_api_java", ":cronet_impl_all_java", + ":cronet_urlconnection_impl_java", "//third_party/android_support_test_runner:runner_java", + "//third_party/hamcrest:hamcrest_core_java", "//third_party/junit", ] deps += cronet_javatests_deps_to_package
diff --git a/components/cronet/native/test/url_request_test.cc b/components/cronet/native/test/url_request_test.cc index cda47a0c..55b0dbc 100644 --- a/components/cronet/native/test/url_request_test.cc +++ b/components/cronet/native/test/url_request_test.cc
@@ -727,6 +727,7 @@ EXPECT_EQ(2, callback->redirect_count_); EXPECT_EQ(200, callback->response_info_->http_status_code); EXPECT_EQ(2ul, callback->redirect_response_info_list_.size()); + EXPECT_EQ(2ul, callback->redirect_url_list_.size()); // Check first redirect (multiredirect.html -> redirect.html). TestUrlRequestCallback::UrlResponseInfo first_expected_response_info( @@ -736,6 +737,8 @@ "redirect-header0", "header-value"})); ExpectResponseInfoEquals(first_expected_response_info, *callback->redirect_response_info_list_.front()); + EXPECT_EQ(cronet::TestServer::GetRedirectURL(), + callback->redirect_url_list_.front()); // Check second redirect (redirect.html -> success.txt). TestUrlRequestCallback::UrlResponseInfo second_expected_response_info( @@ -747,6 +750,9 @@ "redirect-header", "header-value"})); ExpectResponseInfoEquals(second_expected_response_info, *callback->redirect_response_info_list_.back()); + EXPECT_EQ(cronet::TestServer::GetSuccessURL(), + callback->redirect_url_list_.back()); + // Check final response (success.txt). TestUrlRequestCallback::UrlResponseInfo final_expected_response_info( std::vector<std::string>({cronet::TestServer::GetMultiRedirectURL(),
diff --git a/components/cronet/native/url_request.cc b/components/cronet/native/url_request.cc index c594826..98c645f 100644 --- a/components/cronet/native/url_request.cc +++ b/components/cronet/native/url_request.cc
@@ -502,12 +502,12 @@ Cronet_Executor_Execute(executor_, runnable); } -void Cronet_UrlRequestImpl::InvokeCallbackOnRedirectReceived() { +void Cronet_UrlRequestImpl::InvokeCallbackOnRedirectReceived( + const std::string& new_location) { if (IsDone()) return; Cronet_UrlRequestCallback_OnRedirectReceived( - callback_, this, response_info_.get(), - response_info_->url_chain.front().c_str()); + callback_, this, response_info_.get(), new_location.c_str()); } void Cronet_UrlRequestImpl::InvokeCallbackOnResponseStarted() { @@ -612,7 +612,7 @@ // Invoke Cronet_UrlRequestCallback_OnRedirectReceived on client executor. url_request_->PostTaskToExecutor( base::BindOnce(&Cronet_UrlRequestImpl::InvokeCallbackOnRedirectReceived, - base::Unretained(url_request_))); + base::Unretained(url_request_), new_location)); } void Cronet_UrlRequestImpl::NetworkTasks::OnResponseStarted(
diff --git a/components/cronet/native/url_request.h b/components/cronet/native/url_request.h index 7e3a708b..e3936b1a 100644 --- a/components/cronet/native/url_request.h +++ b/components/cronet/native/url_request.h
@@ -71,7 +71,7 @@ void PostTaskToExecutor(base::OnceClosure task); // Helper methods to invoke application |callback_|. - void InvokeCallbackOnRedirectReceived(); + void InvokeCallbackOnRedirectReceived(const std::string& new_location); void InvokeCallbackOnResponseStarted(); void InvokeCallbackOnReadCompleted( std::unique_ptr<Cronet_Buffer> cronet_buffer,
diff --git a/components/embedder_support/android/BUILD.gn b/components/embedder_support/android/BUILD.gn index c7128e1df4..4e6e893 100644 --- a/components/embedder_support/android/BUILD.gn +++ b/components/embedder_support/android/BUILD.gn
@@ -133,6 +133,7 @@ ":web_contents_delegate_java_resources", "//base:base_java", "//content/public/android:content_java", + "//third_party/android_deps:android_support_compat_java", "//ui/android:ui_java", ] java_files = [
diff --git a/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_bn.xtb b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_bn.xtb new file mode 100644 index 0000000..8dee1f5 --- /dev/null +++ b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_bn.xtb
@@ -0,0 +1,19 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="bn"> +<translation id="1555130319947370107">Blue</translation> +<translation id="161042844686301425">Cyan</translation> +<translation id="2713444072780614174">White</translation> +<translation id="3329013043687509092">Saturation</translation> +<translation id="4115378294792113321">Magenta</translation> +<translation id="5901630391730855834">Yellow</translation> +<translation id="6017514345406065928">Green</translation> +<translation id="6042308850641462728">More</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="7535087603100972091">Value</translation> +<translation id="7569983096843329377">Black</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7942349550061667556">Red</translation> +<translation id="8889402386540077796">Hue</translation> +<translation id="9068849894565669697">Select colour</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_et.xtb b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_et.xtb new file mode 100644 index 0000000..fd15a38 --- /dev/null +++ b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_et.xtb
@@ -0,0 +1,19 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="et"> +<translation id="1555130319947370107">Blue</translation> +<translation id="161042844686301425">Cyan</translation> +<translation id="2713444072780614174">White</translation> +<translation id="3329013043687509092">Saturation</translation> +<translation id="4115378294792113321">Magenta</translation> +<translation id="5901630391730855834">Yellow</translation> +<translation id="6017514345406065928">Green</translation> +<translation id="6042308850641462728">More</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="7535087603100972091">Value</translation> +<translation id="7569983096843329377">Black</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7942349550061667556">Red</translation> +<translation id="8889402386540077796">Hue</translation> +<translation id="9068849894565669697">Select colour</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_gu.xtb b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_gu.xtb new file mode 100644 index 0000000..e817b21 --- /dev/null +++ b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_gu.xtb
@@ -0,0 +1,19 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="gu"> +<translation id="1555130319947370107">Blue</translation> +<translation id="161042844686301425">Cyan</translation> +<translation id="2713444072780614174">White</translation> +<translation id="3329013043687509092">Saturation</translation> +<translation id="4115378294792113321">Magenta</translation> +<translation id="5901630391730855834">Yellow</translation> +<translation id="6017514345406065928">Green</translation> +<translation id="6042308850641462728">More</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="7535087603100972091">Value</translation> +<translation id="7569983096843329377">Black</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7942349550061667556">Red</translation> +<translation id="8889402386540077796">Hue</translation> +<translation id="9068849894565669697">Select colour</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_kn.xtb b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_kn.xtb new file mode 100644 index 0000000..22358b1 --- /dev/null +++ b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_kn.xtb
@@ -0,0 +1,19 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="kn"> +<translation id="1555130319947370107">Blue</translation> +<translation id="161042844686301425">Cyan</translation> +<translation id="2713444072780614174">White</translation> +<translation id="3329013043687509092">Saturation</translation> +<translation id="4115378294792113321">Magenta</translation> +<translation id="5901630391730855834">Yellow</translation> +<translation id="6017514345406065928">Green</translation> +<translation id="6042308850641462728">More</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="7535087603100972091">Value</translation> +<translation id="7569983096843329377">Black</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7942349550061667556">Red</translation> +<translation id="8889402386540077796">Hue</translation> +<translation id="9068849894565669697">Select colour</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_ml.xtb b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_ml.xtb new file mode 100644 index 0000000..f336a2093 --- /dev/null +++ b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_ml.xtb
@@ -0,0 +1,19 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ml"> +<translation id="1555130319947370107">Blue</translation> +<translation id="161042844686301425">Cyan</translation> +<translation id="2713444072780614174">White</translation> +<translation id="3329013043687509092">Saturation</translation> +<translation id="4115378294792113321">Magenta</translation> +<translation id="5901630391730855834">Yellow</translation> +<translation id="6017514345406065928">Green</translation> +<translation id="6042308850641462728">More</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="7535087603100972091">Value</translation> +<translation id="7569983096843329377">Black</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7942349550061667556">Red</translation> +<translation id="8889402386540077796">Hue</translation> +<translation id="9068849894565669697">Select colour</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_mr.xtb b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_mr.xtb new file mode 100644 index 0000000..0acb899 --- /dev/null +++ b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_mr.xtb
@@ -0,0 +1,19 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="mr"> +<translation id="1555130319947370107">Blue</translation> +<translation id="161042844686301425">Cyan</translation> +<translation id="2713444072780614174">White</translation> +<translation id="3329013043687509092">Saturation</translation> +<translation id="4115378294792113321">Magenta</translation> +<translation id="5901630391730855834">Yellow</translation> +<translation id="6017514345406065928">Green</translation> +<translation id="6042308850641462728">More</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="7535087603100972091">Value</translation> +<translation id="7569983096843329377">Black</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7942349550061667556">Red</translation> +<translation id="8889402386540077796">Hue</translation> +<translation id="9068849894565669697">Select colour</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_ms.xtb b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_ms.xtb new file mode 100644 index 0000000..b84f111 --- /dev/null +++ b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_ms.xtb
@@ -0,0 +1,19 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ms"> +<translation id="1555130319947370107">Blue</translation> +<translation id="161042844686301425">Cyan</translation> +<translation id="2713444072780614174">White</translation> +<translation id="3329013043687509092">Saturation</translation> +<translation id="4115378294792113321">Magenta</translation> +<translation id="5901630391730855834">Yellow</translation> +<translation id="6017514345406065928">Green</translation> +<translation id="6042308850641462728">More</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="7535087603100972091">Value</translation> +<translation id="7569983096843329377">Black</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7942349550061667556">Red</translation> +<translation id="8889402386540077796">Hue</translation> +<translation id="9068849894565669697">Select colour</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_ta.xtb b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_ta.xtb new file mode 100644 index 0000000..4540ce2 --- /dev/null +++ b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_ta.xtb
@@ -0,0 +1,19 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ta"> +<translation id="1555130319947370107">Blue</translation> +<translation id="161042844686301425">Cyan</translation> +<translation id="2713444072780614174">White</translation> +<translation id="3329013043687509092">Saturation</translation> +<translation id="4115378294792113321">Magenta</translation> +<translation id="5901630391730855834">Yellow</translation> +<translation id="6017514345406065928">Green</translation> +<translation id="6042308850641462728">More</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="7535087603100972091">Value</translation> +<translation id="7569983096843329377">Black</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7942349550061667556">Red</translation> +<translation id="8889402386540077796">Hue</translation> +<translation id="9068849894565669697">Select colour</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_te.xtb b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_te.xtb new file mode 100644 index 0000000..9e67961 --- /dev/null +++ b/components/embedder_support/android/java/strings/translations/web_contents_delegate_android_strings_te.xtb
@@ -0,0 +1,19 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="te"> +<translation id="1555130319947370107">Blue</translation> +<translation id="161042844686301425">Cyan</translation> +<translation id="2713444072780614174">White</translation> +<translation id="3329013043687509092">Saturation</translation> +<translation id="4115378294792113321">Magenta</translation> +<translation id="5901630391730855834">Yellow</translation> +<translation id="6017514345406065928">Green</translation> +<translation id="6042308850641462728">More</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="7535087603100972091">Value</translation> +<translation id="7569983096843329377">Black</translation> +<translation id="7658239707568436148">Cancel</translation> +<translation id="7942349550061667556">Red</translation> +<translation id="8889402386540077796">Hue</translation> +<translation id="9068849894565669697">Select colour</translation> +</translationbundle> \ No newline at end of file
diff --git a/components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd b/components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd index fa0a4f4..b5177f0 100644 --- a/components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd +++ b/components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd
@@ -52,6 +52,7 @@ <file lang="am" path="translations/web_contents_delegate_android_strings_am.xtb" /> <file lang="ar" path="translations/web_contents_delegate_android_strings_ar.xtb" /> <file lang="bg" path="translations/web_contents_delegate_android_strings_bg.xtb" /> + <file lang="bn" path="translations/web_contents_delegate_android_strings_bn.xtb" /> <file lang="ca" path="translations/web_contents_delegate_android_strings_ca.xtb" /> <file lang="cs" path="translations/web_contents_delegate_android_strings_cs.xtb" /> <file lang="da" path="translations/web_contents_delegate_android_strings_da.xtb" /> @@ -60,10 +61,12 @@ <file lang="en-GB" path="translations/web_contents_delegate_android_strings_en-GB.xtb" /> <file lang="es" path="translations/web_contents_delegate_android_strings_es.xtb" /> <file lang="es-419" path="translations/web_contents_delegate_android_strings_es-419.xtb" /> + <file lang="et" path="translations/web_contents_delegate_android_strings_et.xtb" /> <file lang="fa" path="translations/web_contents_delegate_android_strings_fa.xtb" /> <file lang="fi" path="translations/web_contents_delegate_android_strings_fi.xtb" /> <file lang="fil" path="translations/web_contents_delegate_android_strings_fil.xtb" /> <file lang="fr" path="translations/web_contents_delegate_android_strings_fr.xtb" /> + <file lang="gu" path="translations/web_contents_delegate_android_strings_gu.xtb" /> <file lang="hi" path="translations/web_contents_delegate_android_strings_hi.xtb" /> <file lang="hr" path="translations/web_contents_delegate_android_strings_hr.xtb" /> <file lang="hu" path="translations/web_contents_delegate_android_strings_hu.xtb" /> @@ -72,8 +75,12 @@ <file lang="iw" path="translations/web_contents_delegate_android_strings_iw.xtb" /> <file lang="ja" path="translations/web_contents_delegate_android_strings_ja.xtb" /> <file lang="ko" path="translations/web_contents_delegate_android_strings_ko.xtb" /> + <file lang="kn" path="translations/web_contents_delegate_android_strings_kn.xtb" /> <file lang="lt" path="translations/web_contents_delegate_android_strings_lt.xtb" /> <file lang="lv" path="translations/web_contents_delegate_android_strings_lv.xtb" /> + <file lang="ml" path="translations/web_contents_delegate_android_strings_ml.xtb" /> + <file lang="mr" path="translations/web_contents_delegate_android_strings_mr.xtb" /> + <file lang="ms" path="translations/web_contents_delegate_android_strings_ms.xtb" /> <file lang="nl" path="translations/web_contents_delegate_android_strings_nl.xtb" /> <file lang="no" path="translations/web_contents_delegate_android_strings_no.xtb" /> <file lang="pl" path="translations/web_contents_delegate_android_strings_pl.xtb" /> @@ -86,6 +93,8 @@ <file lang="sr" path="translations/web_contents_delegate_android_strings_sr.xtb" /> <file lang="sv" path="translations/web_contents_delegate_android_strings_sv.xtb" /> <file lang="sw" path="translations/web_contents_delegate_android_strings_sw.xtb" /> + <file lang="ta" path="translations/web_contents_delegate_android_strings_ta.xtb" /> + <file lang="te" path="translations/web_contents_delegate_android_strings_te.xtb" /> <file lang="th" path="translations/web_contents_delegate_android_strings_th.xtb" /> <file lang="tr" path="translations/web_contents_delegate_android_strings_tr.xtb" /> <file lang="uk" path="translations/web_contents_delegate_android_strings_uk.xtb" />
diff --git a/components/gcm_driver/android/BUILD.gn b/components/gcm_driver/android/BUILD.gn index 99135a0..b9d9560 100644 --- a/components/gcm_driver/android/BUILD.gn +++ b/components/gcm_driver/android/BUILD.gn
@@ -14,6 +14,7 @@ android_library("gcm_driver_java") { deps = [ "//base:base_java", + "//components/gcm_driver/instance_id/android:instance_id_driver_java", "//content/public/android:content_java", "//third_party/android_tools:android_gcm_java", "//third_party/jsr-305:jsr_305_javalib", @@ -28,8 +29,10 @@ } junit_binary("components_gcm_driver_junit_tests") { - java_files = - [ "junit/src/org/chromium/components/gcm_driver/GCMMessageTest.java" ] + java_files = [ + "junit/src/org/chromium/components/gcm_driver/GCMMessageTest.java", + "junit/src/org/chromium/components/gcm_driver/GCMDriverTest.java", + ] deps = [ ":gcm_driver_java", "//base:base_java",
diff --git a/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java b/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java index 00219cd..6513ec6 100644 --- a/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java +++ b/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMDriver.java
@@ -4,14 +4,25 @@ package org.chromium.components.gcm_driver; +import android.content.Context; +import android.content.SharedPreferences; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.task.AsyncTask; +import org.chromium.components.gcm_driver.instance_id.InstanceIDBridge; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; /** * This class is the Java counterpart to the C++ GCMDriverAndroid class. @@ -23,6 +34,10 @@ @JNINamespace("gcm") public class GCMDriver { private static final String TAG = "GCMDriver"; + // The max number of most recent messages queued per lazy subscription until + // Chrome is foregrounded. + @VisibleForTesting + public static final int MESSAGES_QUEUE_SIZE = 3; // The instance of GCMDriver currently owned by a C++ GCMDriverAndroid, if any. private static GCMDriver sInstance; @@ -120,6 +135,118 @@ message.getDataKeysAndValuesArray()); } + /** + * Stores |message| on disk. Stored Messages for a subscription id will be + * returned by readMessages(). Only the most recent |MESSAGES_QUEUE_SIZE| + * messages with distinct collapse keys are kept. + * @param subscriptionId id of the subscription. + * @param message The message to be persisted. + */ + public static void persistMessage(String subscriptionId, GCMMessage message) { + // Messages are stored as a JSONArray in SharedPreferences. The key is + // |subscriptionId|. The value is a string representing a JSONArray that + // contains messages serialized as a JSONObject. + + // Load the persisted messages for this subscription. + Context context = ContextUtils.getApplicationContext(); + SharedPreferences sharedPrefs = + context.getSharedPreferences(InstanceIDBridge.PREF_PACKAGE, Context.MODE_PRIVATE); + // Default is an empty queue if no messages are queued for this subscription. + String queueString = sharedPrefs.getString(subscriptionId, "[]"); + try { + JSONArray queueJSON = new JSONArray(queueString); + if (message.getCollapseKey() != null) { + queueJSON = filterMessageBasedOnCollapseKey(queueJSON, message.getCollapseKey()); + } + // TODO(https://crbug.com/882887):Add UMA to record how many + // messages are currently in the queue, to identify how often we hit + // the limit. + + // If the queue is full remove the oldest message. + if (queueJSON.length() == MESSAGES_QUEUE_SIZE) { + Log.w(TAG, + "Dropping GCM Message due queue size limit. Sender id:" + + GCMMessage.peekSenderId(queueJSON.getJSONObject(0))); + JSONArray newQueue = new JSONArray(); + // Copy all messages except the first one. + for (int i = 1; i < MESSAGES_QUEUE_SIZE; i++) { + newQueue.put(queueJSON.get(i)); + } + queueJSON = newQueue; + } + // Add the new message to the end. + queueJSON.put(message.toJSON()); + sharedPrefs.edit().putString(subscriptionId, queueJSON.toString()).apply(); + } catch (JSONException e) { + Log.e(TAG, + "Error when parsing the persisted message queue for subscriber:" + + subscriptionId + ":" + e.getMessage()); + } + } + + /** + * Filters our any messages in |messagesJSON| with the given collpase key. It returns the + * filtered list. + */ + private static JSONArray filterMessageBasedOnCollapseKey(JSONArray messages, String collapseKey) + throws JSONException { + JSONArray filteredMessages = new JSONArray(); + for (int i = 0; i < messages.length(); i++) { + JSONObject message = messages.getJSONObject(i); + if (GCMMessage.peekCollapseKey(message).equals(collapseKey)) { + Log.i(TAG, + "Dropping GCM Message due to collapse key collision. Sender id:" + + GCMMessage.peekSenderId(message)); + continue; + } + filteredMessages.put(message); + } + return filteredMessages; + } + + /** + * Reads messages stored using persistMessage() for |subscriptionId|. No + * more than |MESSAGES_QUEUE_SIZE| are returned. + * @param subscriptionId The subscription id of the stored messages. + * @return The messages stored. Returns an empty list in case of failure. + */ + public static GCMMessage[] readMessages(String subscriptionId) { + // TODO(https://crbug.com/882887): Make sure to delete subscription + // information when the token goes. + Context context = ContextUtils.getApplicationContext(); + SharedPreferences sharedPrefs = + context.getSharedPreferences(InstanceIDBridge.PREF_PACKAGE, Context.MODE_PRIVATE); + + // Default is an empty queue if no messages are queued for this subscription. + String queueString = sharedPrefs.getString(subscriptionId, "[]"); + try { + JSONArray queueJSON = new JSONArray(queueString); + List<GCMMessage> messages = new ArrayList<>(); + for (int i = 0; i < queueJSON.length(); i++) { + try { + GCMMessage persistedMessage = + GCMMessage.createFromJSON(queueJSON.getJSONObject(i)); + if (persistedMessage == null) { + Log.e(TAG, + "Persisted GCM Message is invalid. Sender id:" + + GCMMessage.peekSenderId(queueJSON.getJSONObject(i))); + continue; + } + messages.add(persistedMessage); + } catch (JSONException e) { + Log.e(TAG, + "Error when creating a GCMMessage from a JSONObject:" + e.getMessage()); + } + } + return messages.toArray(new GCMMessage[messages.size()]); + } catch (JSONException e) { + Log.e(TAG, + "Error when parsing the persisted message queue for subscriber:" + + subscriptionId); + } + return new GCMMessage[0]; + } + @VisibleForTesting public static void overrideSubscriberForTesting(GoogleCloudMessagingSubscriber subscriber) { assert sInstance != null;
diff --git a/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMMessage.java b/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMMessage.java index f950ac3..bf409f2d 100644 --- a/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMMessage.java +++ b/components/gcm_driver/android/java/src/org/chromium/components/gcm_driver/GCMMessage.java
@@ -183,6 +183,28 @@ } /** + * Returns the collapse key of GCMMessage encoded as a JSONObject. Returns null if non exists. + * Assumes that the JSONObject has previously been created through + * {@link #toJSON}. + * @param jsonObject The JSONObject encoding the GCMMessage + * @return The collapse key. Null if non-exists. + */ + public static String peekCollapseKey(JSONObject jsonObject) { + return jsonObject.optString(KEY_COLLAPSE_KEY, null); + } + + /** + * Returns the sender id of GCMMessage encoded as a JSONObject. Returns null if non exists. + * Assumes that the JSONObject has previously been created through + * {@link #toJSON}. + * @param jsonObject The JSONObject encoding the GCMMessage + * @return The collapse key. Null if non-exists. + */ + public static String peekSenderId(JSONObject jsonObject) { + return jsonObject.optString(KEY_SENDER_ID, null); + } + + /** * Serializes the contents of this GCM Message to a new bundle that can be stored, for example * for purposes of scheduling a job. Only methods available in BaseBundle may be used here, * as it may have to be converted to a PersistableBundle. @@ -196,7 +218,7 @@ * Serializes the contents of this GCM Message to a JSONObject such that it * could be stored as a String. */ - public JSONObject toJSON() throws JSONException { + public JSONObject toJSON() { return serialize(new JSONWriter()); }
diff --git a/components/gcm_driver/android/junit/src/org/chromium/components/gcm_driver/GCMDriverTest.java b/components/gcm_driver/android/junit/src/org/chromium/components/gcm_driver/GCMDriverTest.java new file mode 100644 index 0000000..03a15e8 --- /dev/null +++ b/components/gcm_driver/android/junit/src/org/chromium/components/gcm_driver/GCMDriverTest.java
@@ -0,0 +1,108 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.components.gcm_driver; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import android.os.Bundle; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; + +/** + * Unit tests for GCMDriver. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class GCMDriverTest { + /** + * Tests that GCM messages are persisted and read. + */ + @Test + public void testReadingPersistedMessage() { + final String subscriptionId = "subscriptionId"; + final String anotherSubscriptionId = "AnotherSubscriptionId"; + + Bundle extras = new Bundle(); + extras.putString("subtype", "MyAppId"); + extras.putString("collapse_key", "CollapseKey"); + GCMMessage message = new GCMMessage("MySenderId", extras); + GCMDriver.persistMessage(subscriptionId, message); + + GCMMessage messages[] = GCMDriver.readMessages(subscriptionId); + assertEquals(1, messages.length); + assertEquals(message.getSenderId(), messages[0].getSenderId()); + + messages = GCMDriver.readMessages(anotherSubscriptionId); + assertEquals(0, messages.length); + } + + /** + * Tests that only MESSAGES_QUEUE_SIZE messages are kept. + */ + @Test + public void testPersistingMessageCount() { + // This tests persists MESSAGES_QUEUE_SIZE+extraMessagesCount messages + // and checks if only the most recent |MESSAGES_QUEUE_SIZE| are read. + // |collapse_key| is used to distinguish between messages for + // simplicity. + final String subscriptionId = "subscriptionId"; + final String collapseKeyPrefix = "subscriptionId"; + final int extraMessagesCount = 5; + + // Persist |MESSAGES_QUEUE_SIZE| + |extraMessagesCount| messages. + for (int i = 0; i < GCMDriver.MESSAGES_QUEUE_SIZE + extraMessagesCount; i++) { + Bundle extras = new Bundle(); + extras.putString("subtype", "MyAppId"); + extras.putString("collapse_key", collapseKeyPrefix + i); + GCMMessage message = new GCMMessage("MySenderId", extras); + GCMDriver.persistMessage(subscriptionId, message); + } + // Check that only the most recent |MESSAGES_QUEUE_SIZE| are persisted. + GCMMessage messages[] = GCMDriver.readMessages(subscriptionId); + assertEquals(GCMDriver.MESSAGES_QUEUE_SIZE, messages.length); + for (int i = 0; i < GCMDriver.MESSAGES_QUEUE_SIZE; i++) { + assertEquals( + collapseKeyPrefix + (i + extraMessagesCount), messages[i].getCollapseKey()); + } + } + + /** + * Tests that messages with the same collapse key override each other. + */ + @Test + public void testCollapseKeyCollision() { + final String subscriptionId = "subscriptionId"; + final String collapseKey = "collapseKey"; + final byte[] rawData1 = {0x00, 0x15, 0x30, 0x01}; + final byte[] rawData2 = {0x00, 0x15, 0x30, 0x02}; + + Bundle extras = new Bundle(); + extras.putString("subtype", "MyAppId"); + extras.putString("collapse_key", collapseKey); + extras.putByteArray("rawData", rawData1); + + // Persist a message and make sure it's persisted. + GCMMessage message1 = new GCMMessage("MySenderId", extras); + GCMDriver.persistMessage(subscriptionId, message1); + + GCMMessage messages[] = GCMDriver.readMessages(subscriptionId); + assertEquals(1, messages.length); + assertArrayEquals(rawData1, messages[0].getRawData()); + + // Persist another message with the same collapse key and another raw data. + extras.putByteArray("rawData", rawData2); + GCMMessage message2 = new GCMMessage("MySenderId", extras); + GCMDriver.persistMessage(subscriptionId, message2); + + messages = GCMDriver.readMessages(subscriptionId); + assertEquals(1, messages.length); + assertArrayEquals(rawData2, messages[0].getRawData()); + } +}
diff --git a/components/gcm_driver/instance_id/android/java/src/org/chromium/components/gcm_driver/instance_id/InstanceIDBridge.java b/components/gcm_driver/instance_id/android/java/src/org/chromium/components/gcm_driver/instance_id/InstanceIDBridge.java index e870684..3167195 100644 --- a/components/gcm_driver/instance_id/android/java/src/org/chromium/components/gcm_driver/instance_id/InstanceIDBridge.java +++ b/components/gcm_driver/instance_id/android/java/src/org/chromium/components/gcm_driver/instance_id/InstanceIDBridge.java
@@ -27,7 +27,7 @@ @JNINamespace("instance_id") public class InstanceIDBridge { private static final String FCM_LAZY_SUBSCRIPTIONS = "fcm_lazy_subscriptions"; - private static final String PREF_PACKAGE = "org.chromium.components.gcm_driver.instance_id"; + public static final String PREF_PACKAGE = "org.chromium.components.gcm_driver.instance_id"; private final String mSubtype; private long mNativeInstanceIDAndroid; /**
diff --git a/components/history/OWNERS b/components/history/OWNERS index 499c60e..4dbd651 100644 --- a/components/history/OWNERS +++ b/components/history/OWNERS
@@ -1,4 +1,2 @@ sdefresne@chromium.org sky@chromium.org - -per-file download_database.*=benjhayden@chromium.org
diff --git a/components/history/core/browser/download_database.cc b/components/history/core/browser/download_database.cc index df40855..49a80db 100644 --- a/components/history/core/browser/download_database.cc +++ b/components/history/core/browser/download_database.cc
@@ -43,7 +43,7 @@ DROPPED_REASON_MAX }; -#if defined(OS_POSIX) +#if defined(OS_POSIX) || defined(OS_FUCHSIA) // Binds/reads the given file path to the given column of the given statement. void BindFilePath(sql::Statement& statement,
diff --git a/components/payments/content/android/BUILD.gn b/components/payments/content/android/BUILD.gn index 398ed5c..65ddf25 100644 --- a/components/payments/content/android/BUILD.gn +++ b/components/payments/content/android/BUILD.gn
@@ -50,6 +50,7 @@ ] deps = [ "//base:base_java", + "//components/payments/mojom:mojom_java", "//content/public/android:content_java", "//mojo/public/java:bindings_java", "//third_party/blink/public/mojom:android_mojo_bindings_java",
diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn index 706bf11..44e34ae 100644 --- a/components/policy/core/common/BUILD.gn +++ b/components/policy/core/common/BUILD.gn
@@ -160,6 +160,8 @@ "//extensions/buildflags", "//google_apis", "//net", + "//services/identity/public/cpp", + "//services/identity/public/cpp:cpp_types", "//services/network/public/cpp", "//third_party/libxml", "//third_party/re2",
diff --git a/components/policy/core/common/cloud/DEPS b/components/policy/core/common/cloud/DEPS new file mode 100644 index 0000000..692812d --- /dev/null +++ b/components/policy/core/common/cloud/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+services/identity/public/cpp", +]
diff --git a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc index 0c05c2c..e672fcb7 100644 --- a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc +++ b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.cc
@@ -14,7 +14,10 @@ #include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_urls.h" #include "google_apis/gaia/google_service_auth_error.h" -#include "google_apis/gaia/oauth2_token_service.h" +#include "services/identity/public/cpp/access_token_fetcher.h" +#include "services/identity/public/cpp/access_token_info.h" +#include "services/identity/public/cpp/identity_manager.h" +#include "services/identity/public/cpp/scope_set.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #if !defined(OS_ANDROID) @@ -34,61 +37,55 @@ // On Android, we use a special API to allow us to fetch a token for an account // that is not yet logged in to allow fetching the token before the sign-in // process is finished. -class CloudPolicyClientRegistrationHelper::TokenServiceHelper - : public OAuth2TokenService::Consumer { +class CloudPolicyClientRegistrationHelper::IdentityManagerHelper { public: - TokenServiceHelper(); + IdentityManagerHelper() = default; - void FetchAccessToken( - OAuth2TokenService* token_service, - const std::string& username, - const StringCallback& callback); + void FetchAccessToken(identity::IdentityManager* identity_manager, + const std::string& username, + const StringCallback& callback); private: - // OAuth2TokenService::Consumer implementation: - void OnGetTokenSuccess( - const OAuth2TokenService::Request* request, - const OAuth2AccessTokenConsumer::TokenResponse& token_response) override; - void OnGetTokenFailure(const OAuth2TokenService::Request* request, - const GoogleServiceAuthError& error) override; + void OnAccessTokenFetchComplete(GoogleServiceAuthError error, + identity::AccessTokenInfo token_info); StringCallback callback_; - std::unique_ptr<OAuth2TokenService::Request> token_request_; + std::unique_ptr<identity::AccessTokenFetcher> access_token_fetcher_; }; -CloudPolicyClientRegistrationHelper::TokenServiceHelper::TokenServiceHelper() - : OAuth2TokenService::Consumer("cloud_policy") {} - -void CloudPolicyClientRegistrationHelper::TokenServiceHelper::FetchAccessToken( - OAuth2TokenService* token_service, - const std::string& account_id, - const StringCallback& callback) { - DCHECK(!token_request_); - // Either the caller must supply a username, or the user must be signed in - // already. +void CloudPolicyClientRegistrationHelper::IdentityManagerHelper:: + FetchAccessToken(identity::IdentityManager* identity_manager, + const std::string& account_id, + const StringCallback& callback) { + DCHECK(!access_token_fetcher_); + // The caller must supply a username. DCHECK(!account_id.empty()); - DCHECK(token_service->RefreshTokenIsAvailable(account_id)); + DCHECK(identity_manager->HasAccountWithRefreshToken(account_id)); callback_ = callback; - OAuth2TokenService::ScopeSet scopes; + identity::ScopeSet scopes; scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth); scopes.insert(GaiaConstants::kOAuthWrapBridgeUserInfoScope); - token_request_ = token_service->StartRequest(account_id, scopes, this); + + access_token_fetcher_ = identity_manager->CreateAccessTokenFetcherForAccount( + account_id, "cloud_policy", scopes, + base::BindOnce(&CloudPolicyClientRegistrationHelper:: + IdentityManagerHelper::OnAccessTokenFetchComplete, + base::Unretained(this)), + identity::AccessTokenFetcher::Mode::kImmediate); } -void CloudPolicyClientRegistrationHelper::TokenServiceHelper::OnGetTokenSuccess( - const OAuth2TokenService::Request* request, - const OAuth2AccessTokenConsumer::TokenResponse& token_response) { - DCHECK_EQ(token_request_.get(), request); - callback_.Run(token_response.access_token); -} +void CloudPolicyClientRegistrationHelper::IdentityManagerHelper:: + OnAccessTokenFetchComplete(GoogleServiceAuthError error, + identity::AccessTokenInfo token_info) { + DCHECK(access_token_fetcher_); + access_token_fetcher_.reset(); -void CloudPolicyClientRegistrationHelper::TokenServiceHelper::OnGetTokenFailure( - const OAuth2TokenService::Request* request, - const GoogleServiceAuthError& error) { - DCHECK_EQ(token_request_.get(), request); - callback_.Run(""); + if (error.state() == GoogleServiceAuthError::NONE) + callback_.Run(token_info.token); + else + callback_.Run(""); } #if !defined(OS_ANDROID) @@ -163,9 +160,8 @@ client_->RemoveObserver(this); } - void CloudPolicyClientRegistrationHelper::StartRegistration( - OAuth2TokenService* token_service, + identity::IdentityManager* identity_manager, const std::string& account_id, const base::Closure& callback) { DVLOG(1) << "Starting registration process with account_id"; @@ -173,10 +169,9 @@ callback_ = callback; client_->AddObserver(this); - token_service_helper_.reset(new TokenServiceHelper()); - token_service_helper_->FetchAccessToken( - token_service, - account_id, + identity_manager_helper_.reset(new IdentityManagerHelper()); + identity_manager_helper_->FetchAccessToken( + identity_manager, account_id, base::Bind(&CloudPolicyClientRegistrationHelper::OnTokenFetched, base::Unretained(this))); } @@ -224,7 +219,7 @@ #if !defined(OS_ANDROID) login_token_helper_.reset(); #endif - token_service_helper_.reset(); + identity_manager_helper_.reset(); if (access_token.empty()) { DLOG(WARNING) << "Could not fetch access token for "
diff --git a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.h b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.h index 8b8b671..2caa073 100644 --- a/components/policy/core/common/cloud/cloud_policy_client_registration_helper.h +++ b/components/policy/core/common/cloud/cloud_policy_client_registration_helper.h
@@ -19,7 +19,9 @@ #include "components/policy/policy_export.h" #include "components/policy/proto/device_management_backend.pb.h" -class OAuth2TokenService; +namespace identity { +class IdentityManager; +} namespace network { class SharedURLLoaderFactory; @@ -41,13 +43,12 @@ ~CloudPolicyClientRegistrationHelper() override; // Starts the client registration process. This version uses the - // supplied OAuth2TokenService to mint the new token for the userinfo + // supplied IdentityManager to mint the new token for the userinfo // and DM services, using the |account_id|. // |callback| is invoked when the registration is complete. - void StartRegistration( - OAuth2TokenService* token_service, - const std::string& account_id, - const base::Closure& callback); + void StartRegistration(identity::IdentityManager* identity_manager, + const std::string& account_id, + const base::Closure& callback); // Starts the device registration with an token enrollment process. // |callback| is invoked when the registration is complete. @@ -67,7 +68,7 @@ #endif private: - class TokenServiceHelper; + class IdentityManagerHelper; #if !defined(OS_ANDROID) class LoginTokenHelper; #endif @@ -86,11 +87,11 @@ // Invoked when the registration request has been completed. void RequestCompleted(); - // Internal helper class that uses OAuth2TokenService to fetch an OAuth + // Internal helper class that uses IdentityManager to fetch an OAuth // access token. On desktop, this is only used after the user has signed in - // desktop platforms use LoginTokenHelper for policy fetches performed before // signin is complete. - std::unique_ptr<TokenServiceHelper> token_service_helper_; + std::unique_ptr<IdentityManagerHelper> identity_manager_helper_; #if !defined(OS_ANDROID) // Special desktop-only helper to fetch an OAuth access token prior to
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index e6e529a5..b8cdde0 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -844,6 +844,9 @@ // TPM status information. optional TpmStatusInfo tpm_status_info = 23; + + // Whether hardware write protect switch is on. + optional bool write_protect_switch = 24; } message OsUpdateStatus { @@ -1685,7 +1688,11 @@ message TpmStatusInfo { optional bool enabled = 1; optional bool owned = 2; - optional bool initialized = 3; + // This field was previously named "initialized", but that's not a valid name + // for a proto field since it generates isInitialized method for the Java + // binding which collides with the isInitialized method that exists for all + // Java protos. + optional bool tpm_initialized = 3; optional bool attestation_prepared = 4; optional bool attestation_enrolled = 5; optional int32 dictionary_attack_counter = 6;
diff --git a/components/signin/core/browser/android/BUILD.gn b/components/signin/core/browser/android/BUILD.gn index f52ad9c7..61fb92b 100644 --- a/components/signin/core/browser/android/BUILD.gn +++ b/components/signin/core/browser/android/BUILD.gn
@@ -64,6 +64,8 @@ "//base:base_java", "//base:base_java_test_support", "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_support_test_runner:rules_java", + "//third_party/android_support_test_runner:runner_java", "//third_party/jsr-305:jsr_305_javalib", "//third_party/junit", ]
diff --git a/components/sync_wifi/OWNERS b/components/sync_wifi/OWNERS index 10a5308..261ab18 100644 --- a/components/sync_wifi/OWNERS +++ b/components/sync_wifi/OWNERS
@@ -1 +1 @@ -# stevenjb@chromium.org +file://components/sync/OWNERS
diff --git a/components/tracing/common/tracing_switches.cc b/components/tracing/common/tracing_switches.cc index a55082a..3adedc9b 100644 --- a/components/tracing/common/tracing_switches.cc +++ b/components/tracing/common/tracing_switches.cc
@@ -6,6 +6,10 @@ namespace switches { +// Enables background and upload trace to trace-upload-url. Trigger rules are +// pass as an argument. +const char kEnableBackgroundTracing[] = "enable-background-tracing"; + // Causes TRACE_EVENT flags to be recorded from startup. // This flag will be ignored if --trace-startup or --trace-shutdown is provided. const char kTraceConfigFile[] = "trace-config-file";
diff --git a/components/tracing/common/tracing_switches.h b/components/tracing/common/tracing_switches.h index e8ae2a4..96468105 100644 --- a/components/tracing/common/tracing_switches.h +++ b/components/tracing/common/tracing_switches.h
@@ -9,6 +9,7 @@ namespace switches { +TRACING_EXPORT extern const char kEnableBackgroundTracing[]; TRACING_EXPORT extern const char kTraceConfigFile[]; TRACING_EXPORT extern const char kTraceShutdown[]; TRACING_EXPORT extern const char kTraceShutdownFile[];
diff --git a/components/translate/content/renderer/translate_helper.cc b/components/translate/content/renderer/translate_helper.cc index ae95835a..a12241e9 100644 --- a/components/translate/content/renderer/translate_helper.cc +++ b/components/translate/content/renderer/translate_helper.cc
@@ -74,7 +74,10 @@ world_id_(world_id), extension_scheme_(extension_scheme), binding_(this), - weak_method_factory_(this) {} + weak_method_factory_(this) { + translate_task_runner_ = this->render_frame()->GetTaskRunner( + blink::TaskType::kInternalTranslation); +} TranslateHelper::~TranslateHelper() { } @@ -386,7 +389,7 @@ } // The translation is still pending, check again later. - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + translate_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TranslateHelper::CheckTranslateStatus, weak_method_factory_.GetWeakPtr()), @@ -430,7 +433,7 @@ return; } // Check the status of the translation. - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + translate_task_runner_->PostDelayedTask( FROM_HERE, base::BindOnce(&TranslateHelper::CheckTranslateStatus, weak_method_factory_.GetWeakPtr()),
diff --git a/components/translate/content/renderer/translate_helper.h b/components/translate/content/renderer/translate_helper.h index 14662b4..494985d0 100644 --- a/components/translate/content/renderer/translate_helper.h +++ b/components/translate/content/renderer/translate_helper.h
@@ -163,6 +163,10 @@ // The URL scheme for translate extensions. std::string extension_scheme_; + // The task runner responsible for the translation task, freezing it + // when the frame is backgrounded. + scoped_refptr<base::SingleThreadTaskRunner> translate_task_runner_; + // The Mojo pipe for communication with the browser process. Due to a // refactor, the other end of the pipe is now attached to a // LanguageDetectionTabHelper (which implements the ContentTranslateDriver
diff --git a/components/ui_devtools/views/BUILD.gn b/components/ui_devtools/views/BUILD.gn index 7aa5347..017e97a5 100644 --- a/components/ui_devtools/views/BUILD.gn +++ b/components/ui_devtools/views/BUILD.gn
@@ -41,6 +41,7 @@ } sources = [ + "overlay_agent_unittest.cc", "ui_devtools_unittest.cc", "view_element_unittest.cc", "widget_element_unittest.cc", @@ -54,6 +55,7 @@ "//skia", "//testing/gtest", "//ui/aura", + "//ui/aura:test_support", "//ui/events:test_support", "//ui/views", "//ui/views:test_support",
diff --git a/components/ui_devtools/views/overlay_agent_aura.cc b/components/ui_devtools/views/overlay_agent_aura.cc index 7dfda42..a374ebb 100644 --- a/components/ui_devtools/views/overlay_agent_aura.cc +++ b/components/ui_devtools/views/overlay_agent_aura.cc
@@ -14,8 +14,6 @@ #include "ui/aura/client/screen_position_client.h" #include "ui/aura/env.h" #include "ui/compositor/paint_recorder.h" -#include "ui/display/display.h" -#include "ui/display/screen.h" #include "ui/events/event.h" #include "ui/gfx/canvas.h" #include "ui/gfx/render_text.h" @@ -491,6 +489,10 @@ } Response OverlayAgentAura::HighlightNode(int node_id, bool show_size) { + UIElement* element = dom_agent()->GetElementFromNodeId(node_id); + if (!element) + return Response::Error("No node found with that id"); + if (!layer_for_highlighting_) { layer_for_highlighting_.reset(new ui::Layer(ui::LayerType::LAYER_TEXTURED)); layer_for_highlighting_->set_name("HighlightingLayer"); @@ -498,18 +500,9 @@ layer_for_highlighting_->SetFillsBoundsOpaquely(false); } - UIElement* element = dom_agent()->GetElementFromNodeId(node_id); - std::pair<gfx::NativeWindow, gfx::Rect> window_and_bounds = - element - ? element->GetNodeWindowAndBounds() - : std::make_pair<gfx::NativeWindow, gfx::Rect>(nullptr, gfx::Rect()); - - if (!window_and_bounds.first) - return Response::Error("No node found with that id"); - highlight_rect_config_ = HighlightRectsConfiguration::NO_DRAW; show_size_on_canvas_ = show_size; - UpdateHighlight(window_and_bounds); + UpdateHighlight(element->GetNodeWindowAndBounds()); if (!layer_for_highlighting_->visible()) layer_for_highlighting_->SetVisible(true); @@ -519,9 +512,6 @@ void OverlayAgentAura::UpdateHighlight( const std::pair<gfx::NativeWindow, gfx::Rect>& window_and_bounds) { - display::Display display = - display::Screen::GetScreen()->GetDisplayNearestWindow( - window_and_bounds.first); gfx::NativeWindow root = window_and_bounds.first->GetRootWindow(); layer_for_highlighting_->SetBounds(root->bounds()); layer_for_highlighting_->SchedulePaint(root->bounds());
diff --git a/components/ui_devtools/views/overlay_agent_aura.h b/components/ui_devtools/views/overlay_agent_aura.h index 88e99848..d5341de9 100644 --- a/components/ui_devtools/views/overlay_agent_aura.h +++ b/components/ui_devtools/views/overlay_agent_aura.h
@@ -60,15 +60,22 @@ // no valid target is found. int FindElementIdTargetedByPoint(ui::LocatedEvent* event) const; - // Shows the distances between the nodes identified by |pinned_id| and - // |element_id| in the highlight overlay. - void ShowDistancesInHighlightOverlay(int pinned_id, int element_id); - private: + FRIEND_TEST_ALL_PREFIXES(OverlayAgentTest, + MouseEventsGenerateFEEventsInInspectMode); + FRIEND_TEST_ALL_PREFIXES(OverlayAgentTest, HighlightNonexistentNode); + FRIEND_TEST_ALL_PREFIXES(OverlayAgentTest, HighlightWidget); +#if defined(USE_AURA) + FRIEND_TEST_ALL_PREFIXES(OverlayAgentTest, HighlightWindow); +#endif protocol::Response HighlightNode(int node_id, bool show_size = false); void UpdateHighlight( const std::pair<gfx::NativeWindow, gfx::Rect>& window_and_bounds); + // Shows the distances between the nodes identified by |pinned_id| and + // |element_id| in the highlight overlay. + void ShowDistancesInHighlightOverlay(int pinned_id, int element_id); + // ui:EventHandler: void OnMouseEvent(ui::MouseEvent* event) override; void OnKeyEvent(ui::KeyEvent* event) override; @@ -78,6 +85,8 @@ void OnDeviceScaleFactorChanged(float old_device_scale_factor, float new_device_scale_factor) override {} + ui::Layer* layer_for_highlighting() { return layer_for_highlighting_.get(); } + std::unique_ptr<gfx::RenderText> render_text_; bool show_size_on_canvas_ = false; HighlightRectsConfiguration highlight_rect_config_;
diff --git a/components/ui_devtools/views/overlay_agent_unittest.cc b/components/ui_devtools/views/overlay_agent_unittest.cc new file mode 100644 index 0000000..a349ad7 --- /dev/null +++ b/components/ui_devtools/views/overlay_agent_unittest.cc
@@ -0,0 +1,387 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/ui_devtools/views/overlay_agent_aura.h" + +#include "components/ui_devtools/ui_devtools_unittest_utils.h" +#include "components/ui_devtools/ui_element.h" +#include "components/ui_devtools/views/dom_agent_aura.h" +#include "components/ui_devtools/views/overlay_agent_aura.h" +#include "components/ui_devtools/views/view_element.h" +#include "components/ui_devtools/views/widget_element.h" +#include "components/ui_devtools/views/window_element.h" +#include "ui/events/base_event_utils.h" +#include "ui/events/event_constants.h" +#include "ui/events/test/event_generator.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/views/test/views_test_base.h" +#include "ui/views/window/non_client_view.h" + +#if defined(USE_AURA) +#include "ui/aura/test/test_window_delegate.h" +#include "ui/aura/window.h" +#endif + +namespace ui_devtools { + +namespace { +const SkColor kBackgroundColor = 0; + +gfx::Point GetOriginInScreen(views::View* view) { + gfx::Point point(0, 0); // Since it's local bounds, origin is always 0,0. + views::View::ConvertPointToScreen(view, &point); + return point; +} + +} // namespace + +class OverlayAgentTest : public views::ViewsTestBase { + public: + void SetUp() override { + fake_frontend_channel_ = std::make_unique<FakeFrontendChannel>(); + uber_dispatcher_ = std::make_unique<protocol::UberDispatcher>( + fake_frontend_channel_.get()); + dom_agent_ = std::make_unique<DOMAgentAura>(); + dom_agent_->Init(uber_dispatcher_.get()); + overlay_agent_ = std::make_unique<OverlayAgentAura>(dom_agent_.get()); + overlay_agent_->Init(uber_dispatcher_.get()); + overlay_agent_->enable(); + views::ViewsTestBase::SetUp(); + } + + void TearDown() override { + // Ensure DOMAgent shuts down before the root window closes to avoid + // lifetime issues. + overlay_agent_.reset(); + dom_agent_.reset(); + uber_dispatcher_.reset(); + fake_frontend_channel_.reset(); + views::ViewsTestBase::TearDown(); + } + + protected: + std::unique_ptr<ui::MouseEvent> MouseEventAtRootLocation(gfx::Point p) { + auto event = std::make_unique<ui::MouseEvent>(ui::ET_MOUSE_MOVED, p, p, + ui::EventTimeForNow(), + ui::EF_NONE, ui::EF_NONE); + ui::Event::DispatcherApi(event.get()).set_target(GetContext()); + return event; + } + views::View* GetViewAtPoint(int x, int y) { + gfx::Point point(x, y); + int element_id = overlay_agent()->FindElementIdTargetedByPoint( + MouseEventAtRootLocation(point).get()); + UIElement* element = dom_agent()->GetElementFromNodeId(element_id); + DCHECK_EQ(element->type(), UIElementType::VIEW); + return UIElement::GetBackingElement<views::View, ViewElement>(element); + } + int GetOverlayNodeHighlightRequestedCount(int node_id) { + return frontend_channel()->CountProtocolNotificationMessage( + base::StringPrintf( + "{\"method\":\"Overlay.nodeHighlightRequested\",\"params\":{" + "\"nodeId\":%d}}", + node_id)); + } + + int GetOverlayInspectNodeRequestedCount(int node_id) { + return frontend_channel()->CountProtocolNotificationMessage( + base::StringPrintf( + "{\"method\":\"Overlay.inspectNodeRequested\",\"params\":{" + "\"backendNodeId\":%d}}", + node_id)); + } + + std::unique_ptr<views::Widget> CreateWidget() { + auto widget = std::make_unique<views::Widget>(); + views::Widget::InitParams params; + params.delegate = nullptr; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.bounds = gfx::Rect(0, 0, 400, 400); + params.parent = GetContext(); + widget->Init(params); + widget->Show(); + return widget; + } + + DOMAgent* dom_agent() { return dom_agent_.get(); } + OverlayAgentAura* overlay_agent() { return overlay_agent_.get(); } + FakeFrontendChannel* frontend_channel() { + return fake_frontend_channel_.get(); + } + + private: + std::unique_ptr<protocol::UberDispatcher> uber_dispatcher_; + std::unique_ptr<FakeFrontendChannel> fake_frontend_channel_; + std::unique_ptr<DOMAgentAura> dom_agent_; + std::unique_ptr<OverlayAgentAura> overlay_agent_; +}; + +#if defined(USE_AURA) +TEST_F(OverlayAgentTest, FindElementIdTargetedByPointWindow) { + // Windows without delegates won't act as an event handler. + aura::test::TestWindowDelegate delegate; + std::unique_ptr<aura::Window> window = std::make_unique<aura::Window>( + &delegate, aura::client::WINDOW_TYPE_NORMAL); + window->Init(ui::LAYER_NOT_DRAWN); + window->SetBounds(GetContext()->bounds()); + GetContext()->AddChild(window.get()); + window->Show(); + + std::unique_ptr<protocol::DOM::Node> root; + dom_agent()->getDocument(&root); + + int element_id = overlay_agent()->FindElementIdTargetedByPoint( + MouseEventAtRootLocation(gfx::Point(1, 1)).get()); + UIElement* element = dom_agent()->GetElementFromNodeId(element_id); + DCHECK_EQ(element->type(), UIElementType::WINDOW); + aura::Window* element_window = + UIElement::GetBackingElement<aura::Window, WindowElement>(element); + EXPECT_EQ(element_window, window.get()); + + gfx::Point out_of_bounds = + window->bounds().bottom_right() + gfx::Vector2d(20, 20); + EXPECT_EQ(0, overlay_agent()->FindElementIdTargetedByPoint( + MouseEventAtRootLocation(out_of_bounds).get())); +} +#endif + +TEST_F(OverlayAgentTest, FindElementIdTargetedByPointViews) { + std::unique_ptr<views::Widget> widget = CreateWidget(); + + std::unique_ptr<protocol::DOM::Node> root; + dom_agent()->getDocument(&root); + + views::View* contents_view = widget->GetContentsView(); + contents_view->RemoveAllChildViews(true); + + views::View* child_1 = new views::View; + views::View* child_2 = new views::View; + + // Not to scale! + // ------------------------ + // | contents_view | + // | ---------- | + // | |child_1 |------- | + // | | | | | + // | ---------- | | + // | |child_2| | + // | --------- | + // | | + // ------------------------ + contents_view->AddChildView(child_2); + contents_view->AddChildView(child_1); + child_1->SetBounds(20, 20, 100, 100); + child_2->SetBounds(90, 50, 100, 100); + + EXPECT_EQ(GetViewAtPoint(1, 1), widget->GetContentsView()); + EXPECT_EQ(GetViewAtPoint(21, 21), child_1); + EXPECT_EQ(GetViewAtPoint(170, 130), child_2); + // At the overlap. + EXPECT_EQ(GetViewAtPoint(110, 110), child_1); +} + +TEST_F(OverlayAgentTest, HighlightRects) { + const struct { + std::string name; + gfx::Rect first_element_bounds; + gfx::Rect second_element_bounds; + HighlightRectsConfiguration expected_configuration; + } kTestCases[] = { + {"R1_CONTAINS_R2", gfx::Rect(1, 1, 100, 100), gfx::Rect(2, 2, 50, 50), + R1_CONTAINS_R2}, + {"R1_HORIZONTAL_FULL_LEFT_R2", gfx::Rect(1, 1, 50, 50), + gfx::Rect(60, 1, 60, 60), R1_HORIZONTAL_FULL_LEFT_R2}, + {"R1_TOP_FULL_LEFT_R2", gfx::Rect(30, 30, 50, 50), + gfx::Rect(100, 100, 50, 50), R1_TOP_FULL_LEFT_R2}, + {"R1_BOTTOM_FULL_LEFT_R2", gfx::Rect(100, 100, 50, 50), + gfx::Rect(200, 50, 40, 40), R1_BOTTOM_FULL_LEFT_R2}, + {"R1_TOP_PARTIAL_LEFT_R2", gfx::Rect(100, 100, 50, 50), + gfx::Rect(120, 200, 50, 50), R1_TOP_PARTIAL_LEFT_R2}, + {"R1_BOTTOM_PARTIAL_LEFT_R2", gfx::Rect(50, 200, 100, 100), + gfx::Rect(100, 50, 50, 50), R1_BOTTOM_PARTIAL_LEFT_R2}, + {"R1_INTERSECTS_R2", gfx::Rect(100, 100, 50, 50), + gfx::Rect(120, 120, 50, 50), R1_INTERSECTS_R2}, + }; + for (const auto& test_case : kTestCases) { + SCOPED_TRACE(testing::Message() << "Case: " << test_case.name); + std::unique_ptr<views::Widget> widget = CreateWidget(); + + std::unique_ptr<protocol::DOM::Node> root; + dom_agent()->getDocument(&root); + + // Fish out the client view to serve as superview. Emptying out the content + // view and adding the subviews directly causes NonClientView's hit test to + // fail. + views::View* contents_view = widget->GetContentsView(); + DCHECK_EQ(contents_view->GetClassName(), + views::NonClientView::kViewClassName); + views::NonClientView* non_client_view = + static_cast<views::NonClientView*>(contents_view); + views::View* client_view = non_client_view->client_view(); + + views::View* child_1 = new views::View; + views::View* child_2 = new views::View; + client_view->AddChildView(child_1); + client_view->AddChildView(child_2); + child_1->SetBoundsRect(test_case.first_element_bounds); + child_2->SetBoundsRect(test_case.second_element_bounds); + + overlay_agent()->setInspectMode( + "searchForNode", protocol::Maybe<protocol::Overlay::HighlightConfig>()); + ui::test::EventGenerator generator(widget->GetNativeWindow()); + + // Highlight child 1. + generator.MoveMouseTo(GetOriginInScreen(child_1)); + // Click to pin it. + generator.PressLeftButton(); + // Highlight child 2. Now, the distance overlay is showing. + generator.MoveMouseTo(GetOriginInScreen(child_2)); + + EXPECT_EQ(test_case.expected_configuration, + overlay_agent()->highlight_rect_config()); + // If we don't explicitly stop inspecting, we'll leave ourselves as + // a pretarget handler for the root window and UAF in the next test. + // TODO(lgrey): Fix this when refactoring to support Mac. + overlay_agent()->setInspectMode( + "none", protocol::Maybe<protocol::Overlay::HighlightConfig>()); + } +} + +// Tests that the correct Overlay events are dispatched to the frontend when +// hovering and clicking over a UI element in inspect mode. +TEST_F(OverlayAgentTest, MouseEventsGenerateFEEventsInInspectMode) { + std::unique_ptr<views::Widget> widget = CreateWidget(); + + std::unique_ptr<protocol::DOM::Node> root; + dom_agent()->getDocument(&root); + + gfx::Point p(1, 1); + int node_id = overlay_agent()->FindElementIdTargetedByPoint( + MouseEventAtRootLocation(p).get()); + + EXPECT_EQ(0, GetOverlayInspectNodeRequestedCount(node_id)); + EXPECT_EQ(0, GetOverlayNodeHighlightRequestedCount(node_id)); + overlay_agent()->setInspectMode( + "searchForNode", protocol::Maybe<protocol::Overlay::HighlightConfig>()); + + // Moving the mouse cursor over the widget bounds should request a node + // highlight. + ui::test::EventGenerator generator(widget->GetNativeWindow()); + generator.MoveMouseBy(p.x(), p.y()); + + // 2 mouse events ET_MOUSE_ENTERED and ET_MOUSE_MOVED are generated. + EXPECT_EQ(2, GetOverlayNodeHighlightRequestedCount(node_id)); + EXPECT_EQ(0, GetOverlayInspectNodeRequestedCount(node_id)); + + // Clicking on the widget should pin that element. + generator.PressLeftButton(); + + // Pin parent node after mouse wheel moves up. + int parent_id = dom_agent()->GetParentIdOfNodeId(node_id); + EXPECT_NE(parent_id, overlay_agent()->pinned_id()); + generator.MoveMouseWheel(0, 1); + EXPECT_EQ(parent_id, overlay_agent()->pinned_id()); + + // Re-assign pin node. + node_id = parent_id; + + int inspect_node_notification_count = + GetOverlayInspectNodeRequestedCount(node_id); + + // Press escape to exit inspect mode. + generator.PressKey(ui::KeyboardCode::VKEY_ESCAPE, ui::EventFlags::EF_NONE); + + // Upon exiting inspect mode, the element is inspected and highlighted. + EXPECT_EQ(inspect_node_notification_count + 1, + GetOverlayInspectNodeRequestedCount(node_id)); + ui::Layer* highlighting_layer = overlay_agent()->layer_for_highlighting(); + EXPECT_EQ(kBackgroundColor, highlighting_layer->GetTargetColor()); + EXPECT_TRUE(highlighting_layer->visible()); + + int highlight_notification_count = + GetOverlayNodeHighlightRequestedCount(node_id); + inspect_node_notification_count = + GetOverlayInspectNodeRequestedCount(node_id); + + // Since inspect mode is exited, a subsequent mouse move should generate no + // nodeHighlightRequested or inspectNodeRequested events. + generator.MoveMouseBy(p.x(), p.y()); + EXPECT_EQ(highlight_notification_count, + GetOverlayNodeHighlightRequestedCount(node_id)); + EXPECT_EQ(inspect_node_notification_count, + GetOverlayInspectNodeRequestedCount(node_id)); +} + +TEST_F(OverlayAgentTest, HighlightNonexistentNode) { + std::unique_ptr<protocol::DOM::Node> root; + dom_agent()->getDocument(&root); + + const int id = 1000; + DCHECK(dom_agent()->GetElementFromNodeId(id) == nullptr); + + overlay_agent()->highlightNode(nullptr, id); + if (overlay_agent()->layer_for_highlighting()) { + EXPECT_FALSE(overlay_agent()->layer_for_highlighting()->parent()); + EXPECT_FALSE(overlay_agent()->layer_for_highlighting()->visible()); + } +} + +#if defined(USE_AURA) +TEST_F(OverlayAgentTest, HighlightWindow) { + std::unique_ptr<protocol::DOM::Node> root; + dom_agent()->getDocument(&root); + + std::unique_ptr<aura::Window> window = + std::make_unique<aura::Window>(nullptr, aura::client::WINDOW_TYPE_NORMAL); + window->Init(ui::LAYER_NOT_DRAWN); + window->SetBounds(gfx::Rect()); + GetContext()->AddChild(window.get()); + window->Show(); + + int window_id = + dom_agent() + ->element_root() + ->FindUIElementIdForBackendElement<aura::Window>(window.get()); + DCHECK_NE(window_id, 0); + + overlay_agent()->highlightNode(nullptr, window_id); + ui::Layer* highlightingLayer = overlay_agent()->layer_for_highlighting(); + DCHECK(highlightingLayer); + + EXPECT_EQ(highlightingLayer->parent(), GetContext()->layer()); + EXPECT_TRUE(highlightingLayer->visible()); + + overlay_agent()->hideHighlight(); + EXPECT_FALSE(highlightingLayer->visible()); +} +#endif + +TEST_F(OverlayAgentTest, HighlightWidget) { + std::unique_ptr<views::Widget> widget = CreateWidget(); + + std::unique_ptr<protocol::DOM::Node> root; + dom_agent()->getDocument(&root); + + int widget_id = + dom_agent() + ->element_root() + ->FindUIElementIdForBackendElement<views::Widget>(widget.get()); + DCHECK_NE(widget_id, 0); + + overlay_agent()->highlightNode(nullptr, widget_id); + ui::Layer* highlightingLayer = overlay_agent()->layer_for_highlighting(); + DCHECK(highlightingLayer); + +#if defined(USE_AURA) + EXPECT_EQ(highlightingLayer->parent(), GetContext()->layer()); +#else +// TODO(https://crbug.com/898280): Fix this for Mac. +#endif + EXPECT_TRUE(highlightingLayer->visible()); + + overlay_agent()->hideHighlight(); + EXPECT_FALSE(highlightingLayer->visible()); +} + +} // namespace ui_devtools
diff --git a/components/ui_devtools/views/ui_devtools_unittest.cc b/components/ui_devtools/views/ui_devtools_unittest.cc index 916e32d..853ee3b 100644 --- a/components/ui_devtools/views/ui_devtools_unittest.cc +++ b/components/ui_devtools/views/ui_devtools_unittest.cc
@@ -16,11 +16,6 @@ #include "components/ui_devtools/views/window_element.h" #include "ui/aura/client/window_parenting_client.h" #include "ui/aura/window_tree_host.h" -#include "ui/display/display.h" -#include "ui/events/base_event_utils.h" -#include "ui/events/event_constants.h" -#include "ui/events/test/event_generator.h" -#include "ui/views/background.h" #include "ui/views/test/views_test_base.h" #include "ui/views/widget/native_widget_private.h" #include "ui/views/widget/widget.h" @@ -32,8 +27,6 @@ using namespace ui_devtools::protocol; const int kDefaultChildNodeCount = -1; -const SkColor kBackgroundColor = 0; -const SkColor kBorderColor = SK_ColorBLUE; class TestView : public views::View { public: @@ -98,32 +91,6 @@ return window_node; } -ui::Layer* GetHighlightingLayer(aura::Window* root_window) { - for (auto* layer : root_window->layer()->children()) { - if (layer->name() == "HighlightingLayer") - return layer; - } - return nullptr; -} - -std::unique_ptr<DOM::RGBA> SkColorToRGBA(const SkColor& color) { - return DOM::RGBA::create() - .setA(SkColorGetA(color) / 255) - .setB(SkColorGetB(color)) - .setG(SkColorGetG(color)) - .setR(SkColorGetR(color)) - .build(); -} - -std::unique_ptr<Overlay::HighlightConfig> CreateHighlightConfig( - const SkColor& background_color, - const SkColor& border_color) { - return Overlay::HighlightConfig::create() - .setContentColor(SkColorToRGBA(background_color)) - .setBorderColor(SkColorToRGBA(border_color)) - .build(); -} - } // namespace class UIDevToolsTest : public views::ViewsTestBase { @@ -215,37 +182,6 @@ parent_id, node_id))); } - int GetOverlayNodeHighlightRequestedCount(int node_id) { - return frontend_channel()->CountProtocolNotificationMessage( - base::StringPrintf( - "{\"method\":\"Overlay.nodeHighlightRequested\",\"params\":{" - "\"nodeId\":%d}}", - node_id)); - } - - int GetOverlayInspectNodeRequestedCount(int node_id) { - return frontend_channel()->CountProtocolNotificationMessage( - base::StringPrintf( - "{\"method\":\"Overlay.inspectNodeRequested\",\"params\":{" - "\"backendNodeId\":%d}}", - node_id)); - } - - void HighlightNode(int node_id) { - overlay_agent_->highlightNode( - CreateHighlightConfig(kBackgroundColor, kBorderColor), node_id); - } - - void HideHighlight(int root_window_index) { - overlay_agent_->hideHighlight(); - DCHECK_GE(root_window_index, 0); - DCHECK_LE(root_window_index, - static_cast<int>(dom_agent()->root_windows().size())); - ASSERT_FALSE( - GetHighlightingLayer(dom_agent()->root_windows()[root_window_index]) - ->visible()); - } - FakeFrontendChannel* frontend_channel() { return fake_frontend_channel_.get(); } @@ -255,14 +191,6 @@ return dom_agent()->root_windows()[0]; } - std::unique_ptr<ui::MouseEvent> MouseEventAtRootLocation(gfx::Point p) { - auto event = std::make_unique<ui::MouseEvent>(ui::ET_MOUSE_MOVED, p, p, - ui::EventTimeForNow(), - ui::EF_NONE, ui::EF_NONE); - ui::Event::DispatcherApi(event.get()).set_target(GetPrimaryRootWindow()); - return event; - } - CSSAgent* css_agent() { return css_agent_.get(); } DOMAgentAura* dom_agent() { return dom_agent_.get(); } OverlayAgentAura* overlay_agent() { return overlay_agent_.get(); } @@ -281,383 +209,6 @@ DISALLOW_COPY_AND_ASSIGN(UIDevToolsTest); }; -// Tests that FindElementIdTargetedByPoint() returns a non-zero id when a UI -// element target exists. -TEST_F(UIDevToolsTest, FindElementIdTargetedByPoint) { - std::unique_ptr<views::Widget> widget( - CreateTestWidget(gfx::Rect(1, 1, 1, 1))); - std::unique_ptr<DOM::Node> root; - dom_agent()->getDocument(&root); - EXPECT_NE(0, overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(gfx::Point(1, 1)).get())); -} - -// Test case R1_CONTAINS_R2. -TEST_F(UIDevToolsTest, OneUIElementContainsAnother) { - const gfx::Rect outside_rect(1, 1, 100, 100); - std::unique_ptr<views::Widget> widget_outside(CreateTestWidget(outside_rect)); - - const gfx::Rect inside_rect(2, 2, 50, 50); - std::unique_ptr<views::Widget> widget_inside(CreateTestWidget(inside_rect)); - - std::unique_ptr<DOM::Node> root; - dom_agent()->getDocument(&root); - - int outside_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(outside_rect.origin()).get()); - int inside_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(inside_rect.origin()).get()); - overlay_agent()->ShowDistancesInHighlightOverlay(outside_rect_id, - inside_rect_id); - - HighlightRectsConfiguration highlight_rect_config = - overlay_agent()->highlight_rect_config(); - - // Swapping R1 and R2 shouldn't change |highlight_rect_config|. - overlay_agent()->ShowDistancesInHighlightOverlay(inside_rect_id, - outside_rect_id); - DCHECK_EQ(highlight_rect_config, overlay_agent()->highlight_rect_config()); - - const std::pair<aura::Window*, gfx::Rect> element_outside( - dom_agent() - ->GetElementFromNodeId(outside_rect_id) - ->GetNodeWindowAndBounds()); - - const std::pair<aura::Window*, gfx::Rect> element_inside( - dom_agent() - ->GetElementFromNodeId(inside_rect_id) - ->GetNodeWindowAndBounds()); - - EXPECT_EQ(element_outside.second, outside_rect); - EXPECT_EQ(element_inside.second, inside_rect); - DCHECK_EQ(overlay_agent()->highlight_rect_config(), - HighlightRectsConfiguration::R1_CONTAINS_R2); -} - -// Test case R1_HORIZONTAL_FULL_LEFT_R2. -TEST_F(UIDevToolsTest, OneUIElementStaysHorizontalAndLeftOfAnother) { - const gfx::Rect outside_rect(1, 1, 50, 50); - std::unique_ptr<views::Widget> widget_outside(CreateTestWidget(outside_rect)); - - const gfx::Rect inside_rect(60, 1, 60, 60); - std::unique_ptr<views::Widget> widget_inside(CreateTestWidget(inside_rect)); - - std::unique_ptr<DOM::Node> root; - dom_agent()->getDocument(&root); - - int outside_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(outside_rect.origin()).get()); - int inside_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(inside_rect.origin()).get()); - overlay_agent()->ShowDistancesInHighlightOverlay(outside_rect_id, - inside_rect_id); - - HighlightRectsConfiguration highlight_rect_config = - overlay_agent()->highlight_rect_config(); - - // Swapping R1 and R2 shouldn't change |highlight_rect_config|. - overlay_agent()->ShowDistancesInHighlightOverlay(inside_rect_id, - outside_rect_id); - DCHECK_EQ(highlight_rect_config, overlay_agent()->highlight_rect_config()); - - const std::pair<aura::Window*, gfx::Rect> element_outside( - dom_agent() - ->GetElementFromNodeId(outside_rect_id) - ->GetNodeWindowAndBounds()); - - const std::pair<aura::Window*, gfx::Rect> element_inside( - dom_agent() - ->GetElementFromNodeId(inside_rect_id) - ->GetNodeWindowAndBounds()); - - EXPECT_EQ(element_outside.second, outside_rect); - EXPECT_EQ(element_inside.second, inside_rect); - DCHECK_EQ(overlay_agent()->highlight_rect_config(), - HighlightRectsConfiguration::R1_HORIZONTAL_FULL_LEFT_R2); -} - -// Test case R1_TOP_FULL_LEFT_R2. -TEST_F(UIDevToolsTest, OneUIElementStaysFullyTopLeftOfAnother) { - const gfx::Rect top_left_rect(30, 30, 50, 50); - std::unique_ptr<views::Widget> widget_top_left( - CreateTestWidget(top_left_rect)); - - const gfx::Rect bottom_right_rect(100, 100, 50, 50); - std::unique_ptr<views::Widget> widget_bottom_right( - CreateTestWidget(bottom_right_rect)); - - std::unique_ptr<DOM::Node> root; - dom_agent()->getDocument(&root); - - int top_left_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(top_left_rect.origin()).get()); - int bottom_right_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(bottom_right_rect.origin()).get()); - overlay_agent()->ShowDistancesInHighlightOverlay(top_left_rect_id, - bottom_right_rect_id); - - HighlightRectsConfiguration highlight_rect_config = - overlay_agent()->highlight_rect_config(); - - // Swapping R1 and R2 shouldn't change |highlight_rect_config|. - overlay_agent()->ShowDistancesInHighlightOverlay(bottom_right_rect_id, - top_left_rect_id); - DCHECK_EQ(highlight_rect_config, overlay_agent()->highlight_rect_config()); - - const std::pair<aura::Window*, gfx::Rect> element_top_left( - dom_agent() - ->GetElementFromNodeId(top_left_rect_id) - ->GetNodeWindowAndBounds()); - - const std::pair<aura::Window*, gfx::Rect> element_bottom_right( - dom_agent() - ->GetElementFromNodeId(bottom_right_rect_id) - ->GetNodeWindowAndBounds()); - - EXPECT_EQ(element_top_left.second, top_left_rect); - EXPECT_EQ(element_bottom_right.second, bottom_right_rect); - DCHECK_EQ(overlay_agent()->highlight_rect_config(), - HighlightRectsConfiguration::R1_TOP_FULL_LEFT_R2); -} - -// Test case R1_BOTTOM_FULL_LEFT_R2. -TEST_F(UIDevToolsTest, OneUIElementStaysFullyBottomLeftOfAnother) { - const gfx::Rect bottom_left_rect(100, 100, 50, 50); - std::unique_ptr<views::Widget> widget_bottom_left( - CreateTestWidget(bottom_left_rect)); - - const gfx::Rect top_right_rect(200, 50, 40, 40); - std::unique_ptr<views::Widget> widget_top_right( - CreateTestWidget(top_right_rect)); - - std::unique_ptr<DOM::Node> root; - dom_agent()->getDocument(&root); - - int bottom_left_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(bottom_left_rect.origin()).get()); - int top_right_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(top_right_rect.origin()).get()); - overlay_agent()->ShowDistancesInHighlightOverlay(bottom_left_rect_id, - top_right_rect_id); - - HighlightRectsConfiguration highlight_rect_config = - overlay_agent()->highlight_rect_config(); - - // Swapping R1 and R2 shouldn't change |highlight_rect_config|. - overlay_agent()->ShowDistancesInHighlightOverlay(top_right_rect_id, - bottom_left_rect_id); - - DCHECK_EQ(highlight_rect_config, overlay_agent()->highlight_rect_config()); - - const std::pair<aura::Window*, gfx::Rect> element_top_left( - dom_agent() - ->GetElementFromNodeId(bottom_left_rect_id) - ->GetNodeWindowAndBounds()); - - const std::pair<aura::Window*, gfx::Rect> element_bottom_right( - dom_agent() - ->GetElementFromNodeId(top_right_rect_id) - ->GetNodeWindowAndBounds()); - - EXPECT_EQ(element_top_left.second, bottom_left_rect); - EXPECT_EQ(element_bottom_right.second, top_right_rect); - DCHECK_EQ(overlay_agent()->highlight_rect_config(), - HighlightRectsConfiguration::R1_BOTTOM_FULL_LEFT_R2); -} - -// Test case R1_TOP_PARTIAL_LEFT_R2. -TEST_F(UIDevToolsTest, OneUIElementStaysPartiallyTopLeftOfAnother) { - const gfx::Rect top_left_rect(100, 100, 50, 50); - std::unique_ptr<views::Widget> widget_top_left( - CreateTestWidget(top_left_rect)); - - const gfx::Rect bottom_right_rect(120, 200, 50, 50); - std::unique_ptr<views::Widget> widget_bottom_right( - CreateTestWidget(bottom_right_rect)); - - std::unique_ptr<DOM::Node> root; - dom_agent()->getDocument(&root); - - int top_left_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(top_left_rect.origin()).get()); - int bottom_right_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(bottom_right_rect.origin()).get()); - overlay_agent()->ShowDistancesInHighlightOverlay(top_left_rect_id, - bottom_right_rect_id); - - HighlightRectsConfiguration highlight_rect_config = - overlay_agent()->highlight_rect_config(); - - // Swapping R1 and R2 shouldn't change |highlight_rect_config|. - overlay_agent()->ShowDistancesInHighlightOverlay(bottom_right_rect_id, - top_left_rect_id); - DCHECK_EQ(highlight_rect_config, overlay_agent()->highlight_rect_config()); - - const std::pair<aura::Window*, gfx::Rect> element_top_left( - dom_agent() - ->GetElementFromNodeId(top_left_rect_id) - ->GetNodeWindowAndBounds()); - - const std::pair<aura::Window*, gfx::Rect> element_bottom_right( - dom_agent() - ->GetElementFromNodeId(bottom_right_rect_id) - ->GetNodeWindowAndBounds()); - - EXPECT_EQ(element_top_left.second, top_left_rect); - EXPECT_EQ(element_bottom_right.second, bottom_right_rect); - DCHECK_EQ(overlay_agent()->highlight_rect_config(), - HighlightRectsConfiguration::R1_TOP_PARTIAL_LEFT_R2); -} - -// Test case R1_BOTTOM_PARTIAL_LEFT_R2. -TEST_F(UIDevToolsTest, OneUIElementStaysPartiallyBottomLeftOfAnother) { - const gfx::Rect bottom_left_rect(50, 200, 100, 100); - std::unique_ptr<views::Widget> widget_bottom_left( - CreateTestWidget(bottom_left_rect)); - - const gfx::Rect top_right_rect(100, 50, 50, 50); - std::unique_ptr<views::Widget> widget_top_right( - CreateTestWidget(top_right_rect)); - - std::unique_ptr<DOM::Node> root; - dom_agent()->getDocument(&root); - - int bottom_left_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(bottom_left_rect.origin()).get()); - int top_right_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(top_right_rect.origin()).get()); - overlay_agent()->ShowDistancesInHighlightOverlay(bottom_left_rect_id, - top_right_rect_id); - - HighlightRectsConfiguration highlight_rect_config = - overlay_agent()->highlight_rect_config(); - - // Swapping R1 and R2 shouldn't change |highlight_rect_config|. - overlay_agent()->ShowDistancesInHighlightOverlay(top_right_rect_id, - bottom_left_rect_id); - DCHECK_EQ(highlight_rect_config, overlay_agent()->highlight_rect_config()); - - const std::pair<aura::Window*, gfx::Rect> element_bottom_left( - dom_agent() - ->GetElementFromNodeId(bottom_left_rect_id) - ->GetNodeWindowAndBounds()); - - const std::pair<aura::Window*, gfx::Rect> element_top_right( - dom_agent() - ->GetElementFromNodeId(top_right_rect_id) - ->GetNodeWindowAndBounds()); - - EXPECT_EQ(element_bottom_left.second, bottom_left_rect); - EXPECT_EQ(element_top_right.second, top_right_rect); - DCHECK_EQ(overlay_agent()->highlight_rect_config(), - HighlightRectsConfiguration::R1_BOTTOM_PARTIAL_LEFT_R2); -} - -// Test case R1_INTERSECTS_R2. -TEST_F(UIDevToolsTest, OneUIElementIntersectsAnother) { - const gfx::Rect left_rect(100, 100, 50, 50); - std::unique_ptr<views::Widget> widget_left(CreateTestWidget(left_rect)); - - const gfx::Rect right_rect(120, 120, 50, 50); - std::unique_ptr<views::Widget> widget_right(CreateTestWidget(right_rect)); - - std::unique_ptr<DOM::Node> root; - dom_agent()->getDocument(&root); - - int left_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(left_rect.origin()).get()); - int right_rect_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(right_rect.origin()).get()); - overlay_agent()->ShowDistancesInHighlightOverlay(left_rect_id, right_rect_id); - - HighlightRectsConfiguration highlight_rect_config = - overlay_agent()->highlight_rect_config(); - - // Swapping R1 and R2 shouldn't change |highlight_rect_config|. - overlay_agent()->ShowDistancesInHighlightOverlay(right_rect_id, left_rect_id); - DCHECK_EQ(highlight_rect_config, overlay_agent()->highlight_rect_config()); - - const std::pair<aura::Window*, gfx::Rect> element_left( - dom_agent() - ->GetElementFromNodeId(left_rect_id) - ->GetNodeWindowAndBounds()); - - const std::pair<aura::Window*, gfx::Rect> element_right( - dom_agent() - ->GetElementFromNodeId(right_rect_id) - ->GetNodeWindowAndBounds()); - - EXPECT_EQ(element_left.second, left_rect); - EXPECT_EQ(element_right.second, right_rect); - DCHECK_EQ(overlay_agent()->highlight_rect_config(), - HighlightRectsConfiguration::R1_INTERSECTS_R2); -} - -// Tests that the correct Overlay events are dispatched to the frontend when -// hovering and clicking over a UI element in inspect mode. -TEST_F(UIDevToolsTest, MouseEventsGenerateFEEventsInInspectMode) { - std::unique_ptr<views::Widget> widget( - CreateTestWidget(gfx::Rect(1, 1, 1, 1))); - - std::unique_ptr<DOM::Node> root; - dom_agent()->getDocument(&root); - - gfx::Point p(1, 1); - int node_id = overlay_agent()->FindElementIdTargetedByPoint( - MouseEventAtRootLocation(p).get()); - - EXPECT_EQ(0, GetOverlayInspectNodeRequestedCount(node_id)); - EXPECT_EQ(0, GetOverlayNodeHighlightRequestedCount(node_id)); - overlay_agent()->setInspectMode( - "searchForNode", protocol::Maybe<protocol::Overlay::HighlightConfig>()); - - // Moving the mouse cursor over the widget bounds should request a node - // highlight. - ui::test::EventGenerator generator(widget->GetNativeWindow()); - generator.MoveMouseBy(p.x(), p.y()); - - // 2 mouse events ET_MOUSE_ENTERED and ET_MOUSE_MOVED are generated. - EXPECT_EQ(2, GetOverlayNodeHighlightRequestedCount(node_id)); - EXPECT_EQ(0, GetOverlayInspectNodeRequestedCount(node_id)); - - // Clicking on the widget should pin that element. - generator.PressLeftButton(); - - // Pin parent node after mouse wheel moves up. - int parent_id = dom_agent()->GetParentIdOfNodeId(node_id); - EXPECT_NE(parent_id, overlay_agent()->pinned_id()); - generator.MoveMouseWheel(0, 1); - EXPECT_EQ(parent_id, overlay_agent()->pinned_id()); - - // Re-assign pin node. - node_id = parent_id; - - int inspect_node_notification_count = - GetOverlayInspectNodeRequestedCount(node_id); - - // Press escape to exit inspect mode. - generator.PressKey(ui::KeyboardCode::VKEY_ESCAPE, ui::EventFlags::EF_NONE); - - // Upon exiting inspect mode, the element is inspected and highlighted. - EXPECT_EQ(inspect_node_notification_count + 1, - GetOverlayInspectNodeRequestedCount(node_id)); - ui::Layer* highlighting_layer = GetHighlightingLayer(GetPrimaryRootWindow()); - EXPECT_EQ(kBackgroundColor, highlighting_layer->GetTargetColor()); - EXPECT_TRUE(highlighting_layer->visible()); - - int highlight_notification_count = - GetOverlayNodeHighlightRequestedCount(node_id); - inspect_node_notification_count = - GetOverlayInspectNodeRequestedCount(node_id); - - // Since inspect mode is exited, a subsequent mouse move should generate no - // nodeHighlightRequested or inspectNodeRequested events. - generator.MoveMouseBy(p.x(), p.y()); - EXPECT_EQ(highlight_notification_count, - GetOverlayNodeHighlightRequestedCount(node_id)); - EXPECT_EQ(inspect_node_notification_count, - GetOverlayInspectNodeRequestedCount(node_id)); -} TEST_F(UIDevToolsTest, GetDocumentWithWindowWidgetView) { std::unique_ptr<views::Widget> widget( @@ -995,87 +546,6 @@ ExpectChildNodeInserted(target_view_node->getNodeId(), 0); } -TEST_F(UIDevToolsTest, WindowWidgetViewHighlight) { - std::unique_ptr<views::Widget> widget( - CreateTestWidget(gfx::Rect(0, 0, 400, 400))); - aura::Window* parent_window = widget->GetNativeWindow(); - std::unique_ptr<aura::Window> window(CreateChildWindow(parent_window)); - views::View* root_view = widget->GetRootView(); - - std::unique_ptr<DOM::Node> root; - dom_agent()->getDocument(&root); - - DOM::Node* parent_node = FindInRoot(parent_window, root.get()); - ASSERT_TRUE(parent_node); - Array<DOM::Node>* parent_children = parent_node->getChildren(nullptr); - ASSERT_TRUE(parent_children); - DOM::Node* window_node = parent_children->get(1); - DOM::Node* widget_node = parent_children->get(0); - DOM::Node* root_view_node = widget_node->getChildren(nullptr)->get(0); - - HighlightNode(window_node->getNodeId()); - - ui::Layer* highlighting_layer = GetHighlightingLayer(GetPrimaryRootWindow()); - EXPECT_TRUE(highlighting_layer->visible()); - EXPECT_EQ(kBackgroundColor, highlighting_layer->GetTargetColor()); - - UIElement* element = - dom_agent()->GetElementFromNodeId(window_node->getNodeId()); - ASSERT_EQ(UIElementType::WINDOW, element->type()); - EXPECT_EQ(element->GetNodeWindowAndBounds().first, window.get()); - EXPECT_EQ(element->GetNodeWindowAndBounds().second, - window->GetBoundsInScreen()); - - HideHighlight(0); - HighlightNode(widget_node->getNodeId()); - - highlighting_layer = GetHighlightingLayer(GetPrimaryRootWindow()); - EXPECT_TRUE(highlighting_layer->visible()); - EXPECT_EQ(kBackgroundColor, highlighting_layer->GetTargetColor()); - - element = dom_agent()->GetElementFromNodeId(widget_node->getNodeId()); - ASSERT_EQ(UIElementType::WIDGET, element->type()); - EXPECT_EQ(element->GetNodeWindowAndBounds().first, widget->GetNativeWindow()); - EXPECT_EQ(element->GetNodeWindowAndBounds().second, - widget->GetWindowBoundsInScreen()); - - HideHighlight(0); - HighlightNode(root_view_node->getNodeId()); - - highlighting_layer = GetHighlightingLayer(GetPrimaryRootWindow()); - EXPECT_TRUE(highlighting_layer->visible()); - EXPECT_EQ(kBackgroundColor, highlighting_layer->GetTargetColor()); - - element = dom_agent()->GetElementFromNodeId(root_view_node->getNodeId()); - ASSERT_EQ(UIElementType::VIEW, element->type()); - EXPECT_EQ(element->GetNodeWindowAndBounds().first, - root_view->GetWidget()->GetNativeWindow()); - EXPECT_EQ(element->GetNodeWindowAndBounds().second, - root_view->GetBoundsInScreen()); - - HideHighlight(0); - - // Highlight non-existent node - HighlightNode(10000); - EXPECT_FALSE(GetHighlightingLayer(GetPrimaryRootWindow())->visible()); -} - -int GetNodeIdFromWindow(UIElement* ui_element, aura::Window* window) { - for (auto* child : ui_element->children()) { - if (child->type() == UIElementType::WINDOW && - static_cast<WindowElement*>(child)->window() == window) { - return child->node_id(); - } - } - for (auto* child : ui_element->children()) { - if (child->type() == UIElementType::WINDOW) { - int node_id = GetNodeIdFromWindow(child, window); - if (node_id > 0) - return node_id; - } - } - return 0; -} // TODO(thanhph): Make test AshDevToolsTest.MultipleDisplayHighlight work with // multiple displays. https://crbug.com/726831.
diff --git a/components/ui_devtools/views/view_element_unittest.cc b/components/ui_devtools/views/view_element_unittest.cc index 3abc018..5ef8bca 100644 --- a/components/ui_devtools/views/view_element_unittest.cc +++ b/components/ui_devtools/views/view_element_unittest.cc
@@ -128,4 +128,26 @@ EXPECT_EQ(props[0].second, "This is the tooltip"); } +TEST_F(ViewElementTest, GetNodeWindowAndBounds) { + // For this to be meaningful, the view must be in + // a widget. + auto widget = std::make_unique<views::Widget>(); + views::Widget::InitParams params = + CreateParams(views::Widget::InitParams::TYPE_WINDOW); + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + widget->Init(params); + widget->Show(); + + widget->GetContentsView()->AddChildView(view()); + gfx::Rect bounds(50, 60, 70, 80); + view()->SetBoundsRect(bounds); + + std::pair<gfx::NativeWindow, gfx::Rect> window_and_bounds = + element()->GetNodeWindowAndBounds(); + EXPECT_EQ(window_and_bounds.first, widget->GetNativeWindow()); + EXPECT_EQ(window_and_bounds.second, view()->GetBoundsInScreen()); + + view()->parent()->RemoveChildView(view()); +} + } // namespace ui_devtools
diff --git a/components/ui_devtools/views/widget_element.cc b/components/ui_devtools/views/widget_element.cc index 1ee7b26a..53967b9 100644 --- a/components/ui_devtools/views/widget_element.cc +++ b/components/ui_devtools/views/widget_element.cc
@@ -94,4 +94,19 @@ return static_cast<const WidgetElement*>(element)->widget_; } +template <> +int UIElement::FindUIElementIdForBackendElement<views::Widget>( + views::Widget* element) const { + if (type_ == UIElementType::WIDGET && + UIElement::GetBackingElement<views::Widget, WidgetElement>(this) == + element) { + return node_id_; + } + for (auto* child : children_) { + int ui_element_id = child->FindUIElementIdForBackendElement(element); + if (ui_element_id) + return ui_element_id; + } + return 0; +} } // namespace ui_devtools
diff --git a/components/ui_devtools/views/widget_element_unittest.cc b/components/ui_devtools/views/widget_element_unittest.cc index d598dbb..c08adf9 100644 --- a/components/ui_devtools/views/widget_element_unittest.cc +++ b/components/ui_devtools/views/widget_element_unittest.cc
@@ -130,4 +130,11 @@ EXPECT_EQ(attrs->get(3), "true"); } +TEST_F(WidgetElementTest, GetNodeWindowAndBounds) { + std::pair<gfx::NativeWindow, gfx::Rect> window_and_bounds = + element()->GetNodeWindowAndBounds(); + EXPECT_EQ(widget()->GetNativeWindow(), window_and_bounds.first); + EXPECT_EQ(widget()->GetWindowBoundsInScreen(), window_and_bounds.second); +} + } // namespace ui_devtools
diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc index c1a8c4d4..e33734c 100644 --- a/components/variations/service/variations_service.cc +++ b/components/variations/service/variations_service.cc
@@ -105,6 +105,8 @@ return "chromeos"; #elif defined(OS_ANDROID) return "android"; +#elif defined(OS_FUCHSIA) + return "fuchsia"; #elif defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS) // Default BSD and SOLARIS to Linux to not break those builds, although these // platforms are not officially supported by Chrome.
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 720f435..9cdd4a5 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -17,6 +17,7 @@ #include "components/viz/service/gl/gpu_service_impl.h" #include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "gpu/command_buffer/service/scheduler.h" +#include "gpu/command_buffer/service/shared_image_representation.h" #include "third_party/skia/include/core/SkYUVAIndex.h" #include "ui/gfx/skia_util.h" #include "ui/gl/gl_bindings.h" @@ -89,11 +90,18 @@ // or SkiaOutputSurfaceImplOnGpu::FinishPaintRenderPass, so impl_on_gpu_ // should be always valid. DCHECK(helper->impl_on_gpu_); - helper->impl_on_gpu_->FulfillPromiseTexture(helper->context_, - backend_texture); + helper->impl_on_gpu_->FulfillPromiseTexture( + helper->context_, &helper->shared_image_, backend_texture); } - static void Release(void* texture_context) { DCHECK(texture_context); } + static void Release(void* texture_context) { + DCHECK(texture_context); + auto* helper = static_cast<HelperType*>(texture_context); + if (helper->shared_image_) { + helper->shared_image_->EndReadAccess(); + helper->shared_image_.reset(); + } + } static void Done(void* texture_context) { DCHECK(texture_context); @@ -106,6 +114,10 @@ // The data for calling the fulfill methods in SkiaOutputSurfaceImpl. FulfillContextType context_; + // If non-null, an outstanding SharedImageRepresentation that must be freed on + // Release. Only written / read from GPU thread. + std::unique_ptr<gpu::SharedImageRepresentationSkia> shared_image_; + DISALLOW_COPY_AND_ASSIGN(PromiseTextureHelper); };
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 00eedc5..a2e0614 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -13,6 +13,7 @@ #include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/scheduler.h" +#include "gpu/command_buffer/service/shared_image_representation.h" #include "gpu/command_buffer/service/skia_utils.h" #include "gpu/command_buffer/service/sync_point_manager.h" #include "gpu/command_buffer/service/texture_base.h" @@ -299,8 +300,26 @@ void SkiaOutputSurfaceImplOnGpu::FulfillPromiseTexture( const ResourceMetadata& metadata, + std::unique_ptr<gpu::SharedImageRepresentationSkia>* shared_image_out, GrBackendTexture* backend_texture) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK(!*shared_image_out); + auto* shared_image_manager = gpu_service_->shared_image_manager(); + if (shared_image_manager->IsSharedImage(metadata.mailbox)) { + std::unique_ptr<gpu::SharedImageRepresentationSkia> shared_image = + shared_image_manager->ProduceSkia(metadata.mailbox); + DCHECK(shared_image); + if (!shared_image->BeginReadAccess(metadata.color_type, backend_texture)) { + DLOG(ERROR) + << "Failed to begin read access for SharedImageRepresentationSkia"; + return; + } + *shared_image_out = std::move(shared_image); + return; + } + + // Legacy mailbox path. TODO: Remove this once everything goes through + // SharedImages. if (gpu_service_->is_using_vulkan()) { // TODO(https://crbug.com/838899): Use SkSurface as raster decoder target. // NOTIMPLEMENTED(); @@ -313,15 +332,15 @@ return; } BindOrCopyTextureIfNecessary(texture_base); - GetGrBackendTexture(*gl_version_info(), - /*function_name=*/nullptr, - /*error_state=*/nullptr, *texture_base, - metadata.color_type, backend_texture); + GetGrBackendTexture(*gl_version_info(), *texture_base, metadata.color_type, + backend_texture); } void SkiaOutputSurfaceImplOnGpu::FulfillPromiseTexture( const RenderPassId id, + std::unique_ptr<gpu::SharedImageRepresentationSkia>* shared_image_out, GrBackendTexture* backend_texture) { + DCHECK(!*shared_image_out); auto it = offscreen_surfaces_.find(id); DCHECK(it != offscreen_surfaces_.end()); sk_sp<SkSurface>& surface = it->second;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index ff24dfb..03eeba2 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -31,6 +31,7 @@ namespace gpu { class SyncPointClientState; +class SharedImageRepresentationSkia; #if BUILDFLAG(ENABLE_VULKAN) class VulkanSurface; @@ -86,11 +87,17 @@ std::unique_ptr<CopyOutputRequest> request); // Fulfill callback for promise SkImage created from a resource. - void FulfillPromiseTexture(const ResourceMetadata& metadata, - GrBackendTexture* backend_texture); + void FulfillPromiseTexture( + const ResourceMetadata& metadata, + std::unique_ptr<gpu::SharedImageRepresentationSkia>* shared_image_out, + GrBackendTexture* backend_texture); // Fulfill callback for promise SkImage created from a render pass. - void FulfillPromiseTexture(const RenderPassId id, - GrBackendTexture* backend_texture); + // |shared_image_out| is ignored for render passes, as these aren't based on + // SharedImage. + void FulfillPromiseTexture( + const RenderPassId id, + std::unique_ptr<gpu::SharedImageRepresentationSkia>* shared_image_out, + GrBackendTexture* backend_texture); sk_sp<GrContextThreadSafeProxy> GetGrContextThreadSafeProxy(); const gl::GLVersionInfo* gl_version_info() const { return gl_version_info_; }
diff --git a/components/viz/service/gl/gpu_service_impl.h b/components/viz/service/gl/gpu_service_impl.h index 9fc34bf..664ef05 100644 --- a/components/viz/service/gl/gpu_service_impl.h +++ b/components/viz/service/gl/gpu_service_impl.h
@@ -117,6 +117,10 @@ return gpu_channel_manager_->mailbox_manager(); } + gpu::SharedImageManager* shared_image_manager() { + return gpu_channel_manager_->shared_image_manager(); + } + gl::GLShareGroup* share_group() { return gpu_channel_manager_->share_group(); }
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index 2bc20e1..51f89f6 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -8004,7 +8004,12 @@ // Perform a cross-site omnibox navigation. prev_host = curr_host; prev_spare = curr_spare; + RenderProcessHostWatcher prev_host_watcher( + prev_host, RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION); EXPECT_TRUE(NavigateToURL(shell(), second_url)); + // Wait until the |prev_host| goes away - this ensures that the spare will be + // picked up by subsequent back navigation below. + prev_host_watcher.Wait(); curr_spare = RenderProcessHostImpl::GetSpareRenderProcessHostForTesting(); curr_host = shell()->web_contents()->GetMainFrame()->GetProcess(); // The cross-site omnibox navigation should swap processes.
diff --git a/content/browser/scheduler/responsiveness/watcher_unittest.cc b/content/browser/scheduler/responsiveness/watcher_unittest.cc index f999b87..82b4c7bfb 100644 --- a/content/browser/scheduler/responsiveness/watcher_unittest.cc +++ b/content/browser/scheduler/responsiveness/watcher_unittest.cc
@@ -216,13 +216,7 @@ scoped_refptr<FakeWatcher> watcher_; }; -// Flaky on Linux TSAN. https://crbug.com/876561 -#if defined(OS_LINUX) && defined(THREAD_SANITIZER) -#define MAYBE_MessageLoopObserver DISABLED_MessageLoopObserver -#else -#define MAYBE_MessageLoopObserver MessageLoopObserver -#endif -TEST_F(ResponsivenessWatcherRealIOThreadTest, MAYBE_MessageLoopObserver) { +TEST_F(ResponsivenessWatcherRealIOThreadTest, MessageLoopObserver) { // Post a do-nothing task onto the UI thread. base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI}, base::BindOnce([]() {}));
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc index 06bc82d3..7c1cf3a 100644 --- a/content/browser/service_worker/service_worker_storage.cc +++ b/content/browser/service_worker/service_worker_storage.cc
@@ -1767,8 +1767,11 @@ std::set<GURL> session_only_origins; for (const GURL& origin : registered_origins_) { - if (special_storage_policy_->IsStorageSessionOnly(origin)) - session_only_origins.insert(origin); + if (!special_storage_policy_->IsStorageSessionOnly(origin)) + continue; + if (special_storage_policy_->IsStorageProtected(origin)) + continue; + session_only_origins.insert(origin); } database_task_runner_->PostTask(
diff --git a/content/browser/shared_worker/shared_worker_script_loader_factory.cc b/content/browser/shared_worker/shared_worker_script_loader_factory.cc index bdbec0c..b9e1ae56 100644 --- a/content/browser/shared_worker/shared_worker_script_loader_factory.cc +++ b/content/browser/shared_worker/shared_worker_script_loader_factory.cc
@@ -7,7 +7,6 @@ #include <memory> #include "base/feature_list.h" #include "content/browser/service_worker/service_worker_context_core.h" -#include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_provider_host.h" #include "content/browser/service_worker/service_worker_version.h" #include "content/browser/shared_worker/shared_worker_script_loader.h" @@ -23,7 +22,6 @@ SharedWorkerScriptLoaderFactory::SharedWorkerScriptLoaderFactory( int process_id, - ServiceWorkerContextWrapper* context, base::WeakPtr<ServiceWorkerProviderHost> service_worker_provider_host, base::WeakPtr<AppCacheHost> appcache_host, ResourceContext* resource_context,
diff --git a/content/browser/shared_worker/shared_worker_script_loader_factory.h b/content/browser/shared_worker/shared_worker_script_loader_factory.h index 58072e3..b94570e 100644 --- a/content/browser/shared_worker/shared_worker_script_loader_factory.h +++ b/content/browser/shared_worker/shared_worker_script_loader_factory.h
@@ -16,7 +16,6 @@ namespace content { class AppCacheHost; -class ServiceWorkerContextWrapper; class ServiceWorkerProviderHost; class SharedWorkerScriptLoader; class ResourceContext; @@ -41,7 +40,6 @@ // factories used for non-http(s) URLs, e.g., a chrome-extension:// URL. SharedWorkerScriptLoaderFactory( int process_id, - ServiceWorkerContextWrapper* context, base::WeakPtr<ServiceWorkerProviderHost> provider_host, base::WeakPtr<AppCacheHost> appcache_host, ResourceContext* resource_context,
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc index 24f3152..c29c958 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.cc +++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -214,9 +214,8 @@ SharedWorkerScriptFetcher::CreateAndStart( std::make_unique<SharedWorkerScriptLoaderFactory>( - process_id, context.get(), host, - std::move(appcache_host), context->resource_context(), - std::move(url_loader_factory)), + process_id, host, std::move(appcache_host), + context->resource_context(), std::move(url_loader_factory)), std::move(throttles), std::move(resource_request), base::BindOnce(DidCreateScriptLoaderOnIO, std::move(callback), std::move(provider_info), @@ -229,9 +228,8 @@ network::mojom::URLLoaderFactoryAssociatedPtrInfo main_script_loader_factory; mojo::MakeStrongAssociatedBinding( std::make_unique<SharedWorkerScriptLoaderFactory>( - process_id, context.get(), host->AsWeakPtr(), - std::move(appcache_host), context->resource_context(), - std::move(url_loader_factory)), + process_id, host->AsWeakPtr(), std::move(appcache_host), + context->resource_context(), std::move(url_loader_factory)), mojo::MakeRequest(&main_script_loader_factory)); DidCreateScriptLoaderOnIO(std::move(callback), std::move(provider_info),
diff --git a/content/browser/tracing/background_tracing_manager_impl.cc b/content/browser/tracing/background_tracing_manager_impl.cc index ffdf903..ae047da4 100644 --- a/content/browser/tracing/background_tracing_manager_impl.cc +++ b/content/browser/tracing/background_tracing_manager_impl.cc
@@ -635,7 +635,8 @@ config_.reset(); tracing_timer_.reset(); - content::TracingControllerImpl::GetInstance()->StopTracing(nullptr); + if (is_tracing_) + content::TracingControllerImpl::GetInstance()->StopTracing(nullptr); for (auto* observer : background_tracing_observers_) observer->OnScenarioAborted();
diff --git a/content/browser/tracing/background_tracing_manager_impl.h b/content/browser/tracing/background_tracing_manager_impl.h index d242895..5383337 100644 --- a/content/browser/tracing/background_tracing_manager_impl.h +++ b/content/browser/tracing/background_tracing_manager_impl.h
@@ -69,7 +69,7 @@ void OnRuleTriggered(const BackgroundTracingRule* triggered_rule, StartedFinalizingCallback callback); - void AbortScenario(); + CONTENT_EXPORT void AbortScenario() override; bool HasActiveScenario() override; void OnStartTracingDone(BackgroundTracingConfigImpl::CategoryPreset preset);
diff --git a/content/browser/tracing/tracing_controller_impl.h b/content/browser/tracing/tracing_controller_impl.h index cd8cca3..567720a 100644 --- a/content/browser/tracing/tracing_controller_impl.h +++ b/content/browser/tracing/tracing_controller_impl.h
@@ -50,7 +50,7 @@ CONTENT_EXPORT static TracingControllerImpl* GetInstance(); // Should be called on the UI thread. - TracingControllerImpl(); + CONTENT_EXPORT TracingControllerImpl(); // TracingController implementation. bool GetCategories(GetCategoriesDoneCallback callback) override;
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index f639913..c2eef0d 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -66,6 +66,7 @@ "//mojo/public/java:bindings_java", "//mojo/public/java:system_java", "//mojo/public/java/system:system_impl_java", + "//mojo/public/mojom/base:base_java", "//net/android:net_java", "//services/device:java", "//services/device/public/java:nfc_java", @@ -73,10 +74,13 @@ "//services/service_manager/public/mojom:mojom_java", "//services/shape_detection:shape_detection_java", "//services/shape_detection/public/mojom:mojom_java", + "//skia/public/interfaces:interfaces_java", "//third_party/android_deps:android_support_annotations_java", + "//third_party/android_deps:android_support_compat_java", "//third_party/blink/public:android_mojo_bindings_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:mojom_core_java", + "//third_party/blink/public/mojom:mojom_platform_java", "//third_party/blink/public/mojom:speech_recognition_error_code_java", "//third_party/jsr-305:jsr_305_javalib", "//ui/android:ui_java", @@ -443,6 +447,8 @@ "//third_party/android_deps:android_support_annotations_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", + "//third_party/blink/public:android_mojo_bindings_java", + "//third_party/blink/public:blink_headers_java", "//third_party/jsr-305:jsr_305_javalib", "//third_party/junit", "//ui/android:ui_java",
diff --git a/content/public/android/java/strings/android_content_strings.grd b/content/public/android/java/strings/android_content_strings.grd index 4f5ad63..33e8def 100644 --- a/content/public/android/java/strings/android_content_strings.grd +++ b/content/public/android/java/strings/android_content_strings.grd
@@ -50,6 +50,7 @@ <file lang="am" path="translations/android_content_strings_am.xtb" /> <file lang="ar" path="translations/android_content_strings_ar.xtb" /> <file lang="bg" path="translations/android_content_strings_bg.xtb" /> + <file lang="bn" path="translations/android_content_strings_bn.xtb" /> <file lang="ca" path="translations/android_content_strings_ca.xtb" /> <file lang="cs" path="translations/android_content_strings_cs.xtb" /> <file lang="da" path="translations/android_content_strings_da.xtb" /> @@ -58,10 +59,12 @@ <file lang="en-GB" path="translations/android_content_strings_en-GB.xtb" /> <file lang="es" path="translations/android_content_strings_es.xtb" /> <file lang="es-419" path="translations/android_content_strings_es-419.xtb" /> + <file lang="et" path="translations/android_content_strings_et.xtb" /> <file lang="fa" path="translations/android_content_strings_fa.xtb" /> <file lang="fi" path="translations/android_content_strings_fi.xtb" /> <file lang="fil" path="translations/android_content_strings_fil.xtb" /> <file lang="fr" path="translations/android_content_strings_fr.xtb" /> + <file lang="gu" path="translations/android_content_strings_gu.xtb" /> <file lang="hi" path="translations/android_content_strings_hi.xtb" /> <file lang="hr" path="translations/android_content_strings_hr.xtb" /> <file lang="hu" path="translations/android_content_strings_hu.xtb" /> @@ -70,8 +73,12 @@ <file lang="iw" path="translations/android_content_strings_iw.xtb" /> <file lang="ja" path="translations/android_content_strings_ja.xtb" /> <file lang="ko" path="translations/android_content_strings_ko.xtb" /> + <file lang="kn" path="translations/android_content_strings_kn.xtb" /> <file lang="lt" path="translations/android_content_strings_lt.xtb" /> <file lang="lv" path="translations/android_content_strings_lv.xtb" /> + <file lang="ml" path="translations/android_content_strings_ml.xtb" /> + <file lang="mr" path="translations/android_content_strings_mr.xtb" /> + <file lang="ms" path="translations/android_content_strings_ms.xtb" /> <file lang="nl" path="translations/android_content_strings_nl.xtb" /> <file lang="no" path="translations/android_content_strings_no.xtb" /> <file lang="pl" path="translations/android_content_strings_pl.xtb" /> @@ -84,6 +91,8 @@ <file lang="sr" path="translations/android_content_strings_sr.xtb" /> <file lang="sv" path="translations/android_content_strings_sv.xtb" /> <file lang="sw" path="translations/android_content_strings_sw.xtb" /> + <file lang="ta" path="translations/android_content_strings_ta.xtb" /> + <file lang="te" path="translations/android_content_strings_te.xtb" /> <file lang="th" path="translations/android_content_strings_th.xtb" /> <file lang="tr" path="translations/android_content_strings_tr.xtb" /> <file lang="uk" path="translations/android_content_strings_uk.xtb" />
diff --git a/content/public/android/java/strings/translations/android_content_strings_bn.xtb b/content/public/android/java/strings/translations/android_content_strings_bn.xtb new file mode 100644 index 0000000..faf80ec --- /dev/null +++ b/content/public/android/java/strings/translations/android_content_strings_bn.xtb
@@ -0,0 +1,35 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="bn"> +<translation id="1412240523210238692">Text selection</translation> +<translation id="1542044944667958430">Web search</translation> +<translation id="1768717197362323622">Millisecond</translation> +<translation id="1822429046913737220">AM/PM</translation> +<translation id="2094750046714988961">Can't start profiler because external storage is not ready</translation> +<translation id="2429669115401274487">p.m.</translation> +<translation id="2520230379124234395">Profiler started</translation> +<translation id="2732718972699418926">a.m.</translation> +<translation id="2841013758207633010">Time</translation> +<translation id="376869769528291915">:</translation> +<translation id="3845599764535987402">Hour</translation> +<translation id="4247305538398689241">Set week</translation> +<translation id="4768459022382175196">Second</translation> +<translation id="4859501799452851758">Profiler finished. Results are in <ph name="FILENAME" />.</translation> +<translation id="4932733599132424254">Date</translation> +<translation id="5659744962989939577">Add to dictionary</translation> +<translation id="5789643057113097023">.</translation> +<translation id="5966707198760109579">Week</translation> +<translation id="6015796118275082299">Year</translation> +<translation id="6444070574980481588">Set date and time</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="6849295950938417341">Failed to start profiler</translation> +<translation id="7102218676258945610">Minute</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7575803462290353686">Set time</translation> +<translation id="7781164152564914424">Set month</translation> +<translation id="7821540960913969614">Set date</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8987927404178983737">Month</translation> +</translationbundle> \ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_et.xtb b/content/public/android/java/strings/translations/android_content_strings_et.xtb new file mode 100644 index 0000000..3a50632e --- /dev/null +++ b/content/public/android/java/strings/translations/android_content_strings_et.xtb
@@ -0,0 +1,35 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="et"> +<translation id="1412240523210238692">Text selection</translation> +<translation id="1542044944667958430">Web search</translation> +<translation id="1768717197362323622">Millisecond</translation> +<translation id="1822429046913737220">AM/PM</translation> +<translation id="2094750046714988961">Can't start profiler because external storage is not ready</translation> +<translation id="2429669115401274487">p.m.</translation> +<translation id="2520230379124234395">Profiler started</translation> +<translation id="2732718972699418926">a.m.</translation> +<translation id="2841013758207633010">Time</translation> +<translation id="376869769528291915">:</translation> +<translation id="3845599764535987402">Hour</translation> +<translation id="4247305538398689241">Set week</translation> +<translation id="4768459022382175196">Second</translation> +<translation id="4859501799452851758">Profiler finished. Results are in <ph name="FILENAME" />.</translation> +<translation id="4932733599132424254">Date</translation> +<translation id="5659744962989939577">Add to dictionary</translation> +<translation id="5789643057113097023">.</translation> +<translation id="5966707198760109579">Week</translation> +<translation id="6015796118275082299">Year</translation> +<translation id="6444070574980481588">Set date and time</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="6849295950938417341">Failed to start profiler</translation> +<translation id="7102218676258945610">Minute</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7575803462290353686">Set time</translation> +<translation id="7781164152564914424">Set month</translation> +<translation id="7821540960913969614">Set date</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8987927404178983737">Month</translation> +</translationbundle> \ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_gu.xtb b/content/public/android/java/strings/translations/android_content_strings_gu.xtb new file mode 100644 index 0000000..3f5e7a88 --- /dev/null +++ b/content/public/android/java/strings/translations/android_content_strings_gu.xtb
@@ -0,0 +1,35 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="gu"> +<translation id="1412240523210238692">Text selection</translation> +<translation id="1542044944667958430">Web search</translation> +<translation id="1768717197362323622">Millisecond</translation> +<translation id="1822429046913737220">AM/PM</translation> +<translation id="2094750046714988961">Can't start profiler because external storage is not ready</translation> +<translation id="2429669115401274487">p.m.</translation> +<translation id="2520230379124234395">Profiler started</translation> +<translation id="2732718972699418926">a.m.</translation> +<translation id="2841013758207633010">Time</translation> +<translation id="376869769528291915">:</translation> +<translation id="3845599764535987402">Hour</translation> +<translation id="4247305538398689241">Set week</translation> +<translation id="4768459022382175196">Second</translation> +<translation id="4859501799452851758">Profiler finished. Results are in <ph name="FILENAME" />.</translation> +<translation id="4932733599132424254">Date</translation> +<translation id="5659744962989939577">Add to dictionary</translation> +<translation id="5789643057113097023">.</translation> +<translation id="5966707198760109579">Week</translation> +<translation id="6015796118275082299">Year</translation> +<translation id="6444070574980481588">Set date and time</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="6849295950938417341">Failed to start profiler</translation> +<translation id="7102218676258945610">Minute</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7575803462290353686">Set time</translation> +<translation id="7781164152564914424">Set month</translation> +<translation id="7821540960913969614">Set date</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8987927404178983737">Month</translation> +</translationbundle> \ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_kn.xtb b/content/public/android/java/strings/translations/android_content_strings_kn.xtb new file mode 100644 index 0000000..d0f47222 --- /dev/null +++ b/content/public/android/java/strings/translations/android_content_strings_kn.xtb
@@ -0,0 +1,35 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="kn"> +<translation id="1412240523210238692">Text selection</translation> +<translation id="1542044944667958430">Web search</translation> +<translation id="1768717197362323622">Millisecond</translation> +<translation id="1822429046913737220">AM/PM</translation> +<translation id="2094750046714988961">Can't start profiler because external storage is not ready</translation> +<translation id="2429669115401274487">p.m.</translation> +<translation id="2520230379124234395">Profiler started</translation> +<translation id="2732718972699418926">a.m.</translation> +<translation id="2841013758207633010">Time</translation> +<translation id="376869769528291915">:</translation> +<translation id="3845599764535987402">Hour</translation> +<translation id="4247305538398689241">Set week</translation> +<translation id="4768459022382175196">Second</translation> +<translation id="4859501799452851758">Profiler finished. Results are in <ph name="FILENAME" />.</translation> +<translation id="4932733599132424254">Date</translation> +<translation id="5659744962989939577">Add to dictionary</translation> +<translation id="5789643057113097023">.</translation> +<translation id="5966707198760109579">Week</translation> +<translation id="6015796118275082299">Year</translation> +<translation id="6444070574980481588">Set date and time</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="6849295950938417341">Failed to start profiler</translation> +<translation id="7102218676258945610">Minute</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7575803462290353686">Set time</translation> +<translation id="7781164152564914424">Set month</translation> +<translation id="7821540960913969614">Set date</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8987927404178983737">Month</translation> +</translationbundle> \ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_ml.xtb b/content/public/android/java/strings/translations/android_content_strings_ml.xtb new file mode 100644 index 0000000..5399aa2 --- /dev/null +++ b/content/public/android/java/strings/translations/android_content_strings_ml.xtb
@@ -0,0 +1,35 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ml"> +<translation id="1412240523210238692">Text selection</translation> +<translation id="1542044944667958430">Web search</translation> +<translation id="1768717197362323622">Millisecond</translation> +<translation id="1822429046913737220">AM/PM</translation> +<translation id="2094750046714988961">Can't start profiler because external storage is not ready</translation> +<translation id="2429669115401274487">p.m.</translation> +<translation id="2520230379124234395">Profiler started</translation> +<translation id="2732718972699418926">a.m.</translation> +<translation id="2841013758207633010">Time</translation> +<translation id="376869769528291915">:</translation> +<translation id="3845599764535987402">Hour</translation> +<translation id="4247305538398689241">Set week</translation> +<translation id="4768459022382175196">Second</translation> +<translation id="4859501799452851758">Profiler finished. Results are in <ph name="FILENAME" />.</translation> +<translation id="4932733599132424254">Date</translation> +<translation id="5659744962989939577">Add to dictionary</translation> +<translation id="5789643057113097023">.</translation> +<translation id="5966707198760109579">Week</translation> +<translation id="6015796118275082299">Year</translation> +<translation id="6444070574980481588">Set date and time</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="6849295950938417341">Failed to start profiler</translation> +<translation id="7102218676258945610">Minute</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7575803462290353686">Set time</translation> +<translation id="7781164152564914424">Set month</translation> +<translation id="7821540960913969614">Set date</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8987927404178983737">Month</translation> +</translationbundle> \ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_mr.xtb b/content/public/android/java/strings/translations/android_content_strings_mr.xtb new file mode 100644 index 0000000..01ca029 --- /dev/null +++ b/content/public/android/java/strings/translations/android_content_strings_mr.xtb
@@ -0,0 +1,35 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="mr"> +<translation id="1412240523210238692">Text selection</translation> +<translation id="1542044944667958430">Web search</translation> +<translation id="1768717197362323622">Millisecond</translation> +<translation id="1822429046913737220">AM/PM</translation> +<translation id="2094750046714988961">Can't start profiler because external storage is not ready</translation> +<translation id="2429669115401274487">p.m.</translation> +<translation id="2520230379124234395">Profiler started</translation> +<translation id="2732718972699418926">a.m.</translation> +<translation id="2841013758207633010">Time</translation> +<translation id="376869769528291915">:</translation> +<translation id="3845599764535987402">Hour</translation> +<translation id="4247305538398689241">Set week</translation> +<translation id="4768459022382175196">Second</translation> +<translation id="4859501799452851758">Profiler finished. Results are in <ph name="FILENAME" />.</translation> +<translation id="4932733599132424254">Date</translation> +<translation id="5659744962989939577">Add to dictionary</translation> +<translation id="5789643057113097023">.</translation> +<translation id="5966707198760109579">Week</translation> +<translation id="6015796118275082299">Year</translation> +<translation id="6444070574980481588">Set date and time</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="6849295950938417341">Failed to start profiler</translation> +<translation id="7102218676258945610">Minute</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7575803462290353686">Set time</translation> +<translation id="7781164152564914424">Set month</translation> +<translation id="7821540960913969614">Set date</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8987927404178983737">Month</translation> +</translationbundle> \ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_ms.xtb b/content/public/android/java/strings/translations/android_content_strings_ms.xtb new file mode 100644 index 0000000..ffaf9944 --- /dev/null +++ b/content/public/android/java/strings/translations/android_content_strings_ms.xtb
@@ -0,0 +1,35 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ms"> +<translation id="1412240523210238692">Text selection</translation> +<translation id="1542044944667958430">Web search</translation> +<translation id="1768717197362323622">Millisecond</translation> +<translation id="1822429046913737220">AM/PM</translation> +<translation id="2094750046714988961">Can't start profiler because external storage is not ready</translation> +<translation id="2429669115401274487">p.m.</translation> +<translation id="2520230379124234395">Profiler started</translation> +<translation id="2732718972699418926">a.m.</translation> +<translation id="2841013758207633010">Time</translation> +<translation id="376869769528291915">:</translation> +<translation id="3845599764535987402">Hour</translation> +<translation id="4247305538398689241">Set week</translation> +<translation id="4768459022382175196">Second</translation> +<translation id="4859501799452851758">Profiler finished. Results are in <ph name="FILENAME" />.</translation> +<translation id="4932733599132424254">Date</translation> +<translation id="5659744962989939577">Add to dictionary</translation> +<translation id="5789643057113097023">.</translation> +<translation id="5966707198760109579">Week</translation> +<translation id="6015796118275082299">Year</translation> +<translation id="6444070574980481588">Set date and time</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="6849295950938417341">Failed to start profiler</translation> +<translation id="7102218676258945610">Minute</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7575803462290353686">Set time</translation> +<translation id="7781164152564914424">Set month</translation> +<translation id="7821540960913969614">Set date</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8987927404178983737">Month</translation> +</translationbundle> \ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_ta.xtb b/content/public/android/java/strings/translations/android_content_strings_ta.xtb new file mode 100644 index 0000000..c6d9aaa --- /dev/null +++ b/content/public/android/java/strings/translations/android_content_strings_ta.xtb
@@ -0,0 +1,35 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ta"> +<translation id="1412240523210238692">Text selection</translation> +<translation id="1542044944667958430">Web search</translation> +<translation id="1768717197362323622">Millisecond</translation> +<translation id="1822429046913737220">AM/PM</translation> +<translation id="2094750046714988961">Can't start profiler because external storage is not ready</translation> +<translation id="2429669115401274487">p.m.</translation> +<translation id="2520230379124234395">Profiler started</translation> +<translation id="2732718972699418926">a.m.</translation> +<translation id="2841013758207633010">Time</translation> +<translation id="376869769528291915">:</translation> +<translation id="3845599764535987402">Hour</translation> +<translation id="4247305538398689241">Set week</translation> +<translation id="4768459022382175196">Second</translation> +<translation id="4859501799452851758">Profiler finished. Results are in <ph name="FILENAME" />.</translation> +<translation id="4932733599132424254">Date</translation> +<translation id="5659744962989939577">Add to dictionary</translation> +<translation id="5789643057113097023">.</translation> +<translation id="5966707198760109579">Week</translation> +<translation id="6015796118275082299">Year</translation> +<translation id="6444070574980481588">Set date and time</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="6849295950938417341">Failed to start profiler</translation> +<translation id="7102218676258945610">Minute</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7575803462290353686">Set time</translation> +<translation id="7781164152564914424">Set month</translation> +<translation id="7821540960913969614">Set date</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8987927404178983737">Month</translation> +</translationbundle> \ No newline at end of file
diff --git a/content/public/android/java/strings/translations/android_content_strings_te.xtb b/content/public/android/java/strings/translations/android_content_strings_te.xtb new file mode 100644 index 0000000..c4dce65 --- /dev/null +++ b/content/public/android/java/strings/translations/android_content_strings_te.xtb
@@ -0,0 +1,35 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="te"> +<translation id="1412240523210238692">Text selection</translation> +<translation id="1542044944667958430">Web search</translation> +<translation id="1768717197362323622">Millisecond</translation> +<translation id="1822429046913737220">AM/PM</translation> +<translation id="2094750046714988961">Can't start profiler because external storage is not ready</translation> +<translation id="2429669115401274487">p.m.</translation> +<translation id="2520230379124234395">Profiler started</translation> +<translation id="2732718972699418926">a.m.</translation> +<translation id="2841013758207633010">Time</translation> +<translation id="376869769528291915">:</translation> +<translation id="3845599764535987402">Hour</translation> +<translation id="4247305538398689241">Set week</translation> +<translation id="4768459022382175196">Second</translation> +<translation id="4859501799452851758">Profiler finished. Results are in <ph name="FILENAME" />.</translation> +<translation id="4932733599132424254">Date</translation> +<translation id="5659744962989939577">Add to dictionary</translation> +<translation id="5789643057113097023">.</translation> +<translation id="5966707198760109579">Week</translation> +<translation id="6015796118275082299">Year</translation> +<translation id="6444070574980481588">Set date and time</translation> +<translation id="6527303717912515753">Share</translation> +<translation id="6643016212128521049">Clear</translation> +<translation id="6727102863431372879">Set</translation> +<translation id="6849295950938417341">Failed to start profiler</translation> +<translation id="7102218676258945610">Minute</translation> +<translation id="7138678301420049075">Other</translation> +<translation id="7575803462290353686">Set time</translation> +<translation id="7781164152564914424">Set month</translation> +<translation id="7821540960913969614">Set date</translation> +<translation id="8261506727792406068">Delete</translation> +<translation id="8987927404178983737">Month</translation> +</translationbundle> \ No newline at end of file
diff --git a/content/public/browser/background_tracing_manager.h b/content/public/browser/background_tracing_manager.h index edfb80c0..dfbd33f 100644 --- a/content/public/browser/background_tracing_manager.h +++ b/content/public/browser/background_tracing_manager.h
@@ -90,6 +90,8 @@ virtual bool HasActiveScenario() = 0; + // For tests + virtual void AbortScenario() = 0; virtual void InvalidateTriggerHandlesForTesting() = 0; virtual void FireTimerForTesting() = 0;
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index 5610ce5..a7c2ce1 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -366,7 +366,9 @@ public_deps = [ ":resource_type_bindings", + "//mojo/public/mojom/base:base", "//services/network/public/mojom", + "//services/network/public/mojom:websocket_mojom", "//third_party/blink/public:mojo_bindings", "//ui/accessibility:ax_enums_mojo", "//url/mojom:url_mojom_gurl",
diff --git a/content/renderer/loader/request_extra_data.cc b/content/renderer/loader/request_extra_data.cc index de59451..1033f2d2d 100644 --- a/content/renderer/loader/request_extra_data.cc +++ b/content/renderer/loader/request_extra_data.cc
@@ -21,7 +21,6 @@ originated_from_service_worker_(false), initiated_in_secure_context_(false), is_for_no_state_prefetch_(false), - download_to_network_cache_only_(false), block_mixed_plugin_content_(false), navigation_initiated_by_renderer_(false), attach_same_site_cookies_(false) {}
diff --git a/content/renderer/loader/request_extra_data.h b/content/renderer/loader/request_extra_data.h index caafb00..d2573b3f 100644 --- a/content/renderer/loader/request_extra_data.h +++ b/content/renderer/loader/request_extra_data.h
@@ -106,15 +106,6 @@ is_for_no_state_prefetch_ = prefetch; } - // The request is downloaded to the network cache, but not rendered or - // executed. - bool download_to_network_cache_only() const { - return download_to_network_cache_only_; - } - void set_download_to_network_cache_only(bool download_to_cache) { - download_to_network_cache_only_ = download_to_cache; - } - // Copy of the settings value determining if mixed plugin content should be // blocked. bool block_mixed_plugin_content() const { @@ -174,7 +165,6 @@ base::OnceClosure continue_navigation_function_; bool initiated_in_secure_context_; bool is_for_no_state_prefetch_; - bool download_to_network_cache_only_; bool block_mixed_plugin_content_; bool navigation_initiated_by_renderer_; bool attach_same_site_cookies_;
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index 3d4460d..492bd7d 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -740,7 +740,7 @@ extra_data->CopyToResourceRequest(resource_request.get()); std::unique_ptr<RequestPeer> peer; - if (extra_data->download_to_network_cache_only()) { + if (request.IsDownloadToNetworkCacheOnly()) { peer = std::make_unique<SinkPeer>(this); } else { const bool discard_body =
diff --git a/content/renderer/media/stream/processed_local_audio_source.cc b/content/renderer/media/stream/processed_local_audio_source.cc index bd94662..10622251 100644 --- a/content/renderer/media/stream/processed_local_audio_source.cc +++ b/content/renderer/media/stream/processed_local_audio_source.cc
@@ -177,7 +177,8 @@ // Verify that the reported input channel configuration is supported. if (channel_layout != media::CHANNEL_LAYOUT_MONO && channel_layout != media::CHANNEL_LAYOUT_STEREO && - channel_layout != media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) { + channel_layout != media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC && + channel_layout != media::CHANNEL_LAYOUT_DISCRETE) { WebRtcLogMessage(base::StringPrintf( "ProcessedLocalAudioSource::EnsureSourceIsStarted() fails " " because the input channel layout (%d) is not supported.", @@ -203,6 +204,11 @@ channel_layout, device().input.sample_rate(), device().input.sample_rate() / 100); params.set_effects(device().input.effects()); + if (channel_layout == media::CHANNEL_LAYOUT_DISCRETE) { + DCHECK_LE(device().input.channels(), 2); + params.set_channels_for_discrete(device().input.channels()); + } + DVLOG(1) << params.AsHumanReadableString(); DCHECK(params.IsValid()); media::AudioSourceParameters source_params(device().session_id); const bool use_remote_apm =
diff --git a/content/renderer/media/stream/track_audio_renderer.cc b/content/renderer/media/stream/track_audio_renderer.cc index 0744c1d..b678ec37 100644 --- a/content/renderer/media/stream/track_audio_renderer.cc +++ b/content/renderer/media/stream/track_audio_renderer.cc
@@ -305,9 +305,13 @@ source_params_.sample_rate(), media::AudioLatency::GetRtcBufferSize( source_params_.sample_rate(), hardware_params.frames_per_buffer())); + if (sink_params.channel_layout() == media::CHANNEL_LAYOUT_DISCRETE) { + DCHECK_LE(source_params_.channels(), 2); + sink_params.set_channels_for_discrete(source_params_.channels()); + } DVLOG(1) << ("TrackAudioRenderer::MaybeStartSink() -- Starting sink. " - "source_params_={") - << source_params_.AsHumanReadableString() << "}, hardware_params_={" + "source_params={") + << source_params_.AsHumanReadableString() << "}, hardware_params={" << hardware_params.AsHumanReadableString() << "}, sink parameters={" << sink_params.AsHumanReadableString() << '}';
diff --git a/content/renderer/media/webrtc/rtc_video_encoder.cc b/content/renderer/media/webrtc/rtc_video_encoder.cc index 6e0dfce..87e80db 100644 --- a/content/renderer/media/webrtc/rtc_video_encoder.cc +++ b/content/renderer/media/webrtc/rtc_video_encoder.cc
@@ -325,7 +325,7 @@ input_visible_size_ = input_visible_size; const media::VideoEncodeAccelerator::Config config( media::PIXEL_FORMAT_I420, input_visible_size_, profile, bitrate * 1000, - base::nullopt, base::nullopt, + base::nullopt, base::nullopt, base::nullopt, video_content_type_ == webrtc::VideoContentType::SCREENSHARE ? media::VideoEncodeAccelerator::Config::ContentType::kDisplay : media::VideoEncodeAccelerator::Config::ContentType::kCamera);
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 7b26460a..9e6f59f1 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -4970,12 +4970,13 @@ bool is_for_no_state_prefetch = GetContentClient()->renderer()->IsPrefetchOnly(this, request); extra_data->set_is_for_no_state_prefetch(is_for_no_state_prefetch); - extra_data->set_download_to_network_cache_only( - is_for_no_state_prefetch && resource_type != RESOURCE_TYPE_MAIN_FRAME); extra_data->set_initiated_in_secure_context(frame_document.IsSecureContext()); extra_data->set_attach_same_site_cookies(attach_same_site_cookies); extra_data->set_frame_request_blocker(frame_request_blocker_); + request.SetDownloadToNetworkCacheOnly( + is_for_no_state_prefetch && resource_type != RESOURCE_TYPE_MAIN_FRAME); + // The RenderThreadImpl or its URLLoaderThrottleProvider member may not be // valid in some tests. RenderThreadImpl* render_thread = RenderThreadImpl::current();
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn index 4babaa6..224c505 100644 --- a/content/shell/android/BUILD.gn +++ b/content/shell/android/BUILD.gn
@@ -122,6 +122,7 @@ ":content_shell_java", ":content_shell_manifest", "//base:base_java", + "//components/embedder_support/android:view_java", "//content/public/android:content_java", "//media/capture/video/android:capture_java", "//net/android:net_java",
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py index c161d5e..dfb9934 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -408,7 +408,12 @@ ['win', 'd3d9', 'passthrough'], bug=2192) # ANGLE bug ID # Vulkan / Win / Passthough command decoder + self.Fail('conformance/attribs/' + + 'gl-vertex-attrib-unconsumed-out-of-bounds.html', + ['win', 'passthrough', 'vulkan'], bug=2708) # ANGLE bug ID self.Fail('conformance/canvas/canvas-test.html', + ['win', 'passthrough', 'vulkan'], bug=2929) # ANGLE bug ID + self.Fail('conformance/canvas/canvas-zero-size.html', ['win', 'passthrough', 'vulkan'], bug=2918) # ANGLE bug ID self.Fail('conformance/context/' + 'context-attribute-preserve-drawing-buffer.html', @@ -561,14 +566,20 @@ ['win', 'passthrough', 'vulkan', 'nvidia'], bug=2922) # ANGLE bug ID self.Fail('conformance/textures/misc/texture-size.html', ['win', 'passthrough', 'vulkan', 'nvidia'], bug=2915) # ANGLE bug ID + self.Fail('conformance/textures/misc/texture-size-cube-maps.html', + ['win', 'passthrough', 'vulkan', 'nvidia'], bug=2930) # ANGLE bug ID self.Fail('conformance/limits/gl-max-texture-dimensions.html', ['win', 'passthrough', 'vulkan', 'nvidia'], bug=2915) # ANGLE bug ID + self.Fail('deqp/data/gles2/shaders/conversions.html', + ['win', 'passthrough', 'vulkan', 'nvidia'], bug=2926) # ANGLE bug ID # Vulkan / Win / Intel / Passthough command decoder self.Fail('conformance/rendering/clipping-wide-points.html', ['win', 'passthrough', 'vulkan', 'intel'], bug=2722) # ANGLE bug ID # Vulkan / Win / AMD / Passthough command decoder + self.Fail('conformance/buffers/buffer-data-dynamic-delay.html', + ['win', 'passthrough', 'vulkan', 'amd'], bug=2931) # ANGLE bug ID self.Fail('conformance/canvas/to-data-url-test.html', ['win', 'passthrough', 'vulkan', 'amd'], bug=2918) # ANGLE bug ID self.Fail('conformance/context/premultiplyalpha-test.html',
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 01b7370..63c5638 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -57,6 +57,8 @@ #include "gpu/command_buffer/service/raster_decoder_context_state.h" #include "gpu/command_buffer/service/service_font_manager.h" #include "gpu/command_buffer/service/service_transfer_cache.h" +#include "gpu/command_buffer/service/shared_image_manager.h" +#include "gpu/command_buffer/service/shared_image_representation.h" #include "gpu/command_buffer/service/skia_utils.h" #include "gpu/command_buffer/service/vertex_array_manager.h" #include "gpu/command_buffer/service/vertex_attrib_manager.h" @@ -808,6 +810,7 @@ // Raster helpers. scoped_refptr<ServiceFontManager> font_manager_; + std::unique_ptr<SharedImageRepresentationSkia> shared_image_; sk_sp<SkSurface> sk_surface_; std::unique_ptr<SkDeferredDisplayListRecorder> recorder_; @@ -3008,16 +3011,10 @@ DLOG_IF(ERROR, !mailbox.Verify()) << "BeginRasterCHROMIUM was " "passed a mailbox that was not " "generated by ProduceTextureCHROMIUM."; - gles2::Texture* texture = nullptr; - WrappedSkImage* sk_image_texture = nullptr; - if (group_->gpu_preferences().enable_raster_to_sk_image) { - sk_image_texture = WrappedSkImage::CheckedCast( - group_->mailbox_manager()->ConsumeTexture(mailbox)); - } else { - texture = gles2::Texture::CheckedCast( - group_->mailbox_manager()->ConsumeTexture(mailbox)); - } - if (!texture && !sk_image_texture) { + + DCHECK(!shared_image_); + shared_image_ = group_->shared_image_manager()->ProduceSkia(mailbox); + if (!shared_image_) { LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBeginRasterCHROMIUM", "passed invalid mailbox."); return; @@ -3042,24 +3039,13 @@ if (final_msaa_count > gr_context()->maxSurfaceSampleCountForColorType(sk_color_type)) final_msaa_count = 0; - if (sk_image_texture) { - sk_surface_ = sk_image_texture->GetSkSurface(final_msaa_count, - sk_color_type, surface_props); - } else { - GrBackendTexture gr_texture; - if (!GetGrBackendTexture(gl_version_info(), "glBeginRasterCHROMIUM", - GetErrorState(), *texture, color_type, - &gr_texture)) { - return; - } - sk_surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget( - gr_context(), gr_texture, kTopLeft_GrSurfaceOrigin, final_msaa_count, - sk_color_type, nullptr, &surface_props); - } + sk_surface_ = shared_image_->BeginWriteAccess(gr_context(), final_msaa_count, + sk_color_type, surface_props); if (!sk_surface_) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", "failed to create surface"); + shared_image_.reset(); return; } @@ -3072,7 +3058,8 @@ if (!color_space_entry || !color_space_entry->color_space().IsValid()) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM", "failed to find valid color space"); - sk_surface_.reset(); + shared_image_->EndWriteAccess(std::move(sk_surface_)); + shared_image_.reset(); return; } @@ -3097,18 +3084,11 @@ // TODO(enne): This doesn't handle the case where the background color // changes and so any extra pixels outside the raster area that get // sampled may be incorrect. - if (sk_image_texture) { - if (!sk_image_texture->cleared()) { - raster_canvas_->drawColor(sk_color); - sk_image_texture->SetCleared(); - } - } else { - if (texture->IsLevelCleared(texture->target(), 0)) - return; + if (shared_image_->IsCleared()) + return; - raster_canvas_->drawColor(sk_color); - texture->SetLevelCleared(texture->target(), 0, true); - } + raster_canvas_->drawColor(sk_color); + shared_image_->SetCleared(); } scoped_refptr<Buffer> RasterDecoderImpl::GetShmBuffer(uint32_t shm_id) { @@ -3211,7 +3191,13 @@ sk_surface_->draw(ddl.get()); } sk_surface_->prepareForExternalIO(); - sk_surface_.reset(); + if (!shared_image_) { + // Test only path for SetUpForRasterCHROMIUMForTest. + sk_surface_.reset(); + } else { + shared_image_->EndWriteAccess(std::move(sk_surface_)); + shared_image_.reset(); + } // Unlock all font handles. This needs to be deferred until // SkSurface::prepareForExternalIO since that flushes batched Gr operations in
diff --git a/gpu/command_buffer/service/shared_image_backing.cc b/gpu/command_buffer/service/shared_image_backing.cc index e7a1b74..00ca869 100644 --- a/gpu/command_buffer/service/shared_image_backing.cc +++ b/gpu/command_buffer/service/shared_image_backing.cc
@@ -35,4 +35,9 @@ return nullptr; } +std::unique_ptr<SharedImageRepresentationSkia> SharedImageBacking::ProduceSkia( + SharedImageManager* manager) { + return nullptr; +} + } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image_backing.h b/gpu/command_buffer/service/shared_image_backing.h index 6cae042..6217ff8f 100644 --- a/gpu/command_buffer/service/shared_image_backing.h +++ b/gpu/command_buffer/service/shared_image_backing.h
@@ -23,6 +23,7 @@ class SharedImageManager; class SharedImageRepresentationGLTexture; class SharedImageRepresentationGLTexturePassthrough; +class SharedImageRepresentationSkia; // Represents the actual storage (GL texture, VkImage, GMB) for a SharedImage. // Should not be accessed direclty, instead is accessed through a @@ -77,6 +78,8 @@ SharedImageManager* manager); virtual std::unique_ptr<SharedImageRepresentationGLTexturePassthrough> ProduceGLTexturePassthrough(SharedImageManager* manager); + virtual std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia( + SharedImageManager* manager); // Used by subclasses in Destroy. bool have_context() const { return have_context_; }
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc index 191ac91f..d9d65d97 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
@@ -18,8 +18,10 @@ #include "gpu/command_buffer/service/service_utils.h" #include "gpu/command_buffer/service/shared_image_backing.h" #include "gpu/command_buffer/service/shared_image_representation.h" +#include "gpu/command_buffer/service/skia_utils.h" #include "gpu/config/gpu_finch_features.h" #include "gpu/config/gpu_preferences.h" +#include "third_party/skia/include/gpu/GrBackendSurface.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/size.h" #include "ui/gl/gl_bindings.h" @@ -65,6 +67,73 @@ scoped_refptr<gles2::TexturePassthrough> texture_passthrough_; }; +class SharedImageRepresentationSkiaImpl : public SharedImageRepresentationSkia { + public: + SharedImageRepresentationSkiaImpl(SharedImageManager* manager, + SharedImageBacking* backing, + GLenum target, + GLenum internal_format, + GLenum driver_internal_format, + GLuint service_id) + : SharedImageRepresentationSkia(manager, backing), + target_(target), + internal_format_(internal_format), + driver_internal_format_(driver_internal_format), + service_id_(service_id) {} + + ~SharedImageRepresentationSkiaImpl() override { DCHECK(!write_surface_); } + + sk_sp<SkSurface> BeginWriteAccess( + GrContext* gr_context, + int final_msaa_count, + SkColorType color_type, + const SkSurfaceProps& surface_props) override { + if (write_surface_) + return nullptr; + + GrBackendTexture backend_texture; + if (!GetGrBackendTexture(target_, size(), internal_format_, + driver_internal_format_, service_id_, color_type, + &backend_texture)) { + return nullptr; + } + auto surface = SkSurface::MakeFromBackendTextureAsRenderTarget( + gr_context, backend_texture, kTopLeft_GrSurfaceOrigin, final_msaa_count, + color_type, nullptr, &surface_props); + write_surface_ = surface.get(); + return surface; + } + + void EndWriteAccess(sk_sp<SkSurface> surface) override { + DCHECK_EQ(surface.get(), write_surface_); + DCHECK(surface->unique()); + // TODO(ericrk): Keep the surface around for re-use. + write_surface_ = nullptr; + } + + bool BeginReadAccess(SkColorType color_type, + GrBackendTexture* backend_texture) override { + if (!GetGrBackendTexture(target_, size(), internal_format_, + driver_internal_format_, service_id_, color_type, + backend_texture)) { + return false; + } + return true; + } + + void EndReadAccess() override { + // TODO(ericrk): Handle begin/end correctness checks. + } + + private: + GLenum target_; + GLenum internal_format_ = 0; + GLenum driver_internal_format_ = 0; + GLuint service_id_; + + SkSurface* write_surface_ = nullptr; +}; + // Implementation of SharedImageBacking that creates a GL Texture and stores it // as a gles2::Texture. Can be used with the legacy mailbox implementation. class SharedImageBackingGLTexture : public SharedImageBacking { @@ -74,9 +143,13 @@ const gfx::Size& size, const gfx::ColorSpace& color_space, uint32_t usage, - gles2::Texture* texture) + gles2::Texture* texture, + GLenum internal_format, + GLenum driver_internal_format) : SharedImageBacking(mailbox, format, size, color_space, usage), - texture_(texture) { + texture_(texture), + internal_format_(internal_format), + driver_internal_format_(driver_internal_format) { DCHECK(texture_); } @@ -130,13 +203,21 @@ return std::make_unique<SharedImageRepresentationGLTextureImpl>( manager, this, texture_); } + std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia( + SharedImageManager* manager) override { + return std::make_unique<SharedImageRepresentationSkiaImpl>( + manager, this, texture_->target(), internal_format_, + driver_internal_format_, texture_->service_id()); + } private: gles2::Texture* texture_ = nullptr; + GLenum internal_format_ = 0; + GLenum driver_internal_format_ = 0; }; // Implementation of SharedImageBacking that creates a GL Texture and stores it -// as a gles2::PassthroughTexture. Can be used with the legacy mailbox +// as a gles2::TexturePassthrough. Can be used with the legacy mailbox // implementation. class SharedImageBackingPassthroughGLTexture : public SharedImageBacking { public: @@ -146,9 +227,13 @@ const gfx::Size& size, const gfx::ColorSpace& color_space, uint32_t usage, - scoped_refptr<gles2::TexturePassthrough> passthrough_texture) + scoped_refptr<gles2::TexturePassthrough> passthrough_texture, + GLenum internal_format, + GLenum driver_internal_format) : SharedImageBacking(mailbox, format, size, color_space, usage), - passthrough_texture_(std::move(passthrough_texture)) { + passthrough_texture_(std::move(passthrough_texture)), + internal_format_(internal_format), + driver_internal_format_(driver_internal_format) { DCHECK(passthrough_texture_); } @@ -178,9 +263,17 @@ return std::make_unique<SharedImageRepresentationGLTexturePassthroughImpl>( manager, this, passthrough_texture_); } + std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia( + SharedImageManager* manager) override { + return std::make_unique<SharedImageRepresentationSkiaImpl>( + manager, this, passthrough_texture_->target(), internal_format_, + driver_internal_format_, passthrough_texture_->service_id()); + } private: scoped_refptr<gles2::TexturePassthrough> passthrough_texture_; + GLenum internal_format_ = 0; + GLenum driver_internal_format_ = 0; bool is_cleared_ = false; }; @@ -389,6 +482,12 @@ api->glBindBufferFn(GL_PIXEL_UNPACK_BUFFER, bound_pixel_unpack_buffer); } + // Calculate |driver_internal_format| here rather than caching on + // format_info, as we need to use the |level_info_internal_format| which may + // depend on the generated |image|. + GLenum driver_internal_format = + gl::GetInternalFormat(gl::GLContext::GetCurrent()->GetVersionInfo(), + level_info_internal_format); std::unique_ptr<SharedImageBacking> backing; if (use_passthrough_) { scoped_refptr<gles2::TexturePassthrough> passthrough_texture = @@ -397,15 +496,16 @@ passthrough_texture->SetLevelImage(target, 0, image.get()); backing = std::make_unique<SharedImageBackingPassthroughGLTexture>( mailbox, format, size, color_space, usage, - std::move(passthrough_texture)); + std::move(passthrough_texture), level_info_internal_format, + driver_internal_format); } else { gles2::Texture* texture = new gles2::Texture(service_id); texture->SetLightweightRef(memory_tracker_.get()); texture->SetTarget(target, 1); texture->sampler_state_.min_filter = GL_LINEAR; texture->sampler_state_.mag_filter = GL_LINEAR; - texture->sampler_state_.wrap_r = GL_CLAMP_TO_EDGE; texture->sampler_state_.wrap_s = GL_CLAMP_TO_EDGE; + texture->sampler_state_.wrap_t = GL_CLAMP_TO_EDGE; texture->SetLevelInfo(target, 0, level_info_internal_format, size.width(), size.height(), 1, 0, format_info.gl_format, format_info.gl_type, cleared_rect); @@ -415,7 +515,8 @@ texture->SetLevelImage(target, 0, image.get(), gles2::Texture::BOUND); texture->SetImmutable(true); backing = std::make_unique<SharedImageBackingGLTexture>( - mailbox, format, size, color_space, usage, texture); + mailbox, format, size, color_space, usage, texture, + level_info_internal_format, driver_internal_format); } api->glBindTextureFn(target, old_texture_binding);
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc index 64829216..d9c3e0c 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc
@@ -8,6 +8,7 @@ #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/service/mailbox_manager_impl.h" +#include "gpu/command_buffer/service/raster_decoder_context_state.h" #include "gpu/command_buffer/service/service_utils.h" #include "gpu/command_buffer/service/shared_image_backing.h" #include "gpu/command_buffer/service/shared_image_manager.h" @@ -18,6 +19,8 @@ #include "gpu/config/gpu_feature_info.h" #include "gpu/config/gpu_preferences.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/gpu/GrBackendSurface.h" #include "ui/gfx/color_space.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" @@ -45,15 +48,24 @@ workarounds.max_texture_size = INT_MAX - 1; backing_factory_ = std::make_unique<SharedImageBackingFactoryGLTexture>( preferences, workarounds, GpuFeatureInfo(), &image_factory_, nullptr); + + scoped_refptr<gl::GLShareGroup> share_group = new gl::GLShareGroup(); + context_state_ = new raster::RasterDecoderContextState( + std::move(share_group), surface_, context_, + false /* use_virtualized_gl_contexts */); + context_state_->InitializeGrContext(workarounds, nullptr); } bool use_passthrough() { return GetParam() && gles2::PassthroughCommandDecoderSupported(); } + GrContext* gr_context() { return context_state_->gr_context.get(); } + protected: scoped_refptr<gl::GLSurface> surface_; scoped_refptr<gl::GLContext> context_; + scoped_refptr<raster::RasterDecoderContextState> context_state_; TextureImageFactory image_factory_; std::unique_ptr<SharedImageBackingFactoryGLTexture> backing_factory_; gles2::MailboxManagerImpl mailbox_manager_; @@ -107,7 +119,7 @@ gl_representation.reset(); } - // Finally, validate a SharedImageRepresentationGLTexturePassthrough. + // Next, validate a SharedImageRepresentationGLTexturePassthrough. if (use_passthrough()) { auto gl_representation = shared_image_manager_.ProduceGLTexturePassthrough(mailbox); @@ -122,6 +134,25 @@ gl_representation.reset(); } + // Finally, validate a SharedImageRepresentationSkia. + auto skia_representation = shared_image_manager_.ProduceSkia(mailbox); + EXPECT_TRUE(skia_representation); + auto surface = skia_representation->BeginWriteAccess( + gr_context(), 0, kRGBA_8888_SkColorType, + SkSurfaceProps(0, kUnknown_SkPixelGeometry)); + EXPECT_TRUE(surface); + EXPECT_EQ(size.width(), surface->width()); + EXPECT_EQ(size.height(), surface->height()); + skia_representation->EndWriteAccess(std::move(surface)); + GrBackendTexture backend_texture; + EXPECT_TRUE(skia_representation->BeginReadAccess( + + kRGBA_8888_SkColorType, &backend_texture)); + EXPECT_EQ(size.width(), backend_texture.width()); + EXPECT_EQ(size.width(), backend_texture.width()); + skia_representation->EndReadAccess(); + skia_representation.reset(); + shared_image_manager_.Unregister(mailbox); EXPECT_FALSE(mailbox_manager_.ConsumeTexture(mailbox)); } @@ -171,7 +202,7 @@ gl_representation.reset(); } - // Finally, validate a SharedImageRepresentationGLTexturePassthrough. + // Next, validate a SharedImageRepresentationGLTexturePassthrough. if (use_passthrough()) { auto gl_representation = shared_image_manager_.ProduceGLTexturePassthrough(mailbox); @@ -184,6 +215,25 @@ gl_representation.reset(); } + // Finally, validate a SharedImageRepresentationSkia. + auto skia_representation = shared_image_manager_.ProduceSkia(mailbox); + EXPECT_TRUE(skia_representation); + auto surface = skia_representation->BeginWriteAccess( + gr_context(), 0, kRGBA_8888_SkColorType, + SkSurfaceProps(0, kUnknown_SkPixelGeometry)); + EXPECT_TRUE(surface); + EXPECT_EQ(size.width(), surface->width()); + EXPECT_EQ(size.height(), surface->height()); + skia_representation->EndWriteAccess(std::move(surface)); + GrBackendTexture backend_texture; + EXPECT_TRUE(skia_representation->BeginReadAccess( + + kRGBA_8888_SkColorType, &backend_texture)); + EXPECT_EQ(size.width(), backend_texture.width()); + EXPECT_EQ(size.width(), backend_texture.width()); + skia_representation->EndReadAccess(); + skia_representation.reset(); + shared_image_manager_.Unregister(mailbox); EXPECT_FALSE(mailbox_manager_.ConsumeTexture(mailbox));
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc index 4e8652a..070b1f4 100644 --- a/gpu/command_buffer/service/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -62,8 +62,9 @@ } std::unique_ptr<SharedImageBacking> backing; - if (wrapped_sk_image_factory_ && - (usage & SHARED_IMAGE_USAGE_OOP_RASTERIZATION)) { + bool using_wrapped_sk_image = wrapped_sk_image_factory_ && + (usage & SHARED_IMAGE_USAGE_OOP_RASTERIZATION); + if (using_wrapped_sk_image) { backing = wrapped_sk_image_factory_->CreateSharedImage( mailbox, format, size, color_space, usage); } else { @@ -77,7 +78,8 @@ } // TODO(ericrk): Handle the non-legacy case. - if (!backing->ProduceLegacyMailbox(mailbox_manager_)) { + if (!using_wrapped_sk_image && + !backing->ProduceLegacyMailbox(mailbox_manager_)) { LOG(ERROR) << "CreateSharedImage: could not convert backing to legacy mailbox."; backing->Destroy();
diff --git a/gpu/command_buffer/service/shared_image_manager.cc b/gpu/command_buffer/service/shared_image_manager.cc index 70e1c6c..4f53eca 100644 --- a/gpu/command_buffer/service/shared_image_manager.cc +++ b/gpu/command_buffer/service/shared_image_manager.cc
@@ -75,6 +75,11 @@ found->backing->OnContextLost(); } +bool SharedImageManager::IsSharedImage(const Mailbox& mailbox) { + auto found = images_.find(mailbox); + return found != images_.end(); +} + std::unique_ptr<SharedImageRepresentationGLTexture> SharedImageManager::ProduceGLTexture(const Mailbox& mailbox) { auto found = images_.find(mailbox); @@ -117,6 +122,27 @@ return representation; } +std::unique_ptr<SharedImageRepresentationSkia> SharedImageManager::ProduceSkia( + const Mailbox& mailbox) { + auto found = images_.find(mailbox); + if (found == images_.end()) { + LOG(ERROR) << "SharedImageManager::ProduceSkia: Trying to Produce a " + "Skia representation from a non-existent mailbox."; + return nullptr; + } + + auto representation = found->backing->ProduceSkia(this); + if (!representation) { + LOG(ERROR) << "SharedImageManager::ProduceSkia: Trying to produce a " + "Skia representation from an incompatible mailbox."; + return nullptr; + } + + // Take a ref. This is released when we destroy the generated representation. + found->ref_count++; + return representation; +} + void SharedImageManager::OnRepresentationDestroyed(const Mailbox& mailbox) { // Just call Unregister, which releases a ref on our backing. Unregister(mailbox);
diff --git a/gpu/command_buffer/service/shared_image_manager.h b/gpu/command_buffer/service/shared_image_manager.h index a518fde3..b86c3db 100644 --- a/gpu/command_buffer/service/shared_image_manager.h +++ b/gpu/command_buffer/service/shared_image_manager.h
@@ -28,6 +28,10 @@ // Marks the backing associated with a mailbox as context lost. void OnContextLost(const Mailbox& mailbox); + // Indicates whether a mailbox is associated with a SharedImage. + // TODO: Remove this once all mailboxes are SharedImages. + bool IsSharedImage(const Mailbox& mailbox); + // Accessors which return a SharedImageRepresentation. Representations also // take a ref on the mailbox, releasing it when the representation is // destroyed. @@ -35,6 +39,8 @@ const Mailbox& mailbox); std::unique_ptr<SharedImageRepresentationGLTexturePassthrough> ProduceGLTexturePassthrough(const Mailbox& mailbox); + std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia( + const Mailbox& mailbox); // Called by SharedImageRepresentation in the destructor. void OnRepresentationDestroyed(const Mailbox& mailbox);
diff --git a/gpu/command_buffer/service/shared_image_representation.h b/gpu/command_buffer/service/shared_image_representation.h index 08a5642..b106c02 100644 --- a/gpu/command_buffer/service/shared_image_representation.h +++ b/gpu/command_buffer/service/shared_image_representation.h
@@ -10,9 +10,12 @@ #include "gpu/command_buffer/service/shared_image_backing.h" #include "gpu/command_buffer/service/shared_image_manager.h" #include "gpu/gpu_gles2_export.h" +#include "third_party/skia/include/core/SkSurface.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/size.h" +class GrContext; + namespace gpu { namespace gles2 { class Texture; @@ -38,6 +41,9 @@ // backing should be treated as destroyed. void OnContextLost() { backing_->OnContextLost(); } + protected: + SharedImageBacking* backing() { return backing_; } + private: SharedImageManager* manager_; SharedImageBacking* backing_; @@ -63,6 +69,23 @@ GetTexturePassthrough() = 0; }; +class SharedImageRepresentationSkia : public SharedImageRepresentation { + public: + SharedImageRepresentationSkia(SharedImageManager* manager, + SharedImageBacking* backing) + : SharedImageRepresentation(manager, backing) {} + + virtual sk_sp<SkSurface> BeginWriteAccess( + GrContext* gr_context, + int final_msaa_count, + SkColorType color_type, + const SkSurfaceProps& surface_props) = 0; + virtual void EndWriteAccess(sk_sp<SkSurface> surface) = 0; + virtual bool BeginReadAccess(SkColorType color_type, + GrBackendTexture* backend_texture_out) = 0; + virtual void EndReadAccess() = 0; +}; + } // namespace gpu #endif // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_REPRESENTATION_H_
diff --git a/gpu/command_buffer/service/skia_utils.cc b/gpu/command_buffer/service/skia_utils.cc index 272a8960..a232ef6 100644 --- a/gpu/command_buffer/service/skia_utils.cc +++ b/gpu/command_buffer/service/skia_utils.cc
@@ -13,57 +13,60 @@ namespace gpu { -namespace { - -bool GetGrBackendTextureValidated(const gl::GLVersionInfo& version_info, - const char* function_name, - gles2::ErrorState* error_state, - const gles2::Texture& texture, - GLint sk_color_type, - GrBackendTexture* gr_texture) { - if (texture.target() != GL_TEXTURE_2D && - texture.target() != GL_TEXTURE_RECTANGLE_ARB) { - if (error_state) { - ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name, - "invalid texture target"); - } +bool GetGrBackendTexture(const gl::GLVersionInfo& version_info, + const TextureBase& texture_base, + GLint sk_color_type, + GrBackendTexture* gr_texture) { + if (texture_base.GetType() != TextureBase::Type::kValidated) { + NOTIMPLEMENTED(); return false; } + const auto* texture = static_cast<const gles2::Texture*>(&texture_base); int width; int height; int depth; - if (!texture.GetLevelSize(texture.target(), 0, &width, &height, &depth)) { - if (error_state) { - ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name, - "missing texture size info"); - } + if (!texture->GetLevelSize(texture->target(), 0, &width, &height, &depth)) { + LOG(ERROR) << "GetGrBackendTexture: missing texture size info."; return false; } GLenum type; GLenum internal_format; - if (!texture.GetLevelType(texture.target(), 0, &type, &internal_format)) { - if (error_state) { - ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, function_name, - "missing texture type info"); - } + if (!texture->GetLevelType(texture->target(), 0, &type, &internal_format)) { + LOG(ERROR) << "GetGrBackendTexture: missing texture type info."; + return false; + } + + GLenum driver_internal_format = + GetInternalFormat(&version_info, internal_format); + return GetGrBackendTexture(texture->target(), gfx::Size(width, height), + internal_format, driver_internal_format, + texture->service_id(), sk_color_type, gr_texture); +} + +bool GetGrBackendTexture(GLenum target, + const gfx::Size& size, + GLenum internal_format, + GLenum driver_internal_format, + GLuint service_id, + GLint sk_color_type, + GrBackendTexture* gr_texture) { + if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB) { + LOG(ERROR) << "GetGrBackendTexture: invalid texture target."; return false; } GrGLTextureInfo texture_info; - texture_info.fID = texture.service_id(); - texture_info.fTarget = texture.target(); + texture_info.fID = service_id; + texture_info.fTarget = target; - // GetInternalFormat may return a base internal format but Skia requires a + // |driver_internal_format| may be a base internal format but Skia requires a // sized internal format. So this may be adjusted below. - texture_info.fFormat = GetInternalFormat(&version_info, internal_format); + texture_info.fFormat = driver_internal_format; switch (sk_color_type) { case kARGB_4444_SkColorType: if (internal_format != GL_RGBA4 && internal_format != GL_RGBA) { - if (error_state) { - ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, - function_name, "color type mismatch"); - } + LOG(ERROR) << "GetGrBackendTexture: color type mismatch."; return false; } if (texture_info.fFormat == GL_RGBA) @@ -71,10 +74,7 @@ break; case kRGBA_8888_SkColorType: if (internal_format != GL_RGBA8_OES && internal_format != GL_RGBA) { - if (error_state) { - ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, - function_name, "color type mismatch"); - } + LOG(ERROR) << "GetGrBackendTexture: missing texture type info."; return false; } if (texture_info.fFormat == GL_RGBA) @@ -82,10 +82,7 @@ break; case kBGRA_8888_SkColorType: if (internal_format != GL_BGRA_EXT && internal_format != GL_BGRA8_EXT) { - if (error_state) { - ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, - function_name, "color type mismatch"); - } + LOG(ERROR) << "GetGrBackendTexture: missing texture type info."; return false; } if (texture_info.fFormat == GL_BGRA_EXT) @@ -94,44 +91,13 @@ texture_info.fFormat = GL_RGBA8_OES; break; default: - if (error_state) { - ERRORSTATE_SET_GL_ERROR(error_state, GL_INVALID_OPERATION, - function_name, "unsupported color type"); - } + LOG(ERROR) << "GetGrBackendTexture: unsupported color type."; return false; } - *gr_texture = GrBackendTexture(width, height, GrMipMapped::kNo, texture_info); + *gr_texture = GrBackendTexture(size.width(), size.height(), GrMipMapped::kNo, + texture_info); return true; } -} // namespace - -bool GetGrBackendTexture(const gl::GLVersionInfo& version_info, - const char* function_name, - gles2::ErrorState* error_state, - const TextureBase& texture, - GLint sk_color_type, - GrBackendTexture* gr_texture) { - switch (texture.GetType()) { - case TextureBase::Type::kNone: - NOTREACHED(); - return false; - case TextureBase::Type::kValidated: - return GetGrBackendTextureValidated( - version_info, function_name, error_state, - static_cast<const gles2::Texture&>(texture), sk_color_type, - gr_texture); - case TextureBase::Type::kPassthrough: - NOTIMPLEMENTED(); - return false; - case TextureBase::Type::kSkImage: - return static_cast<const raster::WrappedSkImage&>(texture) - .GetGrBackendTexture(gr_texture); - default: - NOTREACHED(); - } - return false; -} - } // namespace gpu
diff --git a/gpu/command_buffer/service/skia_utils.h b/gpu/command_buffer/service/skia_utils.h index c098d2d8..acb31ac 100644 --- a/gpu/command_buffer/service/skia_utils.h +++ b/gpu/command_buffer/service/skia_utils.h
@@ -9,9 +9,15 @@ // Forwardly declare a few GL types to avoid including GL header files. typedef int GLint; +typedef unsigned int GLenum; +typedef unsigned int GLuint; class GrBackendTexture; +namespace gfx { +class Size; +} // namespace gfx + namespace gl { struct GLVersionInfo; } // namespace gl @@ -19,20 +25,24 @@ namespace gpu { class TextureBase; -namespace gles2 { -class ErrorState; -} // namespace gles2 - -// Wraps a gpu::Texture into Skia API as a GrBackendTexture. Skia does not take -// ownership. Returns true on success. GL errors may be reported in -// |error_state| on failure. +// Wraps a gpu::TextureBase into Skia API as a GrBackendTexture. Skia does not +// take ownership. Returns true on success. +// TODO(ericrk): Remove this once all paths migrate to SharedImage. GPU_GLES2_EXPORT bool GetGrBackendTexture(const gl::GLVersionInfo& version_info, - const char* function_name, - gles2::ErrorState* error_state, const TextureBase& texture, GLint sk_color_type, GrBackendTexture* gr_texture); +// Creates a GrBackendTexture from a service ID. Skia does not take ownership. +// Returns true on success. +GPU_GLES2_EXPORT bool GetGrBackendTexture(GLenum target, + const gfx::Size& size, + GLenum internal_format, + GLenum driver_internal_format, + GLuint service_id, + GLint sk_color_type, + GrBackendTexture* gr_texture); + } // namespace gpu #endif // GPU_COMMAND_BUFFER_SERVICE_SKIA_UTILS_H_
diff --git a/gpu/command_buffer/service/texture_base.cc b/gpu/command_buffer/service/texture_base.cc index f5fab8d..ba266590 100644 --- a/gpu/command_buffer/service/texture_base.cc +++ b/gpu/command_buffer/service/texture_base.cc
@@ -37,8 +37,4 @@ return TextureBase::Type::kNone; } -uint64_t TextureBase::GetTracingId() const { - return service_id_; -} - } // namespace gpu
diff --git a/gpu/command_buffer/service/texture_base.h b/gpu/command_buffer/service/texture_base.h index 09cf818..69463e4 100644 --- a/gpu/command_buffer/service/texture_base.h +++ b/gpu/command_buffer/service/texture_base.h
@@ -30,11 +30,9 @@ MailboxManager* mailbox_manager() const { return mailbox_manager_; } // An identifier for subclasses. Necessary for safe downcasting. - enum class Type { kNone, kValidated, kPassthrough, kSkImage }; + enum class Type { kNone, kValidated, kPassthrough }; virtual Type GetType() const; - virtual uint64_t GetTracingId() const; - protected: // The id of the texture. unsigned int service_id_;
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index f9398f2..4389a128 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc
@@ -3609,7 +3609,7 @@ // Add a |service_guid| which expresses shared ownership between the various // |client_guid|s. auto service_guid = - gl::GetGLTextureServiceGUIDForTracing(ref->texture()->GetTracingId()); + gl::GetGLTextureServiceGUIDForTracing(ref->texture()->service_id()); pmd->CreateSharedGlobalAllocatorDump(service_guid); int importance = 0; // Default importance.
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc index 561da48f..ad25b6db 100644 --- a/gpu/command_buffer/service/wrapped_sk_image.cc +++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -14,6 +14,7 @@ #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/raster_decoder_context_state.h" #include "gpu/command_buffer/service/shared_image_backing.h" +#include "gpu/command_buffer/service/shared_image_representation.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurfaceProps.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" @@ -26,39 +27,30 @@ namespace { -class WrappedSkImageBacking : public SharedImageBacking { +class WrappedSkImage : public SharedImageBacking { public: - WrappedSkImageBacking(const Mailbox& mailbox, - viz::ResourceFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - uint32_t usage, - std::unique_ptr<WrappedSkImage> wrapped_sk_image) - : SharedImageBacking(mailbox, format, size, color_space, usage), - wrapped_sk_image_(std::move(wrapped_sk_image)) { - DCHECK(!!wrapped_sk_image_); + ~WrappedSkImage() override { + DCHECK(context_state_->context_lost || + context_state_->context->IsCurrent(nullptr)); + if (!context_state_->context_lost) + context_state_->need_context_state_reset = true; } - ~WrappedSkImageBacking() override { DCHECK(!wrapped_sk_image_); } - + // SharedImageBacking implementation. bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override { - DCHECK(!!wrapped_sk_image_); - mailbox_manager->ProduceTexture(mailbox(), wrapped_sk_image_.get()); - return true; + return false; } void Destroy() override { - DCHECK(!!wrapped_sk_image_); - wrapped_sk_image_.reset(); + DCHECK(!!image_); + image_.reset(); } - bool IsCleared() const override { return wrapped_sk_image_->cleared(); } + bool IsCleared() const override { return cleared_; } - void SetCleared() override { wrapped_sk_image_->SetCleared(); } + void SetCleared() override { cleared_ = true; } - size_t EstimatedSize() const override { - return wrapped_sk_image_->estimated_size(); - } + size_t EstimatedSize() const override { return estimated_size_; } void OnMemoryDump(const std::string& dump_name, base::trace_event::MemoryAllocatorDump* dump, @@ -67,8 +59,7 @@ // Add a |service_guid| which expresses shared ownership between the // various GPU dumps. auto client_guid = GetSharedImageGUIDForTracing(mailbox()); - auto service_guid = gl::GetGLTextureServiceGUIDForTracing( - wrapped_sk_image_->GetTracingId()); + auto service_guid = gl::GetGLTextureServiceGUIDForTracing(tracing_id_); pmd->CreateSharedGlobalAllocatorDump(service_guid); // TODO(piman): coalesce constant with TextureManager::DumpTextureRef. int importance = 2; // This client always owns the ref. @@ -76,10 +67,145 @@ pmd->AddOwnershipEdge(client_guid, service_guid, importance); } - private: - std::unique_ptr<WrappedSkImage> wrapped_sk_image_; + sk_sp<SkSurface> GetSkSurface(int final_msaa_count, + SkColorType color_type, + const SkSurfaceProps& surface_props) { + if (context_state_->context_lost) + return nullptr; + DCHECK(context_state_->context->IsCurrent(context_state_->surface.get())); + GrBackendTexture gr_texture = + image_->getBackendTexture(/*flushPendingGrContextIO=*/true); + DCHECK(gr_texture.isValid()); + return SkSurface::MakeFromBackendTextureAsRenderTarget( + context_state_->gr_context.get(), gr_texture, kTopLeft_GrSurfaceOrigin, + final_msaa_count, color_type, /*colorSpace=*/nullptr, &surface_props); + } - DISALLOW_COPY_AND_ASSIGN(WrappedSkImageBacking); + bool GetGrBackendTexture(GrBackendTexture* gr_texture) const { + context_state_->need_context_state_reset = true; + *gr_texture = image_->getBackendTexture(/*flushPendingGrContextIO=*/true); + return gr_texture->isValid(); + } + + protected: + std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia( + SharedImageManager* manager) override; + + private: + friend class gpu::raster::WrappedSkImageFactory; + + WrappedSkImage(const Mailbox& mailbox, + viz::ResourceFormat format, + const gfx::Size& size, + const gfx::ColorSpace& color_space, + uint32_t usage, + raster::RasterDecoderContextState* context_state) + : SharedImageBacking(mailbox, format, size, color_space, usage), + context_state_(context_state) { + DCHECK(!!context_state_); + } + + bool Initialize() { + if (context_state_->context_lost) + return false; + DCHECK(context_state_->context->IsCurrent(nullptr)); + + context_state_->need_context_state_reset = true; + + SkImageInfo info = SkImageInfo::Make( + size().width(), size().height(), + ResourceFormatToClosestSkColorType(/*gpu_compositing=*/true, format()), + kOpaque_SkAlphaType); + size_t stride = info.minRowBytes(); + estimated_size_ = info.computeByteSize(stride); + + auto surface = SkSurface::MakeRenderTarget(context_state_->gr_context.get(), + SkBudgeted::kNo, info); + if (!surface) + return false; + + image_ = surface->makeImageSnapshot(); + if (!image_ || !image_->isTextureBacked()) + return false; + + auto gr_texture = + image_->getBackendTexture(/*flushPendingGrContextIO=*/false); + if (!gr_texture.isValid()) + return false; + + switch (gr_texture.backend()) { + case GrBackendApi::kOpenGL: { + GrGLTextureInfo tex_info; + if (gr_texture.getGLTextureInfo(&tex_info)) + tracing_id_ = tex_info.fID; + break; + } + case GrBackendApi::kVulkan: { + GrVkImageInfo image_info; + if (gr_texture.getVkImageInfo(&image_info)) + tracing_id_ = reinterpret_cast<uint64_t>(image_info.fImage); + break; + } + default: + NOTREACHED(); + return false; + } + return true; + } + + RasterDecoderContextState* const context_state_; + + sk_sp<SkImage> image_; + uint32_t estimated_size_ = 0; + bool cleared_ = false; + + uint64_t tracing_id_ = 0; + + DISALLOW_COPY_AND_ASSIGN(WrappedSkImage); +}; + +class WrappedSkImageRepresentation : public SharedImageRepresentationSkia { + public: + WrappedSkImageRepresentation(SharedImageManager* manager, + SharedImageBacking* backing) + : SharedImageRepresentationSkia(manager, backing) {} + + ~WrappedSkImageRepresentation() override { DCHECK(!write_surface_); } + + sk_sp<SkSurface> BeginWriteAccess( + GrContext* gr_context, + int final_msaa_count, + SkColorType color_type, + const SkSurfaceProps& surface_props) override { + auto surface = wrapped_sk_image()->GetSkSurface(final_msaa_count, + color_type, surface_props); + write_surface_ = surface.get(); + return surface; + } + + void EndWriteAccess(sk_sp<SkSurface> surface) override { + DCHECK_EQ(surface.get(), write_surface_); + DCHECK(surface->unique()); + write_surface_ = nullptr; + } + + bool BeginReadAccess(SkColorType color_type, + GrBackendTexture* backend_texture) override { + if (!wrapped_sk_image()->GetGrBackendTexture(backend_texture)) + return false; + return true; + } + + void EndReadAccess() override { + // TODO(ericrk): Handle begin/end correctness checks. + } + + private: + WrappedSkImage* wrapped_sk_image() { + return static_cast<WrappedSkImage*>(backing()); + } + + SkSurface* write_surface_ = nullptr; }; } // namespace @@ -96,112 +222,16 @@ const gfx::Size& size, const gfx::ColorSpace& color_space, uint32_t usage) { - std::unique_ptr<WrappedSkImage> texture(new WrappedSkImage(context_state_)); - if (!texture->Initialize(size, format)) + std::unique_ptr<WrappedSkImage> texture(new WrappedSkImage( + mailbox, format, size, color_space, usage, context_state_)); + if (!texture->Initialize()) return nullptr; - return std::make_unique<WrappedSkImageBacking>( - mailbox, format, size, color_space, usage, std::move(texture)); + return texture; } -WrappedSkImage::WrappedSkImage(raster::RasterDecoderContextState* context_state) - : TextureBase(/*service_id=*/0), context_state_(context_state) { - DCHECK(!!context_state_); -} - -bool WrappedSkImage::Initialize(const gfx::Size& size, - viz::ResourceFormat format) { - if (context_state_->context_lost) - return false; - DCHECK(context_state_->context->IsCurrent(nullptr)); - - context_state_->need_context_state_reset = true; - - SkImageInfo info = SkImageInfo::Make( - size.width(), size.height(), - ResourceFormatToClosestSkColorType(/*gpu_compositing=*/true, format), - kOpaque_SkAlphaType); - size_t stride = info.minRowBytes(); - estimated_size_ = info.computeByteSize(stride); - - auto surface = SkSurface::MakeRenderTarget(context_state_->gr_context.get(), - SkBudgeted::kNo, info); - if (!surface) - return false; - - image_ = surface->makeImageSnapshot(); - if (!image_ || !image_->isTextureBacked()) - return false; - - auto gr_texture = - image_->getBackendTexture(/*flushPendingGrContextIO=*/false); - if (!gr_texture.isValid()) - return false; - - switch (gr_texture.backend()) { - case GrBackendApi::kOpenGL: { - GrGLTextureInfo tex_info; - if (gr_texture.getGLTextureInfo(&tex_info)) - tracing_id_ = service_id_ = tex_info.fID; - break; - } - case GrBackendApi::kVulkan: { - GrVkImageInfo image_info; - if (gr_texture.getVkImageInfo(&image_info)) - tracing_id_ = reinterpret_cast<uint64_t>(image_info.fImage); - break; - } - default: - NOTREACHED(); - return false; - } - return true; -} - -WrappedSkImage::~WrappedSkImage() { - DCHECK(context_state_->context_lost || - context_state_->context->IsCurrent(nullptr)); - if (!context_state_->context_lost) - context_state_->need_context_state_reset = true; - DeleteFromMailboxManager(); -} - -TextureBase::Type WrappedSkImage::GetType() const { - return TextureBase::Type::kSkImage; -} - -uint64_t WrappedSkImage::GetTracingId() const { - return tracing_id_; -} - -// static -WrappedSkImage* WrappedSkImage::CheckedCast(TextureBase* texture) { - if (!texture) - return nullptr; - if (texture->GetType() == TextureBase::Type::kSkImage) - return static_cast<WrappedSkImage*>(texture); - DLOG(ERROR) << "Bad typecast"; - return nullptr; -} - -sk_sp<SkSurface> WrappedSkImage::GetSkSurface( - int final_msaa_count, - SkColorType color_type, - const SkSurfaceProps& surface_props) { - if (context_state_->context_lost) - return nullptr; - DCHECK(context_state_->context->IsCurrent(context_state_->surface.get())); - GrBackendTexture gr_texture = - image_->getBackendTexture(/*flushPendingGrContextIO=*/true); - DCHECK(gr_texture.isValid()); - return SkSurface::MakeFromBackendTextureAsRenderTarget( - context_state_->gr_context.get(), gr_texture, kTopLeft_GrSurfaceOrigin, - final_msaa_count, color_type, /*colorSpace=*/nullptr, &surface_props); -} - -bool WrappedSkImage::GetGrBackendTexture(GrBackendTexture* gr_texture) const { - context_state_->need_context_state_reset = true; - *gr_texture = image_->getBackendTexture(/*flushPendingGrContextIO=*/true); - return gr_texture->isValid(); +std::unique_ptr<SharedImageRepresentationSkia> WrappedSkImage::ProduceSkia( + SharedImageManager* manager) { + return std::make_unique<WrappedSkImageRepresentation>(manager, this); } } // namespace raster
diff --git a/gpu/command_buffer/service/wrapped_sk_image.h b/gpu/command_buffer/service/wrapped_sk_image.h index faa5a7e..3fbef002 100644 --- a/gpu/command_buffer/service/wrapped_sk_image.h +++ b/gpu/command_buffer/service/wrapped_sk_image.h
@@ -15,9 +15,6 @@ #include "third_party/skia/include/core/SkImage.h" #include "ui/gfx/geometry/size.h" -class GrBackendTexture; -class SkSurfaceProps; - namespace gpu { namespace raster { @@ -43,42 +40,6 @@ DISALLOW_COPY_AND_ASSIGN(WrappedSkImageFactory); }; -class GPU_GLES2_EXPORT WrappedSkImage : public TextureBase { - public: - ~WrappedSkImage() override; - bool Initialize(const gfx::Size& size, viz::ResourceFormat format); - - // TextureBase implementation: - TextureBase::Type GetType() const override; - uint64_t GetTracingId() const override; - - static WrappedSkImage* CheckedCast(TextureBase* texture); - - sk_sp<SkSurface> GetSkSurface(int final_msaa_count, - SkColorType color_type, - const SkSurfaceProps& surface_props); - bool GetGrBackendTexture(GrBackendTexture* gr_texture) const; - - uint32_t estimated_size() const { return estimated_size_; } - bool cleared() const { return cleared_; } - void SetCleared() { cleared_ = true; } - - private: - friend class WrappedSkImageFactory; - - explicit WrappedSkImage(raster::RasterDecoderContextState* context_state); - - RasterDecoderContextState* const context_state_; - - sk_sp<SkImage> image_; - uint32_t estimated_size_ = 0; - bool cleared_ = false; - - uint64_t tracing_id_ = 0; - - DISALLOW_COPY_AND_ASSIGN(WrappedSkImage); -}; - } // namespace raster } // namespace gpu
diff --git a/gpu/ipc/client/raster_in_process_context_tests.cc b/gpu/ipc/client/raster_in_process_context_tests.cc index 4efbd45..eabc75d 100644 --- a/gpu/ipc/client/raster_in_process_context_tests.cc +++ b/gpu/ipc/client/raster_in_process_context_tests.cc
@@ -10,7 +10,9 @@ #include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/test/test_gpu_memory_buffer_manager.h" #include "gpu/command_buffer/client/raster_implementation.h" +#include "gpu/command_buffer/client/shared_image_interface.h" #include "gpu/command_buffer/client/shared_memory_limits.h" +#include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/ipc/host/gpu_memory_buffer_support.h" #include "gpu/ipc/raster_in_process_context.h" #include "gpu/ipc/service/gpu_memory_buffer_factory.h" @@ -176,22 +178,22 @@ return; } - // Create texture and allocate storage. - GLuint texture_id = - ri_->CreateTexture(/*use_buffer=*/false, kBufferUsage, kResourceFormat); - ri_->TexStorage2D(texture_id, kBufferSize.width(), kBufferSize.height()); - EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), ri_->GetError()); - - gpu::Mailbox mailbox; - ri_->ProduceTextureDirect(texture_id, mailbox.name); + // Create shared image and allocate storage. + auto* sii = context_->GetSharedImageInterface(); + gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB(); + uint32_t flags = gpu::SHARED_IMAGE_USAGE_RASTER | + gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION; + gpu::Mailbox mailbox = + sii->CreateSharedImage(kResourceFormat, kBufferSize, color_space, flags); + ri_->WaitSyncTokenCHROMIUM(sii->GenUnverifiedSyncToken().GetConstData()); // Call BeginRasterCHROMIUM. - cc::RasterColorSpace color_space(gfx::ColorSpace::CreateSRGB(), 0); + cc::RasterColorSpace raster_color_space(color_space, 0); ri_->BeginRasterCHROMIUM(/*sk_color=*/0, /*msaa_sample_count=*/0, /*can_use_lcd_text=*/false, viz::ResourceFormatToClosestSkColorType( /*gpu_compositing=*/true, kResourceFormat), - color_space, mailbox.name); + raster_color_space, mailbox.name); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), ri_->GetError()); // Should flag an error this command is not allowed between a Begin and
diff --git a/ios/chrome/browser/sync/profile_sync_service_factory.cc b/ios/chrome/browser/sync/profile_sync_service_factory.cc index cc6fa09f..a75971c 100644 --- a/ios/chrome/browser/sync/profile_sync_service_factory.cc +++ b/ios/chrome/browser/sync/profile_sync_service_factory.cc
@@ -17,6 +17,7 @@ #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/sync/driver/startup_controller.h" #include "components/sync/driver/sync_util.h" +#include "components/unified_consent/feature.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" @@ -155,6 +156,8 @@ GetApplicationContext()->GetNetworkConnectionTracker(); init_params.debug_identifier = browser_state->GetDebugName(); init_params.channel = ::GetChannel(); + init_params.user_events_separate_pref_group = + unified_consent::IsUnifiedConsentFeatureEnabled(); auto pss = std::make_unique<ProfileSyncService>(std::move(init_params)); pss->Initialize();
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn index 4a2c143..e54fb8fe 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/cells/BUILD.gn
@@ -19,6 +19,7 @@ "//ios/chrome/app/strings", "//ios/chrome/browser/ui/collection_view", "//ios/chrome/browser/ui/content_suggestions/identifier", + "//ios/chrome/browser/ui/ntp_tile_views:constants", "//ios/chrome/common/favicon", "//ui/base", "//url",
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.h b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.h index 270b04646..6a14b294e 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.h +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.h
@@ -9,14 +9,7 @@ #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" #import "ios/chrome/browser/ui/content_suggestions/cells/suggested_content.h" - -// Enum defining the actions for a ContentSuggestionsMostVisitedActionItem. -typedef NS_ENUM(NSInteger, ContentSuggestionsMostVisitedAction) { - ContentSuggestionsMostVisitedActionBookmark, - ContentSuggestionsMostVisitedActionReadingList, - ContentSuggestionsMostVisitedActionRecentTabs, - ContentSuggestionsMostVisitedActionHistory, -}; +#import "ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.h" // Item containing a most visited action button. These buttons belong to the // collection section as most visited items, but have static placement (the last @@ -24,8 +17,8 @@ @interface ContentSuggestionsMostVisitedActionItem : CollectionViewItem<SuggestedContent> -- (nonnull instancetype)initWithAction: - (ContentSuggestionsMostVisitedAction)action; +- (nonnull instancetype)initWithCollectionShortcutType: + (NTPCollectionShortcutType)type; // Text for the title of the cell. @property(nonatomic, copy, nonnull) NSString* title; @@ -34,8 +27,8 @@ // as the label. @property(nonatomic, copy, nullable) NSString* accessibilityLabel; -// The action type for this button. -@property(nonatomic, assign) ContentSuggestionsMostVisitedAction action; +// The collection that this item acts as a shortcut for. +@property(nonatomic, assign) NTPCollectionShortcutType collectionShortcutType; // Reading list count passed to the most visited cell. @property(nonatomic, assign) NSInteger count;
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.mm index b061460..5300b55a 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.mm
@@ -5,31 +5,22 @@ #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.h" #include "base/logging.h" -#include "base/strings/sys_string_conversions.h" -#include "base/strings/utf_string_conversions.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_cell.h" -#include "ios/chrome/grit/ios_strings.h" -#include "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif @implementation ContentSuggestionsMostVisitedActionItem +@synthesize metricsRecorded; +@synthesize suggestionIdentifier; -@synthesize action = _action; -@synthesize count = _count; -@synthesize metricsRecorded = _metricsRecorded; -@synthesize suggestionIdentifier = _suggestionIdentifier; -@synthesize title = _title; -@synthesize accessibilityLabel = _accessibilityLabel; - -- (instancetype)initWithAction:(ContentSuggestionsMostVisitedAction)action { +- (instancetype)initWithCollectionShortcutType:(NTPCollectionShortcutType)type { self = [super initWithType:0]; if (self) { - _action = action; + _collectionShortcutType = type; self.cellClass = [ContentSuggestionsMostVisitedActionCell class]; - self.title = [self titleForAction:_action]; + self.title = TitleForCollectionShortcutType(_collectionShortcutType); } return self; } @@ -58,7 +49,7 @@ cell.titleLabel.text = self.title; cell.accessibilityLabel = self.accessibilityLabel.length ? self.accessibilityLabel : self.title; - cell.iconView.image = [self imageForAction:_action]; + cell.iconView.image = ImageForCollectionShortcutType(_collectionShortcutType); if (self.count != 0) { cell.countLabel.text = [@(self.count) stringValue]; cell.countContainer.hidden = NO; @@ -75,63 +66,20 @@ #pragma mark - Private -// Returns the title to use for a cell with |action|. -- (NSString*)titleForAction:(ContentSuggestionsMostVisitedAction)action { - switch (action) { - case ContentSuggestionsMostVisitedActionBookmark: - return l10n_util::GetNSString(IDS_IOS_CONTENT_SUGGESTIONS_BOOKMARKS); - case ContentSuggestionsMostVisitedActionReadingList: - return l10n_util::GetNSString(IDS_IOS_CONTENT_SUGGESTIONS_READING_LIST); - case ContentSuggestionsMostVisitedActionRecentTabs: - return l10n_util::GetNSString(IDS_IOS_CONTENT_SUGGESTIONS_RECENT_TABS); - case ContentSuggestionsMostVisitedActionHistory: - return l10n_util::GetNSString(IDS_IOS_CONTENT_SUGGESTIONS_HISTORY); - } -} - -// Returns the image to use for a cell with |action|. -- (UIImage*)imageForAction:(ContentSuggestionsMostVisitedAction)action { - switch (action) { - case ContentSuggestionsMostVisitedActionBookmark: - return [self imageGettingTintedNamed:@"ntp_bookmarks_icon"]; - case ContentSuggestionsMostVisitedActionReadingList: - return [self imageGettingTintedNamed:@"ntp_readinglist_icon"]; - case ContentSuggestionsMostVisitedActionRecentTabs: - return [self imageGettingTintedNamed:@"ntp_recent_icon"]; - case ContentSuggestionsMostVisitedActionHistory: - return [self imageGettingTintedNamed:@"ntp_history_icon"]; - } -} - -// Returns the image named |imageName| with a rendering mode "AlwaysTemplate". -- (UIImage*)imageGettingTintedNamed:(NSString*)imageName { - return [[UIImage imageNamed:imageName] - imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; -} - // Updates self.accessibilityLabel based on the current property values. - (void)updateAccessibilityLabel { // Resetting self.accessibilityLabel to nil will prompt self.title to be used // as the default label. This default value should be used if: // - the cell is not for Reading List, // - there are no unread articles in the reading list. - if (self.action != ContentSuggestionsMostVisitedActionReadingList || + if (self.collectionShortcutType != NTPCollectionShortcutTypeReadingList || self.count <= 0) { self.accessibilityLabel = nil; return; } - BOOL hasMultipleArticles = self.count > 1; - int messageID = - hasMultipleArticles - ? IDS_IOS_CONTENT_SUGGESTIONS_READING_LIST_ACCESSIBILITY_LABEL - : IDS_IOS_CONTENT_SUGGESTIONS_READING_LIST_ACCESSIBILITY_LABEL_ONE_UNREAD; - if (hasMultipleArticles) { - self.accessibilityLabel = l10n_util::GetNSStringF( - messageID, base::SysNSStringToUTF16([@(self.count) stringValue])); - } else { - self.accessibilityLabel = l10n_util::GetNSString(messageID); - } + self.accessibilityLabel = + AccessibilityLabelForReadingListCellWithCount(self.count); DCHECK(self.accessibilityLabel.length); }
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm index 972f4d9..085d42a 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
@@ -282,7 +282,7 @@ self.searchHintLabel.isAccessibilityElement = NO; self.accessibilityButton = [[UIButton alloc] init]; [self.accessibilityButton addTarget:self - action:@selector(focusFakebox) + action:@selector(fakeboxTapped) forControlEvents:UIControlEventTouchUpInside]; // Because the visual fakebox background is implemented within // ContentSuggestionsHeaderView, KVO the highlight events of @@ -330,7 +330,7 @@ l10n_util::GetNSString(IDS_ACCNAME_LOCATION); [self.headerView addToolbarView:fakeTapButton]; [fakeTapButton addTarget:self - action:@selector(focusFakebox) + action:@selector(fakeboxTapped) forControlEvents:UIControlEventTouchUpInside]; } @@ -365,6 +365,11 @@ [self.dispatcher preloadVoiceSearch]; } +- (void)fakeboxTapped { + base::RecordAction(base::UserMetricsAction("MobileFakeboxNTPTapped")); + [self focusFakebox]; +} + - (void)focusFakebox { [self shiftTilesUp]; }
diff --git a/ios/chrome/browser/ui/content_suggestions/mediator_util.mm b/ios/chrome/browser/ui/content_suggestions/mediator_util.mm index 5a9d915605..ea12bb5 100644 --- a/ios/chrome/browser/ui/content_suggestions/mediator_util.mm +++ b/ios/chrome/browser/ui/content_suggestions/mediator_util.mm
@@ -169,20 +169,20 @@ ContentSuggestionsMostVisitedActionItem* BookmarkActionItem() { return [[ContentSuggestionsMostVisitedActionItem alloc] - initWithAction:ContentSuggestionsMostVisitedActionBookmark]; + initWithCollectionShortcutType:NTPCollectionShortcutTypeBookmark]; } ContentSuggestionsMostVisitedActionItem* ReadingListActionItem() { return [[ContentSuggestionsMostVisitedActionItem alloc] - initWithAction:ContentSuggestionsMostVisitedActionReadingList]; + initWithCollectionShortcutType:NTPCollectionShortcutTypeReadingList]; } ContentSuggestionsMostVisitedActionItem* RecentTabsActionItem() { return [[ContentSuggestionsMostVisitedActionItem alloc] - initWithAction:ContentSuggestionsMostVisitedActionRecentTabs]; + initWithCollectionShortcutType:NTPCollectionShortcutTypeRecentTabs]; } ContentSuggestionsMostVisitedActionItem* HistoryActionItem() { return [[ContentSuggestionsMostVisitedActionItem alloc] - initWithAction:ContentSuggestionsMostVisitedActionHistory]; + initWithCollectionShortcutType:NTPCollectionShortcutTypeHistory]; }
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm index d90abf93..bf98bf72 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
@@ -237,20 +237,20 @@ ContentSuggestionsMostVisitedActionItem* mostVisitedItem = base::mac::ObjCCastStrict<ContentSuggestionsMostVisitedActionItem>( item); - switch (mostVisitedItem.action) { - case ContentSuggestionsMostVisitedActionBookmark: + switch (mostVisitedItem.collectionShortcutType) { + case NTPCollectionShortcutTypeBookmark: [self.dispatcher showBookmarksManager]; base::RecordAction(base::UserMetricsAction("MobileNTPShowBookmarks")); break; - case ContentSuggestionsMostVisitedActionReadingList: + case NTPCollectionShortcutTypeReadingList: [self.dispatcher showReadingList]; base::RecordAction(base::UserMetricsAction("MobileNTPShowReadingList")); break; - case ContentSuggestionsMostVisitedActionRecentTabs: + case NTPCollectionShortcutTypeRecentTabs: [self.dispatcher showRecentTabs]; base::RecordAction(base::UserMetricsAction("MobileNTPShowRecentTabs")); break; - case ContentSuggestionsMostVisitedActionHistory: + case NTPCollectionShortcutTypeHistory: [self.dispatcher showHistory]; base::RecordAction(base::UserMetricsAction("MobileNTPShowHistory")); break;
diff --git a/ios/chrome/browser/ui/find_bar/find_bar_controller_ios.mm b/ios/chrome/browser/ui/find_bar/find_bar_controller_ios.mm index 8fcfe5aa..4fc6044 100644 --- a/ios/chrome/browser/ui/find_bar/find_bar_controller_ios.mm +++ b/ios/chrome/browser/ui/find_bar/find_bar_controller_ios.mm
@@ -64,14 +64,12 @@ animated:(BOOL)animated; // Animate find bar over iPhone toolbar. - (void)showIPhoneFindBarViewInParentView:(UIView*)parentView + usingToolbarView:(UIView*)toolbarView selectText:(BOOL)selectText animated:(BOOL)animated; // Responds to touches that make editing changes on the text field, triggering // find-in-page searches for the field's current value. - (void)editingChanged; -// Return the expected find bar height. This will include the status bar height -// when running iOS7 on an iPhone. -- (CGFloat)findBarHeight; // Selects text in such way that selection menu does not appear and // a11y label is read. When -[UITextField selectAll:] is used, iOS // will read "Select All" instead of a11y label. @@ -89,10 +87,7 @@ @property(nonatomic, assign) BOOL isIncognito; @end -@implementation FindBarControllerIOS { - // This var is only useful for iPhone in iOS 10. - NSLayoutConstraint* _heightConstraint; -} +@implementation FindBarControllerIOS @synthesize view = _view; @synthesize findBarView = _findBarView; @@ -112,10 +107,13 @@ #pragma mark View Setup & Teardown -- (UIView*)constructFindBarView { +// Returns the findBar view with a |width|. The elements inside the view are +// already positioned correctly for this width. This is needed to start the +// animation with the elements already positioned. +- (UIView*)constructFindBarViewWithWidth:(CGFloat)width { UIView* findBarBackground = nil; - findBarBackground = [[UIView alloc] initWithFrame:CGRectZero]; + findBarBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, 1)]; findBarBackground.backgroundColor = self.isIncognito ? UIColorFromRGB(kIncognitoToolbarBackgroundColor) : UIColorFromRGB(kToolbarBackgroundColor); @@ -125,22 +123,20 @@ [findBarBackground addSubview:self.findBarView]; self.findBarView.translatesAutoresizingMaskIntoConstraints = NO; - CGFloat findBarHeight = kAdaptiveToolbarHeight; - - NSMutableArray* constraints = [[NSMutableArray alloc] init]; - [constraints addObjectsFromArray:@[ + [NSLayoutConstraint activateConstraints:@[ [self.findBarView.trailingAnchor constraintEqualToAnchor:findBarBackground.trailingAnchor], [self.findBarView.leadingAnchor constraintEqualToAnchor:findBarBackground.leadingAnchor], - [self.findBarView.heightAnchor constraintEqualToConstant:findBarHeight] + [self.findBarView.heightAnchor + constraintEqualToConstant:kAdaptiveToolbarHeight], + [self.findBarView.bottomAnchor + constraintEqualToAnchor:findBarBackground.bottomAnchor], ]]; - [constraints - addObject:[self.findBarView.bottomAnchor - constraintEqualToAnchor:findBarBackground.bottomAnchor]]; - - [NSLayoutConstraint activateConstraints:constraints]; + // Make sure that the findBarView is correctly laid out for the width. + [findBarBackground setNeedsLayout]; + [findBarBackground layoutIfNeeded]; self.findBarView.inputField.delegate = self; [self.findBarView.inputField addTarget:self @@ -239,15 +235,12 @@ // If already showing find bar, update the height constraint only for iOS 10 // because the safe area anchor is not available. if (self.view) { - if (@available(iOS 11, *)) { - } else if (ShouldShowCompactToolbar()) { - _heightConstraint.constant = [self findBarHeight]; - } return; } if (ShouldShowCompactToolbar()) { [self showIPhoneFindBarViewInParentView:parentView + usingToolbarView:toolbarView selectText:selectText animated:animated]; } else { @@ -269,17 +262,27 @@ self.delayTimer = nil; if (animate) { - CGRect oldFrame = self.view.frame; - self.view.layer.anchorPoint = CGPointMake(0.5, 0); - self.view.frame = oldFrame; + void (^animation)(); + if (ShouldShowCompactToolbar()) { + CGRect oldFrame = self.view.frame; + self.view.layer.anchorPoint = CGPointMake(0.5, 0); + self.view.frame = oldFrame; + animation = ^{ + self.view.transform = CGAffineTransformMakeScale(1, 0.05); + self.view.alpha = 0; + }; + } else { + CGFloat rtlModifier = base::i18n::IsRTL() ? -1 : 1; + animation = ^{ + self.view.transform = CGAffineTransformMakeTranslation( + rtlModifier * self.view.bounds.size.width, 0); + }; + } [UIView animateWithDuration:kAnimationDuration - animations:^{ - self.view.transform = CGAffineTransformMakeScale(1, 0.05); - self.view.alpha = 0; - } - completion:^(BOOL finished) { - [self teardownView]; - }]; + animations:animation + completion:^(BOOL finished) { + [self teardownView]; + }]; } else { [self teardownView]; } @@ -304,7 +307,10 @@ selectText:(BOOL)selectText animated:(BOOL)animated { DCHECK(IsIPadIdiom()); - self.view = [self constructFindBarView]; + CGFloat parentWidth = CGRectGetWidth(parentView.bounds); + CGFloat width = MIN(parentWidth - 2 * kRegularRegularHorizontalMargin, + kFindBarWidthRegularRegular); + self.view = [self constructFindBarViewWithWidth:width]; self.view.accessibilityIdentifier = kFindInPageContainerViewId; self.view.translatesAutoresizingMaskIntoConstraints = NO; @@ -316,9 +322,6 @@ shadow.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:shadow]; - CGFloat parentWidth = CGRectGetWidth(parentView.bounds); - CGFloat width = MIN(parentWidth - 2 * kRegularRegularHorizontalMargin, - kFindBarWidthRegularRegular); [NSLayoutConstraint activateConstraints:@[ // Anchors findbar below |toolbarView|. [self.view.topAnchor constraintEqualToAnchor:toolbarView.bottomAnchor], @@ -336,13 +339,23 @@ LayoutSides::kTrailing, {-kShadowMargin, -kShadowMargin, -kShadowMargin, -kShadowMargin}); - self.view.alpha = 0; - self.view.transform = CGAffineTransformMakeScale(1, 0.05); + // Layout the view so the shadow is correctly positioned when the animation + // starts. Otherwise, when the shadow constraints are activated, the view is + // moved. + [self.view layoutIfNeeded]; + + // Position the frame of the view before animating it, so the animation looks + // correct (sliding in from the trailing edge). + CGRect toolbarFrameInParentView = + [toolbarView convertRect:toolbarView.bounds toView:parentView]; + CGFloat originX = base::i18n::IsRTL() ? -width : parentWidth; + self.view.frame = CGRectMake(originX, CGRectGetMaxY(toolbarFrameInParentView), + width, kAdaptiveToolbarHeight); + CGFloat duration = animated ? kAnimationDuration : 0; [UIView animateWithDuration:duration animations:^() { - self.view.alpha = 1; - self.view.transform = CGAffineTransformIdentity; + [self.view layoutIfNeeded]; } completion:^(BOOL finished) { if (selectText) @@ -352,41 +365,27 @@ // Animate find bar over iPhone toolbar. - (void)showIPhoneFindBarViewInParentView:(UIView*)parentView + usingToolbarView:(UIView*)toolbarView selectText:(BOOL)selectText animated:(BOOL)animated { - self.view = [self constructFindBarView]; + self.view = + [self constructFindBarViewWithWidth:toolbarView.bounds.size.width]; self.view.translatesAutoresizingMaskIntoConstraints = NO; [parentView addSubview:self.view]; self.view.accessibilityIdentifier = kFindInPageContainerViewId; - NSLayoutConstraint* leadingConstraint = [self.view.leadingAnchor - constraintEqualToAnchor:parentView.leadingAnchor]; - NSLayoutConstraint* trailingConstraint = [self.view.trailingAnchor - constraintEqualToAnchor:parentView.trailingAnchor]; - // Under iOS 10 SafeArea anchor is not available, so findbar is anchored to - // the top of screen and the height of statusbar should be considered. - NSLayoutConstraint* topConstraint = [self.view.topAnchor - constraintEqualToAnchor:SafeAreaLayoutGuideForView(parentView).topAnchor]; - - CGFloat height; - if (@available(iOS 11, *)) { - height = kAdaptiveToolbarHeight; - } else { - // Portrait: height = findbar + statusbar. - // Landscape: height = findbar - // The height constraint should be updated when iOS 10 device rotates. - height = [self findBarHeight]; - } - _heightConstraint = [self.view.heightAnchor constraintEqualToConstant:height]; [NSLayoutConstraint activateConstraints:@[ - leadingConstraint, trailingConstraint, topConstraint, _heightConstraint + [self.view.leadingAnchor constraintEqualToAnchor:parentView.leadingAnchor], + [self.view.trailingAnchor + constraintEqualToAnchor:parentView.trailingAnchor], + [self.view.topAnchor constraintEqualToAnchor:parentView.topAnchor], + [self.view.bottomAnchor constraintEqualToAnchor:toolbarView.bottomAnchor], ]]; - [self.view setTransform:CGAffineTransformMakeTranslation(0, -height)]; CGFloat duration = animated ? kAnimationDuration : 0; [UIView animateWithDuration:duration animations:^() { - [self.view setTransform:CGAffineTransformIdentity]; + [self.view layoutIfNeeded]; } completion:^(BOOL finished) { if (selectText) @@ -415,12 +414,6 @@ repeats:NO]; } -- (CGFloat)findBarHeight { - if (IsRegularXRegularSizeClass()) - return kAdaptiveToolbarHeight; - return StatusBarHeight() + kAdaptiveToolbarHeight; -} - #pragma mark - UITextFieldDelegate - (BOOL)textFieldShouldBeginEditing:(UITextField*)textField {
diff --git a/ios/chrome/browser/ui/ntp_tile_views/BUILD.gn b/ios/chrome/browser/ui/ntp_tile_views/BUILD.gn index 363e696..c8fc88a 100644 --- a/ios/chrome/browser/ui/ntp_tile_views/BUILD.gn +++ b/ios/chrome/browser/ui/ntp_tile_views/BUILD.gn
@@ -30,4 +30,9 @@ "ntp_tile_constants.h", "ntp_tile_constants.mm", ] + + deps = [ + "//ios/chrome/app/strings:ios_strings_grit", + "//ui/base:base", + ] }
diff --git a/ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.h b/ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.h index fd4ba94..6057a61 100644 --- a/ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.h +++ b/ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.h
@@ -10,4 +10,22 @@ // Size of a Most Visited cell, for example on NTP. extern const CGSize kMostVisitedCellSize; +// Enum listing the collection shortcuts on NTP and similar surfaces. +typedef NS_ENUM(NSInteger, NTPCollectionShortcutType) { + NTPCollectionShortcutTypeBookmark, + NTPCollectionShortcutTypeReadingList, + NTPCollectionShortcutTypeRecentTabs, + NTPCollectionShortcutTypeHistory, +}; + +// Returns a localized title for a given collection shortcut type. +NSString* TitleForCollectionShortcutType(NTPCollectionShortcutType action); +// Returns an icon for a given collection shortcut type to be used in an NTP +// tile. +UIImage* ImageForCollectionShortcutType(NTPCollectionShortcutType action); +// Returns a localized string that can be used as an accessibility label for the +// reading list tile when it's displaying the |count| badge, or, if |count| = 0, +// for a reading list tile with no badge. +NSString* AccessibilityLabelForReadingListCellWithCount(int count); + #endif // IOS_CHROME_BROWSER_UI_NTP_TILE_VIEWS_NTP_TILE_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.mm b/ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.mm index 4e95e42..722aaf1 100644 --- a/ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.mm +++ b/ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.mm
@@ -4,8 +4,62 @@ #import "ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.h" +#include "base/strings/sys_string_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "ios/chrome/grit/ios_strings.h" +#include "ui/base/l10n/l10n_util.h" + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif const CGSize kMostVisitedCellSize = {/*width=*/73, /*height=*/100}; + +// Returns the title to use for a cell with |action|. +NSString* TitleForCollectionShortcutType(NTPCollectionShortcutType type) { + switch (type) { + case NTPCollectionShortcutTypeBookmark: + return l10n_util::GetNSString(IDS_IOS_CONTENT_SUGGESTIONS_BOOKMARKS); + case NTPCollectionShortcutTypeReadingList: + return l10n_util::GetNSString(IDS_IOS_CONTENT_SUGGESTIONS_READING_LIST); + case NTPCollectionShortcutTypeRecentTabs: + return l10n_util::GetNSString(IDS_IOS_CONTENT_SUGGESTIONS_RECENT_TABS); + case NTPCollectionShortcutTypeHistory: + return l10n_util::GetNSString(IDS_IOS_CONTENT_SUGGESTIONS_HISTORY); + } +} + +// Returns the image to use for a cell with |action|. +UIImage* ImageForCollectionShortcutType(NTPCollectionShortcutType type) { + NSString* imageName = nil; + switch (type) { + case NTPCollectionShortcutTypeBookmark: + imageName = @"ntp_bookmarks_icon"; + break; + case NTPCollectionShortcutTypeReadingList: + imageName = @"ntp_readinglist_icon"; + break; + case NTPCollectionShortcutTypeRecentTabs: + imageName = @"ntp_recent_icon"; + break; + case NTPCollectionShortcutTypeHistory: + imageName = @"ntp_history_icon"; + break; + } + return [[UIImage imageNamed:imageName] + imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; +} + +NSString* AccessibilityLabelForReadingListCellWithCount(int count) { + BOOL hasMultipleArticles = count > 1; + int messageID = + hasMultipleArticles + ? IDS_IOS_CONTENT_SUGGESTIONS_READING_LIST_ACCESSIBILITY_LABEL + : IDS_IOS_CONTENT_SUGGESTIONS_READING_LIST_ACCESSIBILITY_LABEL_ONE_UNREAD; + if (hasMultipleArticles) { + return l10n_util::GetNSStringF( + messageID, base::SysNSStringToUTF16([@(count) stringValue])); + } else { + return l10n_util::GetNSString(messageID); + } +}
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm index dc4f72d..9c251d38 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_coordinator.mm
@@ -5,6 +5,8 @@ #import "ios/chrome/browser/ui/omnibox/omnibox_coordinator.h" #include "base/logging.h" +#include "base/metrics/user_metrics.h" +#include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" #include "components/omnibox/browser/omnibox_edit_model.h" #include "components/strings/grit/components_strings.h" @@ -104,7 +106,10 @@ } - (void)focusOmnibox { - [self.textField becomeFirstResponder]; + if (![self.textField isFirstResponder]) { + base::RecordAction(base::UserMetricsAction("MobileOmniboxFocused")); + [self.textField becomeFirstResponder]; + } } - (void)endEditing {
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.h b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.h index b2dfb8d..803caa6e 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.h +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.h
@@ -11,6 +11,7 @@ @class CommandDispatcher; @protocol OmniboxPopupPositioner; +@protocol OmniboxFocuser; class OmniboxPopupViewIOS; namespace ios {
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm index 2ae7f58b..9850291 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
@@ -86,6 +86,9 @@ self.shortcutsCoordinator = [[ShortcutsCoordinator alloc] initWithBaseViewController:self.popupViewController browserState:self.browserState]; + self.shortcutsCoordinator.dispatcher = + (id<ApplicationCommands, BrowserCommands, UrlLoader, + OmniboxFocuser>)(self.dispatcher); [self.shortcutsCoordinator start]; self.popupViewController.shortcutsViewController = self.shortcutsCoordinator.viewController;
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/BUILD.gn b/ios/chrome/browser/ui/omnibox/popup/shortcuts/BUILD.gn index 9af2b974..ab6b8dc0 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/BUILD.gn
@@ -32,6 +32,7 @@ "shortcuts_mediator.mm", "shortcuts_most_visited_item.h", "shortcuts_most_visited_item.mm", + "shortcuts_view_controller_delegate.h", ] configs += [ "//build/config/compiler:enable_arc" ] @@ -39,8 +40,11 @@ "//components/ntp_tiles", "//components/reading_list/core", "//ios/chrome/browser/ntp_tiles", + "//ios/chrome/browser/ui", "//ios/chrome/browser/ui/coordinators:chrome_coordinators", "//ios/chrome/browser/ui/favicon", + "//ios/chrome/browser/ui/toolbar/public", + "//ios/web/public", ] }
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_coordinator.h b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_coordinator.h index bb7985b3..8bab048f 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_coordinator.h +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_coordinator.h
@@ -7,6 +7,11 @@ #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" +@protocol ApplicationCommands; +@protocol BrowserCommands; +@protocol UrlLoader; +@protocol OmniboxFocuser; + // The coordinator for the shortcuts. // Shortcuts are the tiles displayed in the omnibox in the zero state. @interface ShortcutsCoordinator : ChromeCoordinator @@ -14,6 +19,9 @@ // The view controller managed by this coordinator. @property(nonatomic, strong, readonly) UIViewController* viewController; +@property(nonatomic, weak) + id<ApplicationCommands, BrowserCommands, UrlLoader, OmniboxFocuser> + dispatcher; @end #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_SHORTCUTS_SHORTCUTS_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_coordinator.mm b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_coordinator.mm index 31a5df9..8b0a69e5 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_coordinator.mm +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_coordinator.mm
@@ -48,6 +48,8 @@ [[ShortcutsViewController alloc] init]; self.viewController = shortcutsViewController; self.mediator.consumer = shortcutsViewController; + self.mediator.dispatcher = self.dispatcher; + shortcutsViewController.commandHandler = self.mediator; } - (void)stop {
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.h b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.h index 57f078e..b40cb48 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.h +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.h
@@ -8,6 +8,7 @@ #import <UIKit/UIKit.h> #include <memory> +#import "ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller_delegate.h" namespace favicon { class LargeIconService; @@ -18,10 +19,14 @@ class LargeIconCache; class ReadingListModel; +@protocol ApplicationCommands; +@protocol BrowserCommands; +@protocol OmniboxFocuser; @protocol ShortcutsConsumer; +@protocol UrlLoader; // Coordinator for the Omnibox Popup Shortcuts. -@interface ShortcutsMediator : NSObject +@interface ShortcutsMediator : NSObject<ShortcutsViewControllerDelegate> - (instancetype) initWithLargeIconService:(favicon::LargeIconService*)largeIconService @@ -30,8 +35,12 @@ (std::unique_ptr<ntp_tiles::MostVisitedSites>)mostVisitedSites readingListModel:(ReadingListModel*)readingListModel; +// The consumer for the data fetched by this mediator. @property(nonatomic, weak) id<ShortcutsConsumer> consumer; - +// Dispatcher. +@property(nonatomic, weak) + id<ApplicationCommands, BrowserCommands, UrlLoader, OmniboxFocuser> + dispatcher; @end #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_SHORTCUTS_SHORTCUTS_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm index 9f8ed24..458cc85e 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_mediator.mm
@@ -10,6 +10,10 @@ #include "ios/chrome/browser/ntp_tiles/most_visited_sites_observer_bridge.h" #import "ios/chrome/browser/ui/favicon/favicon_attributes_provider.h" #import "ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_consumer.h" +#import "ios/chrome/browser/ui/toolbar/public/omnibox_focuser.h" +#import "ios/chrome/browser/ui/url_loader.h" +#import "ios/web/public/navigation_item.h" +#import "ios/web/public/navigation_manager.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -85,6 +89,15 @@ }]; } +#pragma mark - ShortcutsViewControllerDelegate + +- (void)openMostVisitedItem:(ShortcutsMostVisitedItem*)item { + web::NavigationManager::WebLoadParams params(item.URL); + params.transition_type = ui::PAGE_TRANSITION_AUTO_BOOKMARK; + [self.dispatcher loadURLWithParams:params]; + [self.dispatcher cancelOmniboxEdit]; +} + #pragma mark - MostVisitedSitesObserving - (void)onMostVisitedURLsAvailable:
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.h b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.h index b36b5706..f032495 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.h +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.h
@@ -9,9 +9,13 @@ #import "ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_consumer.h" +@protocol ShortcutsViewControllerDelegate; + // The view controller displaying the omnibox shortcuts in the zero state. @interface ShortcutsViewController : UIViewController<ShortcutsConsumer> +@property(nonatomic, weak) id<ShortcutsViewControllerDelegate> commandHandler; + @end #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_SHORTCUTS_SHORTCUTS_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.mm index eed0b58..518cd6e 100644 --- a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.mm +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller.mm
@@ -7,6 +7,7 @@ #include "base/logging.h" #import "ios/chrome/browser/ui/ntp_tile_views/ntp_most_visited_tile_view.h" #import "ios/chrome/browser/ui/ntp_tile_views/ntp_tile_constants.h" +#import "ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller_delegate.h" #import "ios/chrome/common/favicon/favicon_view.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" @@ -131,7 +132,9 @@ return; } NSUInteger i = [self.mostVisitedItems indexOfObject:item]; - DCHECK(i != NSNotFound); + if (i == NSNotFound) { + return; + } [self.collectionView reloadItemsAtIndexPaths:@[ [NSIndexPath indexPathWithIndex:i] ]]; } @@ -160,4 +163,13 @@ return cell; } +#pragma mark - UICollectionViewDelegate + +- (void)collectionView:(UICollectionView*)collectionView + didSelectItemAtIndexPath:(NSIndexPath*)indexPath { + ShortcutsMostVisitedItem* item = self.mostVisitedItems[indexPath.item]; + DCHECK(item); + [self.commandHandler openMostVisitedItem:item]; +} + @end
diff --git a/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller_delegate.h b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller_delegate.h new file mode 100644 index 0000000..c43ffee --- /dev/null +++ b/ios/chrome/browser/ui/omnibox/popup/shortcuts/shortcuts_view_controller_delegate.h
@@ -0,0 +1,19 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_SHORTCUTS_SHORTCUTS_VIEW_CONTROLLER_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_SHORTCUTS_SHORTCUTS_VIEW_CONTROLLER_DELEGATE_H_ + +@class ShortcutsMostVisitedItem; + +// Commands originating from ShortcutsViewController, for example ones called +// when the shortcuts are tapped. +@protocol ShortcutsViewControllerDelegate + +// Called when a most visited shortcut is selected by the user. +- (void)openMostVisitedItem:(ShortcutsMostVisitedItem*)item; + +@end + +#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_SHORTCUTS_SHORTCUTS_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/media/audio/audio_manager_base.cc b/media/audio/audio_manager_base.cc index 44f7667..e3cf270 100644 --- a/media/audio/audio_manager_base.cc +++ b/media/audio/audio_manager_base.cc
@@ -249,6 +249,7 @@ if (!params.IsValid() || (params.channels() > kMaxInputChannels) || device_id.empty()) { DLOG(ERROR) << "Audio parameters are invalid for device " << device_id; + VLOG(1) << params.AsHumanReadableString(); return nullptr; }
diff --git a/media/audio/win/audio_low_latency_input_win.cc b/media/audio/win/audio_low_latency_input_win.cc index 90b1215..82304fe 100644 --- a/media/audio/win/audio_low_latency_input_win.cc +++ b/media/audio/win/audio_low_latency_input_win.cc
@@ -43,13 +43,14 @@ kCount }; -bool IsSupportedFormatForConversion(const WAVEFORMATEX& format) { - if (format.nSamplesPerSec < limits::kMinSampleRate || - format.nSamplesPerSec > limits::kMaxSampleRate) { +bool IsSupportedFormatForConversion(WAVEFORMATEXTENSIBLE* format_ex) { + WAVEFORMATEX* format = &format_ex->Format; + if (format->nSamplesPerSec < limits::kMinSampleRate || + format->nSamplesPerSec > limits::kMaxSampleRate) { return false; } - switch (format.wBitsPerSample) { + switch (format->wBitsPerSample) { case 8: case 16: case 32: @@ -58,7 +59,7 @@ return false; } - if (GuessChannelLayout(format.nChannels) == CHANNEL_LAYOUT_UNSUPPORTED) { + if (GuessChannelLayout(format->nChannels) == CHANNEL_LAYOUT_UNSUPPORTED) { LOG(ERROR) << "Hardware configuration not supported for audio conversion"; return false; } @@ -85,27 +86,34 @@ const SampleFormat kSampleFormat = kSampleFormatS16; // Set up the desired output format specified by the client. - output_format_.wFormatTag = WAVE_FORMAT_PCM; - output_format_.nChannels = params.channels(); - output_format_.nSamplesPerSec = params.sample_rate(); - output_format_.wBitsPerSample = SampleFormatToBitsPerChannel(kSampleFormat); - output_format_.nBlockAlign = - (output_format_.wBitsPerSample / 8) * output_format_.nChannels; - output_format_.nAvgBytesPerSec = - output_format_.nSamplesPerSec * output_format_.nBlockAlign; - output_format_.cbSize = 0; + DVLOG(1) << params.AsHumanReadableString(); + WAVEFORMATEX* format = &output_format_.Format; + format->wFormatTag = WAVE_FORMAT_EXTENSIBLE; + format->nChannels = params.channels(); + format->nSamplesPerSec = params.sample_rate(); + format->wBitsPerSample = SampleFormatToBitsPerChannel(kSampleFormat); + format->nBlockAlign = (format->wBitsPerSample / 8) * format->nChannels; + format->nAvgBytesPerSec = format->nSamplesPerSec * format->nBlockAlign; + format->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + + // Add the parts which are unique to WAVE_FORMAT_EXTENSIBLE. + output_format_.Samples.wValidBitsPerSample = format->wBitsPerSample; + output_format_.dwChannelMask = + CoreAudioUtil::GetChannelConfig(device_id, eCapture); + output_format_.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; // Set the input (capture) format to the desired output format. In most cases, // it will be used unchanged. input_format_ = output_format_; + DVLOG(1) << CoreAudioUtil::WaveFormatExToString(&input_format_); // Size in bytes of each audio frame. - frame_size_bytes_ = input_format_.nBlockAlign; + frame_size_bytes_ = format->nBlockAlign; // Store size of audio packets which we expect to get from the audio // endpoint device in each capture event. packet_size_bytes_ = params.GetBytesPerBuffer(kSampleFormat); - packet_size_frames_ = packet_size_bytes_ / input_format_.nBlockAlign; + packet_size_frames_ = packet_size_bytes_ / format->nBlockAlign; DVLOG(1) << "Number of bytes per audio frame : " << frame_size_bytes_; DVLOG(1) << "Number of audio frames per packet: " << packet_size_frames_; @@ -127,7 +135,6 @@ bool WASAPIAudioInputStream::Open() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(OPEN_RESULT_OK, open_result_); // Verify that we are not already opened. if (opened_) { @@ -405,8 +412,8 @@ ++buffers_required; DCHECK(!fifo_); - fifo_.reset(new AudioBlockFifo(input_format_.nChannels, packet_size_frames_, - buffers_required)); + fifo_.reset(new AudioBlockFifo(input_format_.Format.nChannels, + packet_size_frames_, buffers_required)); DVLOG(1) << "AudioBlockFifo buffer count: " << buffers_required; @@ -451,7 +458,7 @@ void WASAPIAudioInputStream::PullCaptureDataAndPushToSink() { TRACE_EVENT1("audio", "WASAPIAudioInputStream::PullCaptureDataAndPushToSink", - "sample rate", input_format_.nSamplesPerSec); + "sample rate", input_format_.Format.nSamplesPerSec); UINT64 last_device_position = 0; @@ -527,7 +534,7 @@ // Adjust |capture_time| for the FIFO before pushing. capture_time -= AudioTimestampHelper::FramesToTime( - fifo_->GetAvailableFrames(), input_format_.nSamplesPerSec); + fifo_->GetAvailableFrames(), input_format_.Format.nSamplesPerSec); // TODO(grunell): Since we check |hr == AUDCLNT_S_BUFFER_EMPTY| above, // should we instead assert that |num_frames_to_read != 0|? @@ -536,7 +543,7 @@ fifo_->PushSilence(num_frames_to_read); } else { fifo_->Push(data_ptr, num_frames_to_read, - input_format_.wBitsPerSample / 8); + input_format_.Format.wBitsPerSample / 8); } } @@ -565,13 +572,13 @@ // Move the capture time forward for each vended block. capture_time += AudioTimestampHelper::FramesToTime( - convert_bus_->frames(), output_format_.nSamplesPerSec); + convert_bus_->frames(), output_format_.Format.nSamplesPerSec); } else { sink_->OnData(fifo_->Consume(), capture_time, volume); // Move the capture time forward for each vended block. capture_time += AudioTimestampHelper::FramesToTime( - packet_size_frames_, input_format_.nSamplesPerSec); + packet_size_frames_, input_format_.Format.nSamplesPerSec); } } } // while (true) @@ -654,37 +661,35 @@ #ifndef NDEBUG // The GetMixFormat() method retrieves the stream format that the // audio engine uses for its internal processing of shared-mode streams. - // The method always uses a WAVEFORMATEXTENSIBLE structure, instead - // of a stand-alone WAVEFORMATEX structure, to specify the format. - // An WAVEFORMATEXTENSIBLE structure can specify both the mapping of - // channels to speakers and the number of bits of precision in each sample. - base::win::ScopedCoMem<WAVEFORMATEXTENSIBLE> format_ex; - hr = - audio_client_->GetMixFormat(reinterpret_cast<WAVEFORMATEX**>(&format_ex)); + base::win::ScopedCoMem<WAVEFORMATEX> format; + hr = audio_client_->GetMixFormat(&format); + if (FAILED(hr)) + return hr; - // See http://msdn.microsoft.com/en-us/windows/hardware/gg463006#EFH - // for details on the WAVE file format. - WAVEFORMATEX format = format_ex->Format; DVLOG(2) << "WAVEFORMATEX:"; - DVLOG(2) << " wFormatTags : 0x" << std::hex << format.wFormatTag; - DVLOG(2) << " nChannels : " << format.nChannels; - DVLOG(2) << " nSamplesPerSec : " << format.nSamplesPerSec; - DVLOG(2) << " nAvgBytesPerSec: " << format.nAvgBytesPerSec; - DVLOG(2) << " nBlockAlign : " << format.nBlockAlign; - DVLOG(2) << " wBitsPerSample : " << format.wBitsPerSample; - DVLOG(2) << " cbSize : " << format.cbSize; + DVLOG(2) << " wFormatTags : 0x" << std::hex << format->wFormatTag; + DVLOG(2) << " nChannels : " << format->nChannels; + DVLOG(2) << " nSamplesPerSec : " << format->nSamplesPerSec; + DVLOG(2) << " nAvgBytesPerSec: " << format->nAvgBytesPerSec; + DVLOG(2) << " nBlockAlign : " << format->nBlockAlign; + DVLOG(2) << " wBitsPerSample : " << format->wBitsPerSample; + DVLOG(2) << " cbSize : " << format->cbSize; - DVLOG(2) << "WAVEFORMATEXTENSIBLE:"; - DVLOG(2) << " wValidBitsPerSample: " - << format_ex->Samples.wValidBitsPerSample; - DVLOG(2) << " dwChannelMask : 0x" << std::hex - << format_ex->dwChannelMask; - if (format_ex->SubFormat == KSDATAFORMAT_SUBTYPE_PCM) - DVLOG(2) << " SubFormat : KSDATAFORMAT_SUBTYPE_PCM"; - else if (format_ex->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) - DVLOG(2) << " SubFormat : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT"; - else if (format_ex->SubFormat == KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) - DVLOG(2) << " SubFormat : KSDATAFORMAT_SUBTYPE_WAVEFORMATEX"; + if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { + WAVEFORMATEXTENSIBLE* format_ex = + reinterpret_cast<WAVEFORMATEXTENSIBLE*>(format.get()); + DVLOG(2) << "WAVEFORMATEXTENSIBLE:"; + DVLOG(2) << " wValidBitsPerSample: " + << format_ex->Samples.wValidBitsPerSample; + DVLOG(2) << " dwChannelMask : 0x" << std::hex + << format_ex->dwChannelMask; + if (format_ex->SubFormat == KSDATAFORMAT_SUBTYPE_PCM) + DVLOG(2) << " SubFormat : KSDATAFORMAT_SUBTYPE_PCM"; + else if (format_ex->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) + DVLOG(2) << " SubFormat : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT"; + else if (format_ex->SubFormat == KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + DVLOG(2) << " SubFormat : KSDATAFORMAT_SUBTYPE_WAVEFORMATEX"; + } #endif return hr; } @@ -701,7 +706,8 @@ // the audio engine can mix only PCM streams. base::win::ScopedCoMem<WAVEFORMATEX> closest_match; HRESULT hresult = audio_client_->IsFormatSupported( - AUDCLNT_SHAREMODE_SHARED, &input_format_, &closest_match); + AUDCLNT_SHAREMODE_SHARED, + reinterpret_cast<const WAVEFORMATEX*>(&input_format_), &closest_match); DLOG_IF(ERROR, hresult == S_FALSE) << "Format is not supported but a closest match exists."; @@ -710,8 +716,9 @@ // can provide. If we succeed in initializing the audio client in this // format and are able to convert from this format, we will do that // conversion. - input_format_.nChannels = closest_match->nChannels; - input_format_.nSamplesPerSec = closest_match->nSamplesPerSec; + WAVEFORMATEX* input_format = &input_format_.Format; + input_format->nChannels = closest_match->nChannels; + input_format->nSamplesPerSec = closest_match->nSamplesPerSec; // If the closest match is fixed point PCM (WAVE_FORMAT_PCM or // KSDATAFORMAT_SUBTYPE_PCM), we use the closest match's bits per sample. @@ -729,20 +736,18 @@ return false; }; if (format_is_pcm(closest_match)) - input_format_.wBitsPerSample = closest_match->wBitsPerSample; + input_format->wBitsPerSample = closest_match->wBitsPerSample; - input_format_.nBlockAlign = - (input_format_.wBitsPerSample / 8) * input_format_.nChannels; - input_format_.nAvgBytesPerSec = - input_format_.nSamplesPerSec * input_format_.nBlockAlign; + input_format->nBlockAlign = + (input_format->wBitsPerSample / 8) * input_format->nChannels; + input_format->nAvgBytesPerSec = + input_format->nSamplesPerSec * input_format->nBlockAlign; - if (IsSupportedFormatForConversion(input_format_)) { - DVLOG(1) << "Will convert capture audio from: \nbits: " - << input_format_.wBitsPerSample - << "\nsample rate: " << input_format_.nSamplesPerSec - << "\nchannels: " << input_format_.nChannels - << "\nblock align: " << input_format_.nBlockAlign - << "\navg bytes per sec: " << input_format_.nAvgBytesPerSec; + if (IsSupportedFormatForConversion(&input_format_)) { + DVLOG(1) << "Will convert captured audio: \n" + << CoreAudioUtil::WaveFormatExToString(&input_format_) + << " ==> \n" + << CoreAudioUtil::WaveFormatExToString(&output_format_); SetupConverterAndStoreFormatInfo(); @@ -763,22 +768,24 @@ // Ideally, we want a 1:1 ratio between the buffers we get and the buffers // we give to OnData so that each buffer we receive from the OS can be // directly converted to a buffer that matches with what was asked for. - const double buffer_ratio = - output_format_.nSamplesPerSec / static_cast<double>(packet_size_frames_); - double new_frames_per_buffer = input_format_.nSamplesPerSec / buffer_ratio; + const double buffer_ratio = output_format_.Format.nSamplesPerSec / + static_cast<double>(packet_size_frames_); + double new_frames_per_buffer = + input_format_.Format.nSamplesPerSec / buffer_ratio; - const auto input_layout = GuessChannelLayout(input_format_.nChannels); + const auto input_layout = GuessChannelLayout(input_format_.Format.nChannels); DCHECK_NE(CHANNEL_LAYOUT_UNSUPPORTED, input_layout); - const auto output_layout = GuessChannelLayout(output_format_.nChannels); + const auto output_layout = + GuessChannelLayout(output_format_.Format.nChannels); DCHECK_NE(CHANNEL_LAYOUT_UNSUPPORTED, output_layout); const AudioParameters input(AudioParameters::AUDIO_PCM_LOW_LATENCY, - input_layout, input_format_.nSamplesPerSec, + input_layout, input_format_.Format.nSamplesPerSec, static_cast<int>(new_frames_per_buffer)); - const AudioParameters output(AudioParameters::AUDIO_PCM_LOW_LATENCY, - output_layout, output_format_.nSamplesPerSec, - packet_size_frames_); + const AudioParameters output( + AudioParameters::AUDIO_PCM_LOW_LATENCY, output_layout, + output_format_.Format.nSamplesPerSec, packet_size_frames_); converter_.reset(new AudioConverter(input, output, false)); converter_->AddInput(this); @@ -786,11 +793,11 @@ convert_bus_ = AudioBus::Create(output); // Update our packet size assumptions based on the new format. - const auto new_bytes_per_buffer = - static_cast<int>(new_frames_per_buffer) * input_format_.nBlockAlign; - packet_size_frames_ = new_bytes_per_buffer / input_format_.nBlockAlign; + const auto new_bytes_per_buffer = static_cast<int>(new_frames_per_buffer) * + input_format_.Format.nBlockAlign; + packet_size_frames_ = new_bytes_per_buffer / input_format_.Format.nBlockAlign; packet_size_bytes_ = new_bytes_per_buffer; - frame_size_bytes_ = input_format_.nBlockAlign; + frame_size_bytes_ = input_format_.Format.nBlockAlign; imperfect_buffer_size_conversion_ = std::modf(new_frames_per_buffer, &new_frames_per_buffer) != 0.0; @@ -801,8 +808,8 @@ HRESULT WASAPIAudioInputStream::InitializeAudioEngine() { DCHECK_EQ(OPEN_RESULT_OK, open_result_); DWORD flags; - // Use event-driven mode only fo regular input devices. For loopback the - // EVENTCALLBACK flag is specified when intializing + // Use event-driven mode only for regular input devices. For loopback the + // EVENTCALLBACK flag is specified when initializing // |audio_render_client_for_loopback_|. if (AudioDeviceDescription::IsLoopbackDevice(device_id_)) { flags = AUDCLNT_STREAMFLAGS_LOOPBACK | AUDCLNT_STREAMFLAGS_NOPERSIST; @@ -825,7 +832,7 @@ HRESULT hr = audio_client_->Initialize( AUDCLNT_SHAREMODE_SHARED, flags, buffer_duration, 0, // device period, n/a for shared mode. - &input_format_, + reinterpret_cast<const WAVEFORMATEX*>(&input_format_), device_id_ == AudioDeviceDescription::kCommunicationsDeviceId ? &kCommunicationsSessionId : nullptr); @@ -848,7 +855,7 @@ } const int endpoint_buffer_size_ms = static_cast<double>(endpoint_buffer_size_frames_ * 1000) / - input_format_.nSamplesPerSec + + input_format_.Format.nSamplesPerSec + 0.5; // Round to closest integer UMA_HISTOGRAM_CUSTOM_TIMES( "Media.Audio.Capture.Win.EndpointBufferSize", @@ -917,7 +924,7 @@ hr = audio_render_client_for_loopback_->Initialize( AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST, 0, 0, - &input_format_, NULL); + reinterpret_cast<const WAVEFORMATEX*>(&input_format_), NULL); if (FAILED(hr)) { open_result_ = OPEN_RESULT_LOOPBACK_INIT_FAILED; return hr; @@ -967,14 +974,17 @@ "output format = %#x/%d/%ld/%d/%d/%ld/%d", // clang-format off open_result_, hr, - input_format_.wFormatTag, input_format_.nChannels, - input_format_.nSamplesPerSec, input_format_.wBitsPerSample, - input_format_.nBlockAlign, input_format_.nAvgBytesPerSec, - input_format_.cbSize, - output_format_.wFormatTag, output_format_.nChannels, - output_format_.nSamplesPerSec, output_format_.wBitsPerSample, - output_format_.nBlockAlign, output_format_.nAvgBytesPerSec, - output_format_.cbSize)); + input_format_.Format.wFormatTag, input_format_.Format.nChannels, + input_format_.Format.nSamplesPerSec, + input_format_.Format.wBitsPerSample, + input_format_.Format.nBlockAlign, input_format_.Format.nAvgBytesPerSec, + input_format_.Format.cbSize, + output_format_.Format.wFormatTag, output_format_.Format.nChannels, + output_format_.Format.nSamplesPerSec, + output_format_.Format.wBitsPerSample, + output_format_.Format.nBlockAlign, + output_format_.Format.nAvgBytesPerSec, + output_format_.Format.cbSize)); // clang-format on } } @@ -1052,7 +1062,7 @@ total_concurrent_glitch_and_discontinuities_); double lost_frames_ms = - (total_lost_frames_ * 1000) / input_format_.nSamplesPerSec; + (total_lost_frames_ * 1000) / input_format_.Format.nSamplesPerSec; std::string log_message = base::StringPrintf( "WASAPIAIS: Total glitches=%d. Total frames lost=%llu (%.0lf ms). Total " "discontinuities=%d. Total concurrent glitch and discont=%d. Total low " @@ -1067,7 +1077,7 @@ UMA_HISTOGRAM_LONG_TIMES("Media.Audio.Capture.LostFramesInMs", base::TimeDelta::FromMilliseconds(lost_frames_ms)); int64_t largest_glitch_ms = - (largest_glitch_frames_ * 1000) / input_format_.nSamplesPerSec; + (largest_glitch_frames_ * 1000) / input_format_.Format.nSamplesPerSec; UMA_HISTOGRAM_CUSTOM_TIMES( "Media.Audio.Capture.LargestGlitchMs", base::TimeDelta::FromMilliseconds(largest_glitch_ms),
diff --git a/media/audio/win/audio_low_latency_input_win.h b/media/audio/win/audio_low_latency_input_win.h index ee8307d..788430f 100644 --- a/media/audio/win/audio_low_latency_input_win.h +++ b/media/audio/win/audio_low_latency_input_win.h
@@ -189,14 +189,14 @@ // Contains the desired output audio format which is set up at construction, // that is the audio format this class should output data to the sink in, that // is the format after the converter. - WAVEFORMATEX output_format_; + WAVEFORMATEXTENSIBLE output_format_; // Contains the audio format we get data from the audio engine in. Set to // |output_format_| at construction and might be changed to a close match if // the audio engine doesn't support the originally set format. Note that this // is also the format after the fifo, i.e. the input format to the converter // if any. - WAVEFORMATEX input_format_; + WAVEFORMATEXTENSIBLE input_format_; bool opened_ = false; bool started_ = false;
diff --git a/media/audio/win/audio_low_latency_input_win_unittest.cc b/media/audio/win/audio_low_latency_input_win_unittest.cc index 13cf3734..1f62165 100644 --- a/media/audio/win/audio_low_latency_input_win_unittest.cc +++ b/media/audio/win/audio_low_latency_input_win_unittest.cc
@@ -37,6 +37,7 @@ using ::testing::AnyNumber; using ::testing::AtLeast; using ::testing::Gt; +using ::testing::NiceMock; using ::testing::NotNull; namespace media { @@ -344,7 +345,7 @@ ScopedAudioInputStream ais( CreateDefaultAudioInputStream(audio_manager_.get())); EXPECT_TRUE(ais->Open()); - MockAudioInputCallback sink; + NiceMock<MockAudioInputCallback> sink; ais->Start(&sink); ais.Close(); } @@ -355,7 +356,7 @@ ScopedAudioInputStream ais( CreateDefaultAudioInputStream(audio_manager_.get())); EXPECT_TRUE(ais->Open()); - MockAudioInputCallback sink; + NiceMock<MockAudioInputCallback> sink; ais->Start(&sink); ais->Stop(); ais.Close();
diff --git a/media/audio/win/core_audio_util_win.cc b/media/audio/win/core_audio_util_win.cc index 1863939..7b1c81b 100644 --- a/media/audio/win/core_audio_util_win.cc +++ b/media/audio/win/core_audio_util_win.cc
@@ -132,6 +132,15 @@ case KSAUDIO_SPEAKER_7POINT1_SURROUND: DVLOG(2) << "KSAUDIO_SPEAKER_7POINT1_SURROUND=>CHANNEL_LAYOUT_7_1"; return CHANNEL_LAYOUT_7_1; + case KSAUDIO_SPEAKER_DIRECTOUT: + // When specifying the wave format for a direct-out stream, an application + // should set the dwChannelMask member of the WAVEFORMATEXTENSIBLE + // structure to the value KSAUDIO_SPEAKER_DIRECTOUT, which is zero. + // A channel mask of zero indicates that no speaker positions are defined. + // As always, the number of channels in the stream is specified in the + // Format.nChannels member. + DVLOG(2) << "KSAUDIO_SPEAKER_DIRECTOUT=>CHANNEL_LAYOUT_DISCRETE"; + return CHANNEL_LAYOUT_DISCRETE; default: DVLOG(2) << "Unsupported channel configuration: " << config; return CHANNEL_LAYOUT_UNSUPPORTED; @@ -141,6 +150,9 @@ // TODO(henrika): add mapping for all types in the ChannelLayout enumerator. ChannelConfig ChannelLayoutToChannelConfig(ChannelLayout layout) { switch (layout) { + case CHANNEL_LAYOUT_DISCRETE: + DVLOG(2) << "CHANNEL_LAYOUT_DISCRETE=>KSAUDIO_SPEAKER_DIRECTOUT"; + return KSAUDIO_SPEAKER_DIRECTOUT; case CHANNEL_LAYOUT_MONO: DVLOG(2) << "CHANNEL_LAYOUT_MONO=>KSAUDIO_SPEAKER_MONO"; return KSAUDIO_SPEAKER_MONO; @@ -171,19 +183,6 @@ } } -std::ostream& operator<<(std::ostream& os, const WAVEFORMATPCMEX& format) { - os << "wFormatTag: 0x" << std::hex << format.Format.wFormatTag - << ", nChannels: " << std::dec << format.Format.nChannels - << ", nSamplesPerSec: " << format.Format.nSamplesPerSec - << ", nAvgBytesPerSec: " << format.Format.nAvgBytesPerSec - << ", nBlockAlign: " << format.Format.nBlockAlign - << ", wBitsPerSample: " << format.Format.wBitsPerSample - << ", cbSize: " << format.Format.cbSize - << ", wValidBitsPerSample: " << format.Samples.wValidBitsPerSample - << ", dwChannelMask: 0x" << std::hex << format.dwChannelMask; - return os; -} - std::string GetDeviceID(IMMDevice* device) { ScopedCoMem<WCHAR> device_id_com; std::string device_id; @@ -257,7 +256,7 @@ // for more details. ChannelConfig channel_config = mix_format.dwChannelMask; - // Convert Microsoft's channel configuration to genric ChannelLayout. + // Convert Microsoft's channel configuration to generic ChannelLayout. ChannelLayout channel_layout = ChannelConfigToChannelLayout(channel_config); // Some devices don't appear to set a valid channel layout, so guess based @@ -268,6 +267,7 @@ << mix_format.Format.nChannels; channel_layout = GuessChannelLayout(mix_format.Format.nChannels); } + DVLOG(1) << "channel layout: " << ChannelLayoutToString(channel_layout); return channel_layout; } @@ -368,6 +368,7 @@ } HRESULT GetPreferredAudioParametersInternal(IAudioClient* client, + bool is_output_device, AudioParameters* params, const UMALogCallback& uma_log_cb) { WAVEFORMATPCMEX mix_format; @@ -428,6 +429,19 @@ frames_per_buffer, AudioParameters::HardwareCapabilities(min_frames_per_buffer, max_frames_per_buffer)); + // Set the number of channels explicitly to two for input devices if + // the channel layout is discrete to ensure that the parameters are valid + // and that clients does not have to support multi-channel input cases. + // Any required down-mixing from N (N > 2) to 2 must be performed by the + // input stream implementation instead. + // See https://crbug/868026 for examples where this approach is needed. + if (!is_output_device && + audio_params.channel_layout() == CHANNEL_LAYOUT_DISCRETE) { + DLOG(WARNING) + << "Forcing number of channels to 2 for CHANNEL_LAYOUT_DISCRETE"; + audio_params.set_channels_for_discrete(2); + } + DCHECK(audio_params.IsValid()); *params = audio_params; DVLOG(1) << params->AsHumanReadableString(); @@ -441,6 +455,30 @@ return g_is_supported; } +std::string CoreAudioUtil::WaveFormatExToString( + const WAVEFORMATEXTENSIBLE* format) { + DCHECK_EQ(format->Format.wFormatTag, WAVE_FORMAT_EXTENSIBLE); + DCHECK_GE(format->Format.cbSize, 22); + std::string wave_format = base::StringPrintf( + "wFormatTag: WAVE_FORMAT_EXTENSIBLE, nChannels: %d, nSamplesPerSec: %lu" + ", nAvgBytesPerSec: %lu, nBlockAlign: %d, wBitsPerSample: %d, cbSize: %d" + ", wValidBitsPerSample: %d, dwChannelMask: 0x%lX", + format->Format.nChannels, format->Format.nSamplesPerSec, + format->Format.nAvgBytesPerSec, format->Format.nBlockAlign, + format->Format.wBitsPerSample, format->Format.cbSize, + format->Samples.wValidBitsPerSample, format->dwChannelMask); + if (format->SubFormat == KSDATAFORMAT_SUBTYPE_PCM) { + base::StringAppendF(&wave_format, "%s", + ", SubFormat: KSDATAFORMAT_SUBTYPE_PCM"); + } else if (format->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) { + base::StringAppendF(&wave_format, "%s", + ", SubFormat: KSDATAFORMAT_SUBTYPE_IEEE_FLOAT"); + } else { + base::StringAppendF(&wave_format, "%s", ", SubFormat: NOT_SUPPORTED"); + } + return wave_format; +} + base::TimeDelta CoreAudioUtil::ReferenceTimeToTimeDelta(REFERENCE_TIME time) { // Each unit of reference time is 100 nanoseconds <=> 0.1 microsecond. return base::TimeDelta::FromMicroseconds(0.1 * time + 0.5); @@ -671,6 +709,7 @@ HRESULT CoreAudioUtil::GetSharedModeMixFormat( IAudioClient* client, WAVEFORMATPCMEX* format) { + VLOG(1) << __FUNCTION__; ScopedCoMem<WAVEFORMATPCMEX> format_pcmex; HRESULT hr = client->GetMixFormat( reinterpret_cast<WAVEFORMATEX**>(&format_pcmex)); @@ -682,7 +721,7 @@ << "Format tag: 0x" << std::hex << format_pcmex->Format.wFormatTag; memcpy(format, format_pcmex, bytes); - DVLOG(2) << *format; + DVLOG(2) << CoreAudioUtil::WaveFormatExToString(format); return hr; } @@ -701,7 +740,7 @@ // This log can be triggered both for shared and exclusive modes. DLOG_IF(ERROR, hr == AUDCLNT_E_UNSUPPORTED_FORMAT) << "Unsupported format."; if (hr == S_FALSE) { - DVLOG(2) << *closest_match; + DVLOG(2) << CoreAudioUtil::WaveFormatExToString(closest_match); } return (hr == S_OK); @@ -740,7 +779,7 @@ format.Format.nAvgBytesPerSec = format.Format.nSamplesPerSec * format.Format.nBlockAlign; } - DVLOG(2) << format; + DVLOG(2) << CoreAudioUtil::WaveFormatExToString(&format); // Some devices can initialize a shared-mode stream with a format that is // not identical to the mix format obtained from the GetMixFormat() method. @@ -775,6 +814,7 @@ HRESULT CoreAudioUtil::GetPreferredAudioParameters(const std::string& device_id, bool is_output_device, AudioParameters* params) { + DVLOG(1) << __FUNCTION__; UMALogCallback uma_log_cb( is_output_device ? base::BindRepeating(&LogUMAPreferredOutputParams) : base::BindRepeating(&LogUMAEmptyCb)); @@ -787,17 +827,21 @@ if (!client.Get()) return E_FAIL; - HRESULT hr = - GetPreferredAudioParametersInternal(client.Get(), params, uma_log_cb); - if (FAILED(hr) || is_output_device || !params->IsValid()) + HRESULT hr = GetPreferredAudioParametersInternal( + client.Get(), is_output_device, params, uma_log_cb); + if (FAILED(hr) || is_output_device || !params->IsValid()) { return hr; + } // The following functionality is only for input devices. DCHECK(!is_output_device); // TODO(dalecurtis): Old code rewrote != 1 channels to stereo, do we still // need to do the same thing? - if (params->channels() != 1) { + if (params->channels() != 1 && + params->channel_layout() != CHANNEL_LAYOUT_DISCRETE) { + DLOG(WARNING) + << "Replacing existing audio parameter with predefined version"; params->Reset(params->format(), CHANNEL_LAYOUT_STEREO, params->sample_rate(), params->frames_per_buffer()); }
diff --git a/media/audio/win/core_audio_util_win.h b/media/audio/win/core_audio_util_win.h index cdbbdfa5..e554b0c2a46 100644 --- a/media/audio/win/core_audio_util_win.h +++ b/media/audio/win/core_audio_util_win.h
@@ -40,6 +40,8 @@ // it is safe to call from other threads. static bool IsSupported(); + static std::string WaveFormatExToString(const WAVEFORMATEXTENSIBLE* format); + // Converts between reference time to base::TimeDelta. // One reference-time unit is 100 nanoseconds. // Example: double s = RefererenceTimeToTimeDelta(t).InMillisecondsF();
diff --git a/media/mojo/clients/mojo_video_encode_accelerator_unittest.cc b/media/mojo/clients/mojo_video_encode_accelerator_unittest.cc index c7b4b55..8c3dbd7 100644 --- a/media/mojo/clients/mojo_video_encode_accelerator_unittest.cc +++ b/media/mojo/clients/mojo_video_encode_accelerator_unittest.cc
@@ -165,7 +165,7 @@ const VideoEncodeAccelerator::Config config( PIXEL_FORMAT_I420, kInputVisibleSize, kOutputProfile, kInitialBitrate, - base::nullopt, base::nullopt, kContentType); + base::nullopt, base::nullopt, base::nullopt, kContentType); EXPECT_TRUE(mojo_vea()->Initialize(config, mock_vea_client)); base::RunLoop().RunUntilIdle(); }
diff --git a/media/mojo/interfaces/video_encode_accelerator_mojom_traits.cc b/media/mojo/interfaces/video_encode_accelerator_mojom_traits.cc index edfcf3f..7ca9e59 100644 --- a/media/mojo/interfaces/video_encode_accelerator_mojom_traits.cc +++ b/media/mojo/interfaces/video_encode_accelerator_mojom_traits.cc
@@ -178,7 +178,7 @@ *output = media::VideoEncodeAccelerator::Config( input_format, input_visible_size, output_profile, input.initial_bitrate(), - initial_framerate, h264_output_level, content_type); + initial_framerate, h264_output_level, base::nullopt, content_type); return true; }
diff --git a/media/video/video_encode_accelerator.cc b/media/video/video_encode_accelerator.cc index bf05cb72..339e57c4 100644 --- a/media/video/video_encode_accelerator.cc +++ b/media/video/video_encode_accelerator.cc
@@ -42,6 +42,7 @@ uint32_t initial_bitrate, base::Optional<uint32_t> initial_framerate, base::Optional<uint8_t> h264_output_level, + base::Optional<StorageType> storage_type, ContentType content_type) : input_format(input_format), input_visible_size(input_visible_size), @@ -51,6 +52,7 @@ VideoEncodeAccelerator::kDefaultFramerate)), h264_output_level(h264_output_level.value_or( VideoEncodeAccelerator::kDefaultH264Level)), + storage_type(storage_type), content_type(content_type) {} VideoEncodeAccelerator::Config::~Config() = default;
diff --git a/media/video/video_encode_accelerator.h b/media/video/video_encode_accelerator.h index 15b3f2e..4371d94 100644 --- a/media/video/video_encode_accelerator.h +++ b/media/video/video_encode_accelerator.h
@@ -105,6 +105,10 @@ // Indicates if video content should be treated as a "normal" camera feed // or as generated (e.g. screen capture). enum class ContentType { kCamera, kDisplay }; + // Indicates the storage type of a video frame provided on Encode(). + // kShmem if a video frame is mapped in user space. + // kDmabuf if a video frame is referred by dmabuf. + enum class StorageType { kShmem, kDmabuf }; Config(); Config(const Config& config); @@ -115,6 +119,7 @@ uint32_t initial_bitrate, base::Optional<uint32_t> initial_framerate = base::nullopt, base::Optional<uint8_t> h264_output_level = base::nullopt, + base::Optional<StorageType> storage_type = base::nullopt, ContentType content_type = ContentType::kCamera); ~Config(); @@ -147,6 +152,13 @@ // use |kDefaultH264Level| if not given. base::Optional<uint8_t> h264_output_level; + // The storage type of video frame provided on Encode(). + // If no value is set, VEA doesn't check the storage type of video frame on + // Encode(). + // This is kShmem iff a video frame is mapped in user space. + // This is kDmabuf iff a video frame has dmabuf. + base::Optional<StorageType> storage_type; + // Indicates captured video (from a camera) or generated (screen grabber). // Screen content has a number of special properties such as lack of noise, // burstiness of motion and requirements for readability of small text in @@ -216,6 +228,9 @@ virtual bool Initialize(const Config& config, Client* client) = 0; // Encodes the given frame. + // The storage type of |frame| must be the |storage_type| if it is specified + // in Initialize(). + // TODO(crbug.com/895230): Raise an error if the storage types are mismatch. // Parameters: // |frame| is the VideoFrame that is to be encoded. // |force_keyframe| forces the encoding of a keyframe for this frame.
diff --git a/media/webrtc/audio_processor.cc b/media/webrtc/audio_processor.cc index 9156f09..93c0408 100644 --- a/media/webrtc/audio_processor.cc +++ b/media/webrtc/audio_processor.cc
@@ -30,6 +30,10 @@ case CHANNEL_LAYOUT_MONO: return webrtc::AudioProcessing::kMono; case CHANNEL_LAYOUT_STEREO: + case CHANNEL_LAYOUT_DISCRETE: + // TODO(https://crbug.com/868026): currently mapping all discrete channel + // layouts to two channels assuming that any required channel remix takes + // place in the native audio layer. return webrtc::AudioProcessing::kStereo; case CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC: return webrtc::AudioProcessing::kStereoAndKeyboard;
diff --git a/mojo/public/tools/bindings/generators/js_templates/externs/interface_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/externs/interface_definition.tmpl index 672b5d5..cbdac79 100644 --- a/mojo/public/tools/bindings/generators/js_templates/externs/interface_definition.tmpl +++ b/mojo/public/tools/bindings/generators/js_templates/externs/interface_definition.tmpl
@@ -1,3 +1,9 @@ +{# Note that goog.provide is understood by the Closure Compiler even if the + Closure base library is unavailable. See https://crbug.com/898692 #} +goog.provide('{{module.namespace}}.{{interface.name}}'); +goog.provide('{{module.namespace}}.{{interface.name}}Impl'); +goog.provide('{{module.namespace}}.{{interface.name}}Ptr'); + {% macro generateInterfaceClass() -%} class { {%- for method in interface.methods %}
diff --git a/mojo/public/tools/bindings/generators/js_templates/externs/module.externs.tmpl b/mojo/public/tools/bindings/generators/js_templates/externs/module.externs.tmpl index fd71106..938252f7 100644 --- a/mojo/public/tools/bindings/generators/js_templates/externs/module.externs.tmpl +++ b/mojo/public/tools/bindings/generators/js_templates/externs/module.externs.tmpl
@@ -2,19 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -{% for declaration in module.namespace|namespace_declarations -%} -/** @const */ -{%- if loop.first %} -var {{declaration}} = {}; -{% else %} -{{declaration}} = {}; -{% endif -%} -{%- endfor -%} - +{# Note that goog.provide is understood by the Closure Compiler even if the + Closure base library is unavailable. See https://crbug.com/898692 #} {#--- Constant definitions #} {%- for constant in module.constants %} /** @type { {{constant.kind|closure_type_with_nullability }} } */ -{{module.namespace}}.{{constant.name}}; +goog.provide('{{module.namespace}}.{{constant.name}}'); {%- endfor %} {#--- Enum definitions #}
diff --git a/mojo/public/tools/bindings/generators/js_templates/externs/struct_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/externs/struct_definition.tmpl index 4aecb67..9aeeb65 100644 --- a/mojo/public/tools/bindings/generators/js_templates/externs/struct_definition.tmpl +++ b/mojo/public/tools/bindings/generators/js_templates/externs/struct_definition.tmpl
@@ -1,3 +1,7 @@ +{# Note that goog.provide is understood by the Closure Compiler even if the + Closure base library is unavailable. See https://crbug.com/898692 #} +goog.provide('{{module.namespace}}.{{struct.name}}'); + {{module.namespace}}.{{struct.name}} = class { constructor() { {%- for packed_field in struct.packed.packed_fields %}
diff --git a/mojo/public/tools/bindings/generators/js_templates/lite/interface_externs.tmpl b/mojo/public/tools/bindings/generators/js_templates/lite/interface_externs.tmpl index 18a98aa..ea16286 100644 --- a/mojo/public/tools/bindings/generators/js_templates/lite/interface_externs.tmpl +++ b/mojo/public/tools/bindings/generators/js_templates/lite/interface_externs.tmpl
@@ -1,3 +1,11 @@ +{# Note that goog.provide is understood by the Closure Compiler even if the + Closure base library is unavailable. See https://crbug.com/898692 #} +goog.provide('{{module.namespace}}.{{interface.name}}'); +goog.provide('{{module.namespace}}.{{interface.name}}Interface'); +goog.provide('{{module.namespace}}.{{interface.name}}Request'); +goog.provide('{{module.namespace}}.{{interface.name}}Proxy'); +goog.provide('{{module.namespace}}.{{interface.name}}CallbackRouter'); + {% macro generateInterfaceClassBody() -%} {%- for method in interface.methods %} /**
diff --git a/mojo/public/tools/bindings/generators/js_templates/lite/module.externs.tmpl b/mojo/public/tools/bindings/generators/js_templates/lite/module.externs.tmpl index 7e652dc..cc85bf4 100644 --- a/mojo/public/tools/bindings/generators/js_templates/lite/module.externs.tmpl +++ b/mojo/public/tools/bindings/generators/js_templates/lite/module.externs.tmpl
@@ -2,19 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -{% for declaration in module.namespace|namespace_declarations -%} -/** @const */ -{%- if loop.first %} -var {{declaration}} = {}; -{% else %} -{{declaration}} = {}; -{% endif -%} -{%- endfor -%} - +{# Note that goog.provide is understood by the Closure Compiler even if the + Closure base library is unavailable. See https://crbug.com/898692 #} {#--- Constant definitions #} {%- for constant in module.constants %} /** @type { {{constant.kind|closure_type_with_nullability }} } */ -{{module.namespace}}.{{constant.name}}; +goog.provide('{{module.namespace}}.{{constant.name}}'); {%- endfor %} {#--- Enum definitions #}
diff --git a/mojo/public/tools/bindings/generators/js_templates/lite/struct_externs.tmpl b/mojo/public/tools/bindings/generators/js_templates/lite/struct_externs.tmpl index 391573fe..c64ce8d8 100644 --- a/mojo/public/tools/bindings/generators/js_templates/lite/struct_externs.tmpl +++ b/mojo/public/tools/bindings/generators/js_templates/lite/struct_externs.tmpl
@@ -1,3 +1,7 @@ +{# Note that goog.provide is understood by the Closure Compiler even if the + Closure base library is unavailable. See https://crbug.com/898692 #} +goog.provide('{{module.namespace}}.{{struct.name}}'); + {{module.namespace}}.{{struct.name}} = class { constructor() { {%- for packed_field in struct.packed.packed_fields %}
diff --git a/ppapi/proxy/audio_encoder_resource.cc b/ppapi/proxy/audio_encoder_resource.cc index 51dcab4..f903663 100644 --- a/ppapi/proxy/audio_encoder_resource.cc +++ b/ppapi/proxy/audio_encoder_resource.cc
@@ -18,18 +18,6 @@ namespace ppapi { namespace proxy { -namespace { - -void RunCallback(scoped_refptr<TrackedCallback>* callback, int32_t error) { - if (TrackedCallback::IsPending(*callback)) { - scoped_refptr<TrackedCallback> temp; - callback->swap(temp); - temp->Run(error); - } -} - -} // namespace - AudioEncoderResource::AudioEncoderResource(Connection connection, PP_Instance instance) : PluginResource(connection, instance), @@ -205,12 +193,12 @@ ArrayWriter writer(output); if (params.result() != PP_OK || !writer.is_valid() || !writer.StoreVector(profiles)) { - RunCallback(&get_supported_profiles_callback_, PP_ERROR_FAILED); + SafeRunCallback(&get_supported_profiles_callback_, PP_ERROR_FAILED); return; } - RunCallback(&get_supported_profiles_callback_, - base::checked_cast<int32_t>(profiles.size())); + SafeRunCallback(&get_supported_profiles_callback_, + base::checked_cast<int32_t>(profiles.size())); } void AudioEncoderResource::OnPluginMsgInitializeReply( @@ -224,7 +212,7 @@ int32_t error = params.result(); if (error) { - RunCallback(&initialize_callback_, error); + SafeRunCallback(&initialize_callback_, error); return; } @@ -234,7 +222,7 @@ !audio_buffer_manager_.SetBuffers( audio_buffer_count, audio_buffer_size, std::make_unique<base::SharedMemory>(buffer_handle, false), true)) { - RunCallback(&initialize_callback_, PP_ERROR_NOMEMORY); + SafeRunCallback(&initialize_callback_, PP_ERROR_NOMEMORY); return; } @@ -243,7 +231,7 @@ !bitstream_buffer_manager_.SetBuffers( bitstream_buffer_count, bitstream_buffer_size, std::make_unique<base::SharedMemory>(buffer_handle, false), false)) { - RunCallback(&initialize_callback_, PP_ERROR_NOMEMORY); + SafeRunCallback(&initialize_callback_, PP_ERROR_NOMEMORY); return; } @@ -255,7 +243,7 @@ number_of_samples_ = number_of_samples; initialized_ = true; - RunCallback(&initialize_callback_, PP_OK); + SafeRunCallback(&initialize_callback_, PP_OK); } void AudioEncoderResource::OnPluginMsgEncodeReply( @@ -273,7 +261,7 @@ scoped_refptr<TrackedCallback> callback = it->second; encode_callbacks_.erase(it); - RunCallback(&callback, encoder_last_error_); + SafeRunCallback(&callback, encoder_last_error_); audio_buffer_manager_.EnqueueBuffer(buffer_id); // If the plugin is waiting for an audio buffer, we can give the one @@ -301,15 +289,15 @@ DCHECK(error); encoder_last_error_ = error; - RunCallback(&get_supported_profiles_callback_, error); - RunCallback(&initialize_callback_, error); - RunCallback(&get_buffer_callback_, error); + SafeRunCallback(&get_supported_profiles_callback_, error); + SafeRunCallback(&initialize_callback_, error); + SafeRunCallback(&get_buffer_callback_, error); get_buffer_data_ = nullptr; - RunCallback(&get_bitstream_buffer_callback_, error); + SafeRunCallback(&get_bitstream_buffer_callback_, error); get_bitstream_buffer_data_ = nullptr; for (EncodeMap::iterator it = encode_callbacks_.begin(); it != encode_callbacks_.end(); ++it) - RunCallback(&it->second, error); + SafeRunCallback(&it->second, error); encode_callbacks_.clear(); } @@ -329,7 +317,7 @@ // Take a reference for the plugin. *get_buffer_data_ = resource->GetReference(); get_buffer_data_ = nullptr; - RunCallback(&get_buffer_callback_, PP_OK); + SafeRunCallback(&get_buffer_callback_, PP_OK); } void AudioEncoderResource::TryWriteBitstreamBuffer() { @@ -345,7 +333,7 @@ get_bitstream_buffer_data_->buffer = buffer->bitstream.data; get_bitstream_buffer_data_->size = buffer->bitstream.data_size; get_bitstream_buffer_data_ = nullptr; - RunCallback(&get_bitstream_buffer_callback_, PP_OK); + SafeRunCallback(&get_bitstream_buffer_callback_, PP_OK); } void AudioEncoderResource::ReleaseBuffers() {
diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc index a5fdfca..3eb4b87a 100644 --- a/ppapi/proxy/host_dispatcher.cc +++ b/ppapi/proxy/host_dispatcher.cc
@@ -21,8 +21,8 @@ namespace { -typedef std::map<PP_Instance, HostDispatcher*> InstanceToDispatcherMap; -InstanceToDispatcherMap* g_instance_to_dispatcher = NULL; +typedef std::map<PP_Instance, HostDispatcher*> InstanceToHostDispatcherMap; +InstanceToHostDispatcherMap* g_instance_to_host_dispatcher = NULL; typedef std::map<PP_Module, HostDispatcher*> ModuleToDispatcherMap; ModuleToDispatcherMap* g_module_to_dispatcher = NULL; @@ -101,11 +101,11 @@ // static HostDispatcher* HostDispatcher::GetForInstance(PP_Instance instance) { - if (!g_instance_to_dispatcher) + if (!g_instance_to_host_dispatcher) return NULL; - InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( - instance); - if (found == g_instance_to_dispatcher->end()) + InstanceToHostDispatcherMap::iterator found = + g_instance_to_host_dispatcher->find(instance); + if (found == g_instance_to_host_dispatcher->end()) return NULL; return found->second; } @@ -113,19 +113,19 @@ // static void HostDispatcher::SetForInstance(PP_Instance instance, HostDispatcher* dispatcher) { - if (!g_instance_to_dispatcher) - g_instance_to_dispatcher = new InstanceToDispatcherMap; - (*g_instance_to_dispatcher)[instance] = dispatcher; + if (!g_instance_to_host_dispatcher) + g_instance_to_host_dispatcher = new InstanceToHostDispatcherMap; + (*g_instance_to_host_dispatcher)[instance] = dispatcher; } // static void HostDispatcher::RemoveForInstance(PP_Instance instance) { - if (!g_instance_to_dispatcher) + if (!g_instance_to_host_dispatcher) return; - InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( - instance); - if (found != g_instance_to_dispatcher->end()) - g_instance_to_dispatcher->erase(found); + InstanceToHostDispatcherMap::iterator found = + g_instance_to_host_dispatcher->find(instance); + if (found != g_instance_to_host_dispatcher->end()) + g_instance_to_host_dispatcher->erase(found); } bool HostDispatcher::IsPlugin() const {
diff --git a/ppapi/proxy/nacl_message_scanner.cc b/ppapi/proxy/nacl_message_scanner.cc index 4fae6974..0e478c22 100644 --- a/ppapi/proxy/nacl_message_scanner.cc +++ b/ppapi/proxy/nacl_message_scanner.cc
@@ -213,10 +213,7 @@ template <class MessageType> class MessageScannerImpl { public: - explicit MessageScannerImpl(const IPC::Message* msg) - // The cast below is invalid. See https://crbug.com/520760. - : msg_(static_cast<const MessageType*>(msg)) { - } + explicit MessageScannerImpl(const IPC::Message* msg) : msg_(msg) {} bool ScanMessage(ScanningResults* results) { typename MessageType::Param params; if (!MessageType::Read(msg_, ¶ms)) @@ -254,7 +251,7 @@ } private: - const MessageType* msg_; + const IPC::Message* msg_; }; } // namespace
diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc index 6bc240d..67c9c3b 100644 --- a/ppapi/proxy/plugin_dispatcher.cc +++ b/ppapi/proxy/plugin_dispatcher.cc
@@ -41,8 +41,8 @@ namespace { -typedef std::map<PP_Instance, PluginDispatcher*> InstanceToDispatcherMap; -InstanceToDispatcherMap* g_instance_to_dispatcher = NULL; +typedef std::map<PP_Instance, PluginDispatcher*> InstanceToPluginDispatcherMap; +InstanceToPluginDispatcherMap* g_instance_to_plugin_dispatcher = NULL; typedef std::set<PluginDispatcher*> DispatcherSet; DispatcherSet* g_live_dispatchers = NULL; @@ -152,11 +152,11 @@ // static PluginDispatcher* PluginDispatcher::GetForInstance(PP_Instance instance) { - if (!g_instance_to_dispatcher) + if (!g_instance_to_plugin_dispatcher) return NULL; - InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( - instance); - if (found == g_instance_to_dispatcher->end()) + InstanceToPluginDispatcherMap::iterator found = + g_instance_to_plugin_dispatcher->find(instance); + if (found == g_instance_to_plugin_dispatcher->end()) return NULL; return found->second; } @@ -178,13 +178,13 @@ PP_LogLevel level, const std::string& source, const std::string& value) { - if (!g_live_dispatchers || !g_instance_to_dispatcher) + if (!g_live_dispatchers || !g_instance_to_plugin_dispatcher) return; if (instance) { - InstanceToDispatcherMap::iterator found = - g_instance_to_dispatcher->find(instance); - if (found != g_instance_to_dispatcher->end()) { + InstanceToPluginDispatcherMap::iterator found = + g_instance_to_plugin_dispatcher->find(instance); + if (found != g_instance_to_plugin_dispatcher->end()) { // Send just to this specific dispatcher. found->second->Send(new PpapiHostMsg_LogWithSource( instance, static_cast<int>(level), source, value)); @@ -283,21 +283,21 @@ } void PluginDispatcher::DidCreateInstance(PP_Instance instance) { - if (!g_instance_to_dispatcher) - g_instance_to_dispatcher = new InstanceToDispatcherMap; - (*g_instance_to_dispatcher)[instance] = this; + if (!g_instance_to_plugin_dispatcher) + g_instance_to_plugin_dispatcher = new InstanceToPluginDispatcherMap; + (*g_instance_to_plugin_dispatcher)[instance] = this; instance_map_[instance] = std::make_unique<InstanceData>(); } void PluginDispatcher::DidDestroyInstance(PP_Instance instance) { instance_map_.erase(instance); - if (g_instance_to_dispatcher) { - InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( - instance); - if (found != g_instance_to_dispatcher->end()) { + if (g_instance_to_plugin_dispatcher) { + InstanceToPluginDispatcherMap::iterator found = + g_instance_to_plugin_dispatcher->find(instance); + if (found != g_instance_to_plugin_dispatcher->end()) { DCHECK(found->second == this); - g_instance_to_dispatcher->erase(found); + g_instance_to_plugin_dispatcher->erase(found); } else { NOTREACHED(); } @@ -322,13 +322,13 @@ } void PluginDispatcher::ForceFreeAllInstances() { - if (!g_instance_to_dispatcher) + if (!g_instance_to_plugin_dispatcher) return; // Iterating will remove each item from the map, so we need to make a copy // to avoid things changing out from under is. - InstanceToDispatcherMap temp_map = *g_instance_to_dispatcher; - for (InstanceToDispatcherMap::iterator i = temp_map.begin(); + InstanceToPluginDispatcherMap temp_map = *g_instance_to_plugin_dispatcher; + for (InstanceToPluginDispatcherMap::iterator i = temp_map.begin(); i != temp_map.end(); ++i) { if (i->second == this) { // Synthesize an "instance destroyed" message, this will notify the
diff --git a/ppapi/proxy/plugin_resource.cc b/ppapi/proxy/plugin_resource.cc index 177012dd..7128318 100644 --- a/ppapi/proxy/plugin_resource.cc +++ b/ppapi/proxy/plugin_resource.cc
@@ -13,6 +13,14 @@ namespace ppapi { namespace proxy { +void SafeRunCallback(scoped_refptr<TrackedCallback>* callback, int32_t error) { + if (TrackedCallback::IsPending(*callback)) { + scoped_refptr<TrackedCallback> temp; + callback->swap(temp); + temp->Run(error); + } +} + PluginResource::PluginResource(Connection connection, PP_Instance instance) : Resource(OBJECT_IS_PROXY, instance), connection_(connection),
diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h index 8f32277..54aa2b5 100644 --- a/ppapi/proxy/plugin_resource.h +++ b/ppapi/proxy/plugin_resource.h
@@ -26,6 +26,10 @@ namespace ppapi { namespace proxy { +// A "safe" way to run callbacks, doing nothing if they are not +// pending (active). +void SafeRunCallback(scoped_refptr<TrackedCallback>* callback, int32_t error); + class PPAPI_PROXY_EXPORT PluginResource : public Resource { public: enum Destination {
diff --git a/ppapi/proxy/video_decoder_resource.cc b/ppapi/proxy/video_decoder_resource.cc index bcd60561..94548e14 100644 --- a/ppapi/proxy/video_decoder_resource.cc +++ b/ppapi/proxy/video_decoder_resource.cc
@@ -523,11 +523,7 @@ void VideoDecoderResource::RunCallbackWithError( scoped_refptr<TrackedCallback>* callback) { - if (TrackedCallback::IsPending(*callback)) { - scoped_refptr<TrackedCallback> temp; - callback->swap(temp); - temp->Run(decoder_last_error_); - } + SafeRunCallback(callback, decoder_last_error_); } void VideoDecoderResource::DeleteGLTexture(uint32_t id) {
diff --git a/ppapi/proxy/video_encoder_resource.cc b/ppapi/proxy/video_encoder_resource.cc index 1abb315..eef9ea938 100644 --- a/ppapi/proxy/video_encoder_resource.cc +++ b/ppapi/proxy/video_encoder_resource.cc
@@ -26,15 +26,6 @@ namespace { -void RunCallback(scoped_refptr<TrackedCallback>* callback, int32_t error) { - if (!TrackedCallback::IsPending(*callback)) - return; - - scoped_refptr<TrackedCallback> temp; - callback->swap(temp); - temp->Run(error); -} - std::vector<PP_VideoProfileDescription_0_1> PP_VideoProfileDescriptionTo_0_1( std::vector<PP_VideoProfileDescription> profiles) { std::vector<PP_VideoProfileDescription_0_1> profiles_0_1; @@ -299,7 +290,7 @@ ArrayWriter writer(output); if (!writer.is_valid()) { - RunCallback(&get_supported_profiles_callback_, PP_ERROR_BADARGUMENT); + SafeRunCallback(&get_supported_profiles_callback_, PP_ERROR_BADARGUMENT); return; } @@ -311,12 +302,12 @@ write_result = writer.StoreVector(profiles); if (!write_result) { - RunCallback(&get_supported_profiles_callback_, PP_ERROR_FAILED); + SafeRunCallback(&get_supported_profiles_callback_, PP_ERROR_FAILED); return; } - RunCallback(&get_supported_profiles_callback_, - base::checked_cast<int32_t>(profiles.size())); + SafeRunCallback(&get_supported_profiles_callback_, + base::checked_cast<int32_t>(profiles.size())); } void VideoEncoderResource::OnPluginMsgInitializeReply( @@ -332,7 +323,7 @@ input_frame_count_ = input_frame_count; input_coded_size_ = input_coded_size; - RunCallback(&initialize_callback_, encoder_last_error_); + SafeRunCallback(&initialize_callback_, encoder_last_error_); } void VideoEncoderResource::OnPluginMsgGetVideoFramesReply( @@ -377,7 +368,7 @@ scoped_refptr<TrackedCallback> callback = it->second; encode_callbacks_.erase(it); - RunCallback(&callback, encoder_last_error_); + SafeRunCallback(&callback, encoder_last_error_); buffer_manager_.EnqueueBuffer(frame_id); // If the plugin is waiting for a video frame, we can give the one @@ -431,16 +422,16 @@ void VideoEncoderResource::NotifyError(int32_t error) { encoder_last_error_ = error; - RunCallback(&get_supported_profiles_callback_, error); - RunCallback(&initialize_callback_, error); - RunCallback(&get_video_frame_callback_, error); + SafeRunCallback(&get_supported_profiles_callback_, error); + SafeRunCallback(&initialize_callback_, error); + SafeRunCallback(&get_video_frame_callback_, error); get_video_frame_data_ = nullptr; - RunCallback(&get_bitstream_buffer_callback_, error); + SafeRunCallback(&get_bitstream_buffer_callback_, error); get_bitstream_buffer_data_ = nullptr; for (EncodeMap::iterator it = encode_callbacks_.begin(); it != encode_callbacks_.end(); ++it) { scoped_refptr<TrackedCallback> callback = it->second; - RunCallback(&callback, error); + SafeRunCallback(&callback, error); } encode_callbacks_.clear(); } @@ -459,7 +450,7 @@ *get_video_frame_data_ = resource->GetReference(); get_video_frame_data_ = nullptr; - RunCallback(&get_video_frame_callback_, PP_OK); + SafeRunCallback(&get_video_frame_callback_, PP_OK); } void VideoEncoderResource::WriteBitstreamBuffer(const BitstreamBuffer& buffer) { @@ -469,7 +460,7 @@ get_bitstream_buffer_data_->buffer = shm_buffers_[buffer.id]->shm->memory(); get_bitstream_buffer_data_->key_frame = PP_FromBool(buffer.key_frame); get_bitstream_buffer_data_ = nullptr; - RunCallback(&get_bitstream_buffer_callback_, PP_OK); + SafeRunCallback(&get_bitstream_buffer_callback_, PP_OK); } void VideoEncoderResource::ReleaseFrames() {
diff --git a/remoting/host/installer/build-installer-archive.py b/remoting/host/installer/build-installer-archive.py index 4585d0a..90828eb1 100755 --- a/remoting/host/installer/build-installer-archive.py +++ b/remoting/host/installer/build-installer-archive.py
@@ -21,6 +21,10 @@ import sys import zipfile +sys.path.append(os.path.join( + os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, + "build", "android", "gyp")) +from util import build_utils def cleanDir(dir): """Deletes and recreates the dir to make sure it is clean. @@ -54,23 +58,6 @@ return defs -def createZip(zip_path, directory): - """Creates a zipfile at zip_path for the given directory. - - Args: - zip_path: Path to zip file to create. - directory: Directory with contents to archive. - """ - zipfile_base = os.path.splitext(os.path.basename(zip_path))[0] - zip = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) - for (root, dirs, files) in os.walk(directory): - for f in files: - full_path = os.path.join(root, f) - rel_path = os.path.relpath(full_path, directory) - zip.write(full_path, os.path.join(zipfile_base, rel_path)) - zip.close() - - def remapSrcFile(dst_root, src_roots, src_file): """Calculates destination file path and creates directory. @@ -206,7 +193,10 @@ else: shutil.copy2(bs, dst_file) - createZip(zip_path, temp_dir) + build_utils.ZipDir( + zip_path, temp_dir, + compress_fn=lambda _: zipfile.ZIP_DEFLATED, + zip_prefix_path=os.path.splitext(os.path.basename(zip_path))[0]) def error(msg):
diff --git a/remoting/host/installer/mac/BUILD.gn b/remoting/host/installer/mac/BUILD.gn index 67d9574d..5791753 100644 --- a/remoting/host/installer/mac/BUILD.gn +++ b/remoting/host/installer/mac/BUILD.gn
@@ -36,6 +36,10 @@ script = "//remoting/host/installer/build-installer-archive.py" + sources = [ + "//build/android/gyp/util/build_utils.py", + ] + args = [ rebase_path("$target_gen_dir/remoting_installation", root_build_dir), rebase_path(zip_path, root_build_dir),
diff --git a/remoting/host/installer/win/BUILD.gn b/remoting/host/installer/win/BUILD.gn index 645b971..62d2293 100644 --- a/remoting/host/installer/win/BUILD.gn +++ b/remoting/host/installer/win/BUILD.gn
@@ -8,6 +8,10 @@ action("remoting_me2me_host_archive") { script = "//remoting/host/installer/build-installer-archive.py" + sources = [ + "//build/android/gyp/util/build_utils.py", + ] + deps = [ "//remoting/host:remoting_native_messaging_manifests", "//remoting/host:remoting_start_host",
diff --git a/remoting/webapp/build-webapp.py b/remoting/webapp/build-webapp.py index 2f02e8d3..626d7aa 100755 --- a/remoting/webapp/build-webapp.py +++ b/remoting/webapp/build-webapp.py
@@ -25,6 +25,11 @@ import time import zipfile +sys.path.append(os.path.join( + os.path.dirname(__file__), os.pardir, os.pardir, + "build", "android", "gyp")) +from util import build_utils + # Update the module path, assuming that this script is in src/remoting/webapp, # and that the google_api_keys module is in src/google_apis. Note that # sys.path[0] refers to the directory containing this script. @@ -46,18 +51,6 @@ os.remove(oldFilepath) -def createZip(zip_path, directory): - """Creates a zipfile at zip_path for the given directory.""" - zipfile_base = os.path.splitext(os.path.basename(zip_path))[0] - zip = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) - for (root, dirs, files) in os.walk(directory): - for f in files: - full_path = os.path.join(root, f) - rel_path = os.path.relpath(full_path, directory) - zip.write(full_path, os.path.join(zipfile_base, rel_path)) - zip.close() - - def replaceString(destination, placeholder, value): findAndReplace(os.path.join(destination, 'plugin_settings.js'), "'" + placeholder + "'", "'" + value + "'") @@ -344,7 +337,10 @@ context) # Make the zipfile. - createZip(zip_path, destination) + build_utils.ZipDir( + zip_path, destination, + compress_fn=lambda _: zipfile.ZIP_DEFLATED, + zip_prefix_path=os.path.splitext(os.path.basename(zip_path))[0]) return 0
diff --git a/remoting/webapp/build_template.gni b/remoting/webapp/build_template.gni index 05790597..d5ed945 100644 --- a/remoting/webapp/build_template.gni +++ b/remoting/webapp/build_template.gni
@@ -214,6 +214,10 @@ action(target_name) { script = "//remoting/webapp/build-webapp.py" + sources = [ + "//build/android/gyp/util/build_utils.py", + ] + output_dir = invoker.output_dir zip_path = invoker.zip_path extra_files = invoker.extra_files
diff --git a/services/BUILD.gn b/services/BUILD.gn index 07666f1..4e4c493 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn
@@ -174,6 +174,7 @@ "//base:base_java_test_support", "//mojo/public/java:base_java", "//mojo/public/java:bindings_java", + "//mojo/public/mojom/base:base_java", "//services/shape_detection:shape_detection_java", "//services/shape_detection/public/mojom:mojom_java", "//skia/public/interfaces:interfaces_java",
diff --git a/services/service_manager/public/java/BUILD.gn b/services/service_manager/public/java/BUILD.gn index c989f3a1..a9a269c 100644 --- a/services/service_manager/public/java/BUILD.gn +++ b/services/service_manager/public/java/BUILD.gn
@@ -15,6 +15,7 @@ "//base:base_java", "//mojo/public/java:bindings_java", "//mojo/public/java:system_java", + "//services/service_manager/public/mojom:constants_java", "//services/service_manager/public/mojom:mojom_java", ] }
diff --git a/services/tracing/perfetto/json_trace_exporter.cc b/services/tracing/perfetto/json_trace_exporter.cc index df3f0103..d58f65e6 100644 --- a/services/tracing/perfetto/json_trace_exporter.cc +++ b/services/tracing/perfetto/json_trace_exporter.cc
@@ -209,7 +209,7 @@ // Start tracing. perfetto::TraceConfig trace_config; - trace_config.add_buffers()->set_size_kb(4096 * 100); + trace_config.add_buffers()->set_size_kb(1024 * 32); auto* trace_event_config = trace_config.add_data_sources()->mutable_config(); trace_event_config->set_name(mojom::kTraceEventDataSourceName);
diff --git a/services/tracing/perfetto/perfetto_integration_unittest.cc b/services/tracing/perfetto/perfetto_integration_unittest.cc index 94c6ce2..237a1a5 100644 --- a/services/tracing/perfetto/perfetto_integration_unittest.cc +++ b/services/tracing/perfetto/perfetto_integration_unittest.cc
@@ -188,7 +188,7 @@ void StartTracing() { perfetto::TraceConfig trace_config; - trace_config.add_buffers()->set_size_kb(4096 * 100); + trace_config.add_buffers()->set_size_kb(1024 * 32); auto* ds_config = trace_config.add_data_sources()->mutable_config(); ds_config->set_name(data_source_name_); ds_config->set_target_buffer(0);
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index b14e5dc5..08c43f7f 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -134,9 +134,9 @@ { "args": [ "-v", + "--browser=android-chrome", "--upload-results", "--output-format=histograms", - "--browser=android-chromium", "--test-shard-map-filename=android_nexus5x_fyi_4_shard_map.json" ], "isolate_name": "performance_test_suite", @@ -179,7 +179,7 @@ { "args": [ "-v", - "--browser=android-chromium", + "--browser=android-chrome", "--upload-results", "--run-ref-build", "--test-shard-map-filename=android_pixel2_shard_map.json"
diff --git a/testing/buildbot/filters/chromeos.single_process_mash.content_browsertests.filter b/testing/buildbot/filters/chromeos.single_process_mash.content_browsertests.filter index a7d20df..c5f9a16d 100644 --- a/testing/buildbot/filters/chromeos.single_process_mash.content_browsertests.filter +++ b/testing/buildbot/filters/chromeos.single_process_mash.content_browsertests.filter
@@ -22,9 +22,5 @@ -SitePerProcessHitTestBrowserTest.SubframeGestureEventRouting* -# https://crbug.com/888156 --NavigationControllerBrowserTest.UtilizationOfSpareRenderProcessHost - - # Flaky. https://crbug.com/889878 -SyntheticKeyEventTest.KeyboardEventAck
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index cd48e1b..a86210b 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -511,31 +511,13 @@ "AudioService": [ { "platforms": [ - "linux" - ], - "experiments": [ - { - "name": "AudioProcess_LaunchOnStartup_Sandboxed_v7", - "params": { - "teardown_timeout_s": "0" - }, - "enable_features": [ - "AudioServiceAudioStreams", - "AudioServiceLaunchOnStartup", - "AudioServiceOutOfProcess", - "AudioServiceSandbox" - ] - } - ] - }, - { - "platforms": [ + "linux", "mac", "windows" ], "experiments": [ { - "name": "AudioProcess_LaunchOnStartup_Sandboxed_APM_v8", + "name": "AudioProcess_Sandboxed_APM_v9", "params": { "teardown_timeout_s": "0" },
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index 9138cd08..bd180b15 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -97,6 +97,7 @@ crbug.com/778875 virtual/threaded/animations/animationworklet/ [ Skip ] crbug.com/841567 virtual/threaded/fast/scrolling [ Skip ] +crbug.com/841567 virtual/fractional_scrolling_threaded/fast/scrolling [ Skip ] # Fail on SPv1, but succeed on SPv2 crbug.com/472330 fast/borders/border-image-outset-split-inline-vertical-lr.html [ Pass ] @@ -1267,6 +1268,15 @@ Bug(none) paint/invalidation/reflection/scroll-fixed-reflected-layer.html [ Failure ] Bug(none) svg/transforms/text-with-mask-with-svg-transform.svg [ Failure ] +Bug(none) fast/scrolling/fractional-scroll-offset-document.html [ Crash ] +Bug(none) virtual/fractional_scrolling/fast/scrolling/editor-command-scroll-page-scale.html [ Crash ] +Bug(none) virtual/fractional_scrolling/fast/scrolling/fractional-scroll-offset-document.html [ Crash ] +Bug(none) virtual/fractional_scrolling/fast/scrolling/keyboard-scroll-page-scale.html [ Crash ] +Bug(none) virtual/fractional_scrolling/fast/scrolling/overflow-clip-with-page-scale.html [ Crash ] +Bug(none) virtual/fractional_scrolling/fast/scrolling/same-page-navigate.html [ Crash ] +Bug(none) virtual/fractional_scrolling/fast/scrolling/scroll-without-document-element-renderer.html [ Crash ] +Bug(none) virtual/fractional_scrolling/fast/scrolling/scroll-without-document-element.html [ Crash ] + crbug.com/833083 paint/invalidation/compositing/composited-layers-move-in-subpixels.html [ Failure ] Bug(none) compositing/squashing/frame-clip-squashed-scrolled.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index fd768170..8d6acb42 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -180,6 +180,13 @@ crbug.com/857490 virtual/paint-touchaction-rects/fast/events/touch/gesture/pad-gesture-fling.html [ Skip ] crbug.com/857490 virtual/paint-touchaction-rects/fast/events/touch/gesture/touch-gesture-fling-with-page-scale.html [ Skip ] +# Tests not yet passing with Blink FractionalScrollOffsets enabled. +crbug.com/414283 virtual/fractional_scrolling/fast/scrolling/fractional-scroll-offset-fixed-position-non-composited.html [ Failure ] +crbug.com/414283 virtual/fractional_scrolling/fast/scrolling/fractional-scroll-offset-iframe-fixed-position.html [ Failure ] +crbug.com/414283 virtual/fractional_scrolling_threaded/fast/scrolling/fractional-scroll-offset-document.html [ Failure Timeout ] +crbug.com/414283 virtual/fractional_scrolling_threaded/fast/scrolling/fractional-scroll-offset-fixed-position-non-composited.html [ Failure ] +crbug.com/414283 virtual/fractional_scrolling_threaded/fast/scrolling/fractional-scroll-offset-iframe-fixed-position.html [ Failure ] + # Display locking, currently only available via a virtual test. crbug.com/882663 display-lock [ Skip ] crbug.com/882663 virtual/display-lock/display-lock/context-suspend-empty.html [ Failure ] @@ -4014,8 +4021,6 @@ crbug.com/655458 external/wpt/workers/constructors/SharedWorker/interface-objects.html [ Failure ] crbug.com/655458 external/wpt/workers/constructors/SharedWorker/unresolvable-url.html [ Failure ] -crbug.com/655458 external/wpt/workers/constructors/SharedWorker/same-origin.html [ Failure Timeout ] -crbug.com/655458 external/wpt/workers/constructors/Worker/same-origin.html [ Failure Timeout ] crbug.com/685303 external/wpt/workers/interfaces/WorkerGlobalScope/onerror/propagate-to-window-onerror.html [ Failure Timeout ] crbug.com/685303 external/wpt/workers/constructors/Worker/AbstractWorker.onerror.html [ Failure Timeout ] crbug.com/655458 external/wpt/workers/interfaces/WorkerUtils/importScripts/006.html [ Failure Timeout ] @@ -4080,9 +4085,6 @@ crbug.com/825798 external/wpt/html/semantics/embedded-content/media-elements/track/track-element/track-webvtt-non-snap-to-lines.html [ Failure ] - -crbug.com/651778 external/wpt/workers/Worker_cross_origin_security_err.htm [ Timeout ] - # This test requires a special browser flag and seems not suitable for a wpt test, see bug. crbug.com/691944 external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ] crbug.com/691944 virtual/service-worker-servicification/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ] @@ -5415,7 +5417,7 @@ # Sheriff 2018-10-03 crbug.com/891530 [ Linux ] virtual/android/rootscroller/remove-rootscroller-crash.html [ Pass Timeout ] -crbug.com/891510 [ Win7 ] fast/dom/inline-event-attributes-release.html [ Failure Pass ] +crbug.com/891510 [ Linux Win7 ] fast/dom/inline-event-attributes-release.html [ Failure Pass ] crbug.com/892772 [ Mac ] editing/caret/caret-painting-low-dpi.html [ Failure Pass ] # Flakiness in DTMF @@ -5460,7 +5462,6 @@ # Sheriff 2018-10-24 crbug.com/898394 [ Linux ] virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top.html [ Failure ] crbug.com/898378 [ Mac10.13 ] virtual/scroll_customization/fast/scroll-behavior/smooth-scroll/keyboard-scroll.html [ Timeout ] -crbug.com/898485 [ Mac ] paint/invalidation/table/cached-69296.html [ Failure Pass ] # Sheriff 2018-10-24 crbug.com/889185 [ Win10 ] http/tests/images/feature-policy-image-compression.html [ Failure ] @@ -5481,3 +5482,6 @@ crbug.com/889185 [ Win10 ] virtual/gpu-rasterization/images/feature-policy-max-downscaling-image-responsive-image.html [ Failure ] crbug.com/889185 [ Win10 ] virtual/gpu-rasterization/images/feature-policy-max-downscaling-image-styles.html [ Failure ] crbug.com/889185 [ Win10 ] virtual/gpu-rasterization/images/feature-policy-max-downscaling-image.html [ Failure ] + +# Sheriff 2018-10-25 +crbug.com/874576 http/tests/images/feature-policy-image-compression-cached-image.html [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 2030539..a8e2b0b18 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -618,6 +618,16 @@ "args": ["--enable-blink-features=FractionalMouseEvent"] }, { + "prefix": "fractional_scrolling_threaded", + "base": "fast/scrolling", + "args": ["--enable-blink-features=FractionalScrollOffsets", "--enable-threaded-compositing"] + }, + { + "prefix": "fractional_scrolling", + "base": "fast/scrolling", + "args": ["--enable-blink-features=FractionalScrollOffsets"] + }, + { "prefix": "speech-with-unified-autoplay", "base": "external/wpt/speech-api", "args": ["--autoplay-policy=document-user-activation-required"]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/domparsing/DOMParser-parseFromString-xml-parsererror.html b/third_party/WebKit/LayoutTests/external/wpt/domparsing/DOMParser-parseFromString-xml-parsererror.html new file mode 100644 index 0000000..9ecd0edd --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/domparsing/DOMParser-parseFromString-xml-parsererror.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<title>DOMParser: <parsererror> element added on error</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const xhtml_prologue = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"' + + ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n' + + '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' + + '<body>\n', + xhtml_epilogue = '</body>\n</html>\n'; + +[ + '<span x:test="testing">1</span>', // undeclared 'x' namespace prefix + '< span>2</span>', // bad start tag + '<span :test="testing">3</span>', // empty namespace prefix + '<span><em>4</span></em>', // staggered tags + '<span>5', // missing end </span> tag + '6</span>', // missing start <span> tag + '<span>7< /span>', // bad end tag + '<span>8</ span>', // bad end tag + '<span novalue>9</span>', // missing attribute value + '<span ="noattr">10</span>', // missing attribute name + '<span ::="test">11</span>', // bad namespace prefix + '<span xmlns:="urn:x-test:test">12</span>', // missing namespace prefix + '<span xmlns:xmlns="">13</span>', // invalid namespace prefix + '<span data-test=testing>14</span>', // unquoted attribute value + '15<span', // bad start tag + '<8:test xmlns:8="urn:x-test:test">16</8:test>', // invalid namespace prefix + '<span xmlns:p1 xmlns:p2="urn:x-test:test"/>17', // missing namespace URI +].forEach(fragment => { + test(() => { + var document_string = xhtml_prologue + fragment + xhtml_epilogue; + var doc = (new DOMParser).parseFromString(document_string, "application/xhtml+xml"); + var parsererrors = doc.getElementsByTagName("parsererror"); + assert_equals(parsererrors.length, 1, 'expecting one parsererror'); + }, document.title + ', ' + fragment); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt index 0f2d8d8..d73ca783 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt
@@ -4,10 +4,12 @@ PASS getDisplayMedia() with video false PASS getDisplayMedia() with audio false FAIL getDisplayMedia() with audio true promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'getDisplayMedia' on 'Navigator': Audio capture is not supported" -PASS getDisplayMedia() call with advanced constraint -PASS getDisplayMedia() call with min constraint -PASS getDisplayMedia() call with exact constraint -PASS getDisplayMedia() call with max constraint +PASS getDisplayMedia() with advanced constraint +PASS getDisplayMedia() with min constraint +PASS getDisplayMedia() with exact constraint +PASS getDisplayMedia() with max constraint +PASS getDisplayMedia() with constraints applied +PASS getDisplayMedia() overconstrained PASS getDisplayMedia() with getSettings Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/screen-capture/getdisplaymedia.https.html b/third_party/WebKit/LayoutTests/external/wpt/screen-capture/getdisplaymedia.https.html index f5edab5b..06ab72d2 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/screen-capture/getdisplaymedia.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/screen-capture/getdisplaymedia.https.html
@@ -6,115 +6,150 @@ <script> 'use strict'; -promise_test(function() { +promise_test(async t => { assert_idl_attribute(navigator, 'getDisplayMedia'); - - return navigator.getDisplayMedia({video: true}).then(function(s) { - assert_equals(s.getVideoTracks().length, 1); - assert_equals(s.getAudioTracks().length, 0); - }); + const stream = await navigator.getDisplayMedia({video: true}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + assert_equals(stream.getTracks().length, 1); + assert_equals(stream.getVideoTracks().length, 1); + assert_equals(stream.getAudioTracks().length, 0); }, 'getDisplayMedia() with video true'); // Empty constraint parameter and boolean values of false defaults to -// {video: true}. -promise_test(function() { +// {video: true}. This is described in items 3-4 of section 5.1, see +// https://w3c.github.io/mediacapture-screen-share/#navigator-additions. +// Note that this results in some non-intuitive cases returning a video track, +// i.e. {video: false}. +promise_test(async t => { assert_idl_attribute(navigator, 'getDisplayMedia'); - - return navigator.getDisplayMedia().then(function(s) { - assert_equals(s.getVideoTracks().length, 1); - assert_equals(s.getAudioTracks().length, 0); - }); + const stream = await navigator.getDisplayMedia(); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + assert_equals(stream.getTracks().length, 1); + assert_equals(stream.getVideoTracks().length, 1); + assert_equals(stream.getAudioTracks().length, 0); }, 'getDisplayMedia() with no constraints'); -promise_test(function() { +promise_test(async t => { assert_idl_attribute(navigator, 'getDisplayMedia'); - - return navigator.getDisplayMedia({video: false}).then(function(s) { - assert_equals(s.getVideoTracks().length, 1); - assert_equals(s.getAudioTracks().length, 0); - }); + const stream = await navigator.getDisplayMedia({video: false}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + assert_equals(stream.getTracks().length, 1); + assert_equals(stream.getVideoTracks().length, 1); + assert_equals(stream.getAudioTracks().length, 0); }, 'getDisplayMedia() with video false'); -promise_test(function() { +promise_test(async t => { assert_idl_attribute(navigator, 'getDisplayMedia'); - - return navigator.getDisplayMedia({audio: false}).then(function(s) { - assert_equals(s.getVideoTracks().length, 1); - assert_equals(s.getAudioTracks().length, 0); - }); + const stream = await navigator.getDisplayMedia({audio: false}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + assert_equals(stream.getTracks().length, 1); + assert_equals(stream.getVideoTracks().length, 1); + assert_equals(stream.getAudioTracks().length, 0); }, 'getDisplayMedia() with audio false'); -promise_test(function() { +promise_test(async t => { assert_idl_attribute(navigator, 'getDisplayMedia'); - - return navigator.getDisplayMedia({audio: true}).then(function(s) { - assert_equals(s.getVideoTracks().length, 0); - assert_equals(s.getAudioTracks().length, 1); - }); + const stream = await navigator.getDisplayMedia({audio: true}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + assert_equals(stream.getTracks().length, 1); + assert_equals(stream.getVideoTracks().length, 0); + assert_equals(stream.getAudioTracks().length, 1); }, 'getDisplayMedia() with audio true'); -promise_test(function() { +promise_test(async t => { assert_idl_attribute(navigator, 'getDisplayMedia'); + try { + const stream = + await navigator.getDisplayMedia({video: {advanced: [{zoom: 1}]}}); + } catch (err) { + assert_equals(err.name, 'TypeError'); + return; + } + assert_unreached('getDisplayMedia should have failed'); +}, 'getDisplayMedia() with advanced constraint'); - return navigator - .getDisplayMedia({video: {advanced: [{zoom: 1}]}}) - .then(function(s) { - fail('getDisplayMedia should have failed'); - }) - .catch(function(e) { - assert_equals(e.name, 'TypeError'); - }); -}, 'getDisplayMedia() call with advanced constraint'); - -promise_test(function() { +promise_test(async t => { assert_idl_attribute(navigator, 'getDisplayMedia'); + try { + const stream = + await navigator.getDisplayMedia({video: {width: {min: 360}}}); + } catch (err) { + assert_equals(err.name, 'TypeError'); + return; + } + assert_unreached('getDisplayMedia should have failed'); +}, 'getDisplayMedia() with min constraint'); - return navigator - .getDisplayMedia({video: {width: {min: 360}}}) - .then(function(s) { - fail('getDisplayMedia should have failed'); - }) - .catch(function(e) { - assert_equals(e.name, 'TypeError'); - }); -}, 'getDisplayMedia() call with min constraint'); - -promise_test(function() { +promise_test(async t => { assert_idl_attribute(navigator, 'getDisplayMedia'); + try { + const stream = + await navigator.getDisplayMedia({video: {width: {exact: 360}}}); + } catch (err) { + assert_equals(err.name, 'TypeError'); + return; + } + assert_unreached('getDisplayMedia should have failed'); +}, 'getDisplayMedia() with exact constraint'); - return navigator - .getDisplayMedia({video: {width: {exact: 360}}}) - .then(function(s) { - fail('getDisplayMedia should have failed'); - }) - .catch(function(e) { - assert_equals(e.name, 'TypeError'); - }); -}, 'getDisplayMedia() call with exact constraint'); - -promise_test(function() { +promise_test(async t => { assert_idl_attribute(navigator, 'getDisplayMedia'); + const maxWidth = 360; + const stream = + await navigator.getDisplayMedia({video: {width: {max: maxWidth}}}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + assert_equals(stream.getVideoTracks().length, 1); + assert_equals(stream.getAudioTracks().length, 0); + assert_less_than_equal( + stream.getVideoTracks()[0].getSettings().width, maxWidth); +}, 'getDisplayMedia() with max constraint'); - return navigator - .getDisplayMedia({video: {width: {max: 360}}}) - .then(function(s) { - assert_equals(s.getVideoTracks().length, 1); - assert_equals(s.getAudioTracks().length, 0); - }); -}, 'getDisplayMedia() call with max constraint'); +promise_test(async t => { + assert_idl_attribute(navigator, 'getDisplayMedia'); + const maxWidth = 360; + const maxFrameRate = 4; + const stream = await navigator.getDisplayMedia( + {video: {width: {max: maxWidth}, frameRate: {max: maxFrameRate}}}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + assert_equals(stream.getVideoTracks().length, 1); + assert_equals(stream.getAudioTracks().length, 0); + const settings = stream.getVideoTracks()[0].getSettings(); + assert_less_than_equal(settings.width, maxWidth); + assert_less_than_equal(settings.frameRate, maxFrameRate); +}, 'getDisplayMedia() with constraints applied'); + +promise_test(async t => { + assert_idl_attribute(navigator, 'getDisplayMedia'); + try { + const stream = await navigator.getDisplayMedia({video: {width: {max: 0}}}); + } catch (err) { + assert_equals(err.name, 'OverconstrainedError'); + return; + } + assert_unreached('getDisplayMedia should have failed'); +}, 'getDisplayMedia() overconstrained'); // Content shell picks a fake desktop device by default. -promise_test(function() { +promise_test(async t => { assert_idl_attribute(navigator, 'getDisplayMedia'); - - return navigator.getDisplayMedia({video: true}).then(function(s) { - assert_equals(s.getVideoTracks().length, 1); - assert_equals(s.getAudioTracks().length, 0); - var settings = s.getVideoTracks()[0].getSettings(); - assert_equals(settings.displaySurface, "monitor"); - assert_equals(settings.logicalSurface, true); - assert_equals(settings.cursor, "never"); - }); + const stream = await navigator.getDisplayMedia({video: true}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + assert_equals(stream.getVideoTracks().length, 1); + assert_equals(stream.getAudioTracks().length, 0); + const settings = stream.getVideoTracks()[0].getSettings(); + assert_any( + assert_equals, settings.displaySurface, + ['monitor', 'window', 'application', 'browser']); + assert_any(assert_equals, settings.logicalSurface, [true, false]); + assert_any(assert_equals, settings.cursor, ['never', 'always', 'motion']); }, 'getDisplayMedia() with getSettings'); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/imported-classic-script.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/imported-classic-script.js new file mode 100644 index 0000000..5fc52040 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/imported-classic-script.js
@@ -0,0 +1 @@ +const imported = 'A classic script.';
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/imported-module-script.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/imported-module-script.js new file mode 100644 index 0000000..56d196df --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/imported-module-script.js
@@ -0,0 +1 @@ +export const imported = 'A module script.';
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/update-registration-with-type.py b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/update-registration-with-type.py new file mode 100644 index 0000000..4f6d5ae28 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/update-registration-with-type.py
@@ -0,0 +1,33 @@ +def classic_script(): + return """ + importScripts('./imported-classic-script.js'); + self.onmessage = e => { + e.source.postMessage(imported); + }; + """ + +def module_script(): + return """ + import * as module from './imported-module-script.js'; + self.onmessage = e => { + e.source.postMessage(module.imported); + }; + """ + +# Returns the classic script for a first request and +# returns the module script for second and subsequent requests. +def main(request, response): + headers = [('Content-Type', 'application/javascript'), + ('Pragma', 'no-store'), + ('Cache-Control', 'no-store')] + + classic_first = request.GET['classic_first'] + key = request.GET['key'] + requested_once = request.server.stash.take(key) + if requested_once is None: + request.server.stash.put(key, True) + body = classic_script() if classic_first == '1' else module_script() + else: + body = module_script() if classic_first == '1' else classic_script() + + return 200, headers, body
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/update-registration-with-type.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/update-registration-with-type.https.html new file mode 100644 index 0000000..00c8a33 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/update-registration-with-type.https.html
@@ -0,0 +1,74 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Service Worker: Update the registration with a different script type.</title> +<!-- common.js is for guid() --> +<script src="/mixed-content/generic/common.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/test-helpers.sub.js"></script> +<script> +// These tests check that a registration is updated correctly with +// different script type. At first Service Worker is register as +// classic script type, then it is re-registered as module script type, +// and vice versa. A main script is also updated at the same time. +promise_test(async t => { + const key = guid(); + const script = `resources/update-registration-with-type.py?classic_first=1&key=${key}`; + const scope = 'resources/update-registration-with-type'; + await service_worker_unregister(t, scope); + + // Register with classic script type. + const firstRegistration = await navigator.serviceWorker.register(script, { + scope: scope, + type: 'classic' + }); + firstRegistration.installing.postMessage(' '); + let msgEvent = await new Promise(resolve => { + navigator.serviceWorker.onmessage = resolve; + }); + assert_equals(msgEvent.data, 'A classic script.'); + + // Re-register with module script type. + const secondRegistration = await navigator.serviceWorker.register(script, { + scope: scope, + type: 'module' + }); + secondRegistration.installing.postMessage(' '); + msgEvent = await new Promise(resolve => { + navigator.serviceWorker.onmessage = resolve; + }); + assert_equals(msgEvent.data, 'A module script.'); + assert_equals(firstRegistration, secondRegistration); +}, 'Update the registration with a different script type (classic => module).'); + +promise_test(async t => { + const key = guid(); + const script = `resources/update-registration-with-type.py?classic_first=0&key=${key}`; + const scope = 'resources/update-registration-with-type'; + await service_worker_unregister(t, scope); + + // Register with module script type. + const firstRegistration = await navigator.serviceWorker.register(script, { + scope: scope, + type: 'module' + }); + firstRegistration.installing.postMessage(' '); + let msgEvent = await new Promise(resolve => { + navigator.serviceWorker.onmessage = resolve; + }); + assert_equals(msgEvent.data, 'A module script.'); + + // Re-register with classic script type. + const secondRegistration = await navigator.serviceWorker.register(script, { + scope: scope, + type: 'classic' + }); + secondRegistration.installing.postMessage(' '); + msgEvent = await new Promise(resolve => { + navigator.serviceWorker.onmessage = resolve; + }); + assert_equals(msgEvent.data, 'A classic script.'); + assert_equals(firstRegistration, secondRegistration); +}, 'Update the registration with a different script type (module => classic).'); +</script> +</body>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/color-space/transferFromImageBitmap.html b/third_party/WebKit/LayoutTests/fast/canvas/color-space/transferFromImageBitmap.html index 1de2cc5..9ccb32c 100644 --- a/third_party/WebKit/LayoutTests/fast/canvas/color-space/transferFromImageBitmap.html +++ b/third_party/WebKit/LayoutTests/fast/canvas/color-space/transferFromImageBitmap.html
@@ -111,7 +111,7 @@ ]; var alphaValues = [0.5, 1]; var colorSpaceConversions = [ - 'none', 'default', 'preserve', 'srgb', 'linear-rgb', 'rec2020', 'p3']; + 'none', 'default', 'srgb', 'linear-rgb', 'rec2020', 'p3']; var testScenarios = []; for (var i = 0; i < colorSpaces.length; i++)
diff --git a/third_party/WebKit/LayoutTests/fast/scrolling/fractional-scroll-offset-document-expected.txt b/third_party/WebKit/LayoutTests/fast/scrolling/fractional-scroll-offset-document-expected.txt deleted file mode 100644 index 70dc4d9..0000000 --- a/third_party/WebKit/LayoutTests/fast/scrolling/fractional-scroll-offset-document-expected.txt +++ /dev/null
@@ -1,16 +0,0 @@ -Verifies that document scrolling supports fractional offset. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS successfullyParsed is true - -TEST COMPLETE -PASS document.scrollingElement.scrollTop is within 0.00001 of 0 -PASS document.scrollingElement.scrollLeft is within 0.00001 of 0 -PASS document.scrollingElement.scrollTop is within 0.00001 of 10 -PASS document.scrollingElement.scrollLeft is within 0.00001 of 20 -PASS document.scrollingElement.scrollTop is within 0.00001 of 31 -PASS document.scrollingElement.scrollLeft is within 0.00001 of 9 -PASS document.scrollingElement.scrollTop is within 0.00001 of 0 -PASS document.scrollingElement.scrollLeft is within 0.00001 of 0
diff --git a/third_party/WebKit/LayoutTests/fast/scrolling/fractional-scroll-offset-document.html b/third_party/WebKit/LayoutTests/fast/scrolling/fractional-scroll-offset-document.html index fce58cd..03621af 100644 --- a/third_party/WebKit/LayoutTests/fast/scrolling/fractional-scroll-offset-document.html +++ b/third_party/WebKit/LayoutTests/fast/scrolling/fractional-scroll-offset-document.html
@@ -1,48 +1,78 @@ <!DOCTYPE HTML> -<body style="width:30000px;height:30000px" onload="runTest()"> -</body> +<script src='../../resources/testharness.js'></script> +<script src='../../resources/testharnessreport.js'></script> +<script src='../../resources/gesture-util.js'></script> +<style> + body,html { + margin: 0; + width: 10000px; + height: 10000px; + } +</style> -<script src="../../resources/js-test.js"></script> <script> -description("Verifies that document scrolling supports fractional offset."); + const scroller = document.scrollingElement; + let floatPrecision = 0.00001; -var floatPrecision = 0.00001; -var useIntegerScrollOffset = true; -function checkScrollOffset(offset_x, offset_y) -{ - if (useIntegerScrollOffset) { - offset_x = Math.floor(offset_x); - offset_y = Math.floor(offset_y); - } - shouldBeCloseTo('document.scrollingElement.scrollTop', offset_y, floatPrecision); - shouldBeCloseTo('document.scrollingElement.scrollLeft', offset_x, floatPrecision); -} + window.addEventListener('load', async () => { + await waitForCompositorCommit(); -function scroll() -{ - window.scrollTo(0, 0); - eventSender.gestureScrollBegin(100.1, 300.2); - checkScrollOffset(0, 0); - eventSender.gestureScrollUpdate(-20.5, -10.2); - checkScrollOffset(20.5, 10.2); - eventSender.gestureScrollUpdate(10.9, -20.9); - checkScrollOffset(9.6, 31.1); - eventSender.gestureScrollUpdate(100.4, 220.9); - checkScrollOffset(0.0, 0.0); - eventSender.gestureScrollEnd(0, 0); -} + promise_test(async () => { + scroller.scrollTop = 0; + scroller.scrollLeft = 0; + const distance = 5; + const x = 400; + const y = 300; + const precise_deltas = true; -function runTest() -{ - if (window.eventSender) { - if (internals.runtimeFlags.fractionalScrollOffsetsEnabled) { - debug("fractional scroll offset mode"); - internals.settings.setPreferCompositingToLCDTextEnabled(true); - useIntegerScrollOffset = true; + if (window.internals) { + window.internals.setPageScaleFactor(4); + window.internals.setVisualViewportOffset(600, 450); + await waitForCompositorCommit(); } - scroll(); - } -} + let expected_scroll = distance / window.visualViewport.scale; + + // If fractional scroll offsets are enabled, the expected scroll offset + // should be the actuall fractional distance we scrolled. Otherwise the + // offset should be truncated. + if (internals.runtimeFlags.fractionalScrollOffsetsEnabled) { + assert_not_equals(expected_scroll, + Math.round(expected_scroll), + 'Expected scroll should be fractional'); + } else { + expected_scroll = Math.floor(expected_scroll); + } + + // Scroll Vertically + await smoothScroll(distance, + x, y, + GestureSourceType.TOUCHPAD_INPUT, + 'down', + SPEED_INSTANT, + precise_deltas); + + await waitFor(() => { return scroller.scrollTop >= expected_scroll; }, + "Didn't scroll to expected value."); + await waitForCompositorCommit(); + assert_approx_equals(scroller.scrollTop, expected_scroll, floatPrecision); + + await waitForCompositorCommit(); + + // Scroll Horizontally + await smoothScroll(distance, + x, y, + GestureSourceType.TOUCHPAD_INPUT, + 'right', + SPEED_INSTANT, + precise_deltas); + + await waitFor(() => { return scroller.scrollLeft >= expected_scroll; }, + "Didn't scroll to expected value."); + + await waitForCompositorCommit(); + + assert_approx_equals(scroller.scrollLeft, expected_scroll, floatPrecision); + }, 'Scrolling while zoomed scroller preserves fractional offsets.'); + }); </script> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/scrolling/scrolling-apis-subpixel.html b/third_party/WebKit/LayoutTests/fast/scrolling/scrolling-apis-subpixel.html index e38eed93..bf0c5a5 100644 --- a/third_party/WebKit/LayoutTests/fast/scrolling/scrolling-apis-subpixel.html +++ b/third_party/WebKit/LayoutTests/fast/scrolling/scrolling-apis-subpixel.html
@@ -1,42 +1,35 @@ <!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> + <style> .spacer { height: 1000px; width: 1000px; } -#scroller, body { +#scroller { height: 100px; width: 100px; overflow: scroll; } </style> -<body class=scroller> <div id=scroller> <div class=spacer></div> </div> <div class=spacer></div> -</body> -<script src="../../resources/testharness.js"></script> -<script src="../../resources/testharnessreport.js"></script> -<script> -// Note we current support fractional scrolling only for the special case of -// browser zoom. When http://crbug.com/414283 is fixed, we should test -// other cases like device scale. +<script> // FIXME: Make this smaller. crbug.com/414283. var floatPrecision = 0.01; function testScroll(scrollOffset, expectedScrollOffset) { // Scrolling DIV with scrollTop/scrollLeft scroller.scrollTop = scrollOffset; - assert_approx_equals(scroller.scrollTop, expectedScrollOffset, floatPrecision); scroller.scrollLeft = scrollOffset; + assert_approx_equals(scroller.scrollTop, expectedScrollOffset, floatPrecision); assert_approx_equals(scroller.scrollLeft, expectedScrollOffset, floatPrecision); - // Note that the body element is a special case - we don't attempt to - // test it here as it's semantics are in flux (http://goo.gl/BFHtMR). - //Scrolling the document with window.scroll window.scroll(0,0); scrollOffset++; @@ -58,24 +51,41 @@ assert_approx_equals(window.scrollX, expectedScrollOffset, floatPrecision); } -function testPageZoom(zoom) { - internals.setZoomFactor(2); - testScroll(4, 4); - testScroll(4.5, 4.5); -} +test( () => { + const setOffset = 4.2; + let expectedOffset = 4; + + // When fractional offsets are enabled, we should allow setting a fractional + // scroll offset. + if (internals.runtimeFlags.fractionalScrollOffsetsEnabled) + expectedOffset = 4.2; + + testScroll(setOffset, expectedOffset); +}, "Set fractional scroll offset without zoom"); test( () => { - internals.settings.setPreferCompositingToLCDTextEnabled(false); - testScroll(4.2, 4); - testPageZoom(2); -}, "By default we don't yet get fractional scroll offsets with more " + - "granularity than the page zoom factor."); + internals.setZoomFactor(2); -if (internals.runtimeFlags.fractionalScrollOffsetsEnabled) { - test( () => { - internals.settings.setPreferCompositingToLCDTextEnabled(true); - testScroll(4.2, 4.2); - testPageZoom(2); - }, "Verifies that scrolling APIs support fractional offsets."); -} + // Zooming provides additional granularity, regardless of the runtimeFlag + // being enabled or not. + const setOffset = 4.5; + const expectedOffset = 4.5; + testScroll(setOffset, expectedOffset); +}, "Set fractional scroll offset when zoomed"); + +test( () => { + internals.setZoomFactor(2); + + // Zooming provides additional granularity but we try to set a value beyond the 0.5 increment. + const setOffset = 4.6; + let expectedOffset = 4.5; + + // When fractional offsets are enabled, we should allow setting a fractional + // scroll offset. + if (internals.runtimeFlags.fractionalScrollOffsetsEnabled) + expectedOffset = 4.6; + + testScroll(setOffset, expectedOffset); +}, "Set fractional scroll offset to higher granularity when zoomed."); + </script>
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/cached-69296-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/cached-69296-expected.txt index 79ed8d6..3dcb8f6 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/cached-69296-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v2/paint/invalidation/table/cached-69296-expected.txt
@@ -12,7 +12,7 @@ "reason": "background" }, { - "object": "LayoutTableRow TR id='row1'", + "object": "LayoutTableRow TR id='row1' class='change'", "rect": [20, 20, 160, 51], "reason": "background" }
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-cached-image-expected.png b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-cached-image-expected.png new file mode 100644 index 0000000..453c7f4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-cached-image-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-cached-image.html b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-cached-image.html new file mode 100644 index 0000000..a433b7b0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/images/feature-policy-image-compression-cached-image.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<style> +body { + font: 10px Ahem; +} +</style> +<body> + <iframe src="resources/frame-with-compression-test-images.html" allow="image-compression 'none'" width="440" height="180"></iframe> + <iframe src="resources/frame-with-compression-test-images.html" allow="image-compression 'none'" width="440" height="180"></iframe> + <iframe src="resources/frame-with-compression-test-images.html" allow="image-compression 'none'" width="440" height="180"></iframe> +</body>
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table/cached-69296-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-69296-expected.txt similarity index 91% rename from third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table/cached-69296-expected.txt rename to third_party/WebKit/LayoutTests/paint/invalidation/table/cached-69296-expected.txt index 4c1f86c..ac9679b4b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/table/cached-69296-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-69296-expected.txt
@@ -23,7 +23,7 @@ "reason": "background" }, { - "object": "LayoutTableRow TR id='row1'", + "object": "LayoutTableRow TR id='row1' class='change'", "rect": [20, 20, 160, 51], "reason": "background" }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-69296.html b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-69296.html index 1d947cf..60dc47b2 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-69296.html +++ b/third_party/WebKit/LayoutTests/paint/invalidation/table/cached-69296.html
@@ -5,6 +5,7 @@ <html> <head> <script src="../resources/text-based-repaint.js"></script> + <script src="../../../resources/run-after-layout-and-paint.js"></script> <style> BODY { margin: 20px; @@ -17,7 +18,7 @@ height: 50px; border: 1px solid #333333; } - #row1:hover { + #row1.change { background-color: #ddd; color: #111; } @@ -26,18 +27,10 @@ <script type="text/javascript"> window.testIsAsync = true; function repaintTest() { - row = document.getElementById('row1'); - rowRect = row.getBoundingClientRect(); - x = rowRect.left + 75; - y = rowRect.top; - requestAnimationFrame(function() { - // Move cursor over row. - if (window.eventSender) - eventSender.mouseMoveTo(x, y + 1); - requestAnimationFrame(function() { - // Move cursor off row. - if (window.eventSender) - eventSender.mouseMoveTo(x, y - 1); + row1.classList.add('change'); + runAfterLayoutAndPaint(function() { + row1.classList.remove('change'); + runAfterLayoutAndPaint(function() { finishRepaintTest(); }); });
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/paint/invalidation/table/cached-69296-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/paint/invalidation/table/cached-69296-expected.txt deleted file mode 100644 index 4c1f86c..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/paint/invalidation/table/cached-69296-expected.txt +++ /dev/null
@@ -1,34 +0,0 @@ -{ - "layers": [ - { - "name": "LayoutView #document", - "bounds": [800, 600], - "drawsContent": false, - "backgroundColor": "#FFFFFF" - }, - { - "name": "Scrolling Layer", - "bounds": [800, 600], - "drawsContent": false - }, - { - "name": "Scrolling Contents Layer", - "bounds": [800, 600], - "contentsOpaque": true, - "backgroundColor": "#FFFFFF", - "paintInvalidations": [ - { - "object": "LayoutTableRow TR id='row1'", - "rect": [20, 20, 160, 51], - "reason": "background" - }, - { - "object": "LayoutTableRow TR id='row1'", - "rect": [20, 20, 160, 51], - "reason": "background" - } - ] - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/paint/invalidation/table/cached-69296-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/paint/invalidation/table/cached-69296-expected.txt deleted file mode 100644 index 58ba65a..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/paint/invalidation/table/cached-69296-expected.txt +++ /dev/null
@@ -1,22 +0,0 @@ -{ - "layers": [ - { - "name": "LayoutView #document", - "bounds": [800, 600], - "drawsContent": false, - "backgroundColor": "#FFFFFF" - }, - { - "name": "Scrolling Layer", - "bounds": [800, 600], - "drawsContent": false - }, - { - "name": "Scrolling Contents Layer", - "bounds": [800, 600], - "contentsOpaque": true, - "backgroundColor": "#FFFFFF" - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/table/cached-69296-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/table/cached-69296-expected.txt deleted file mode 100644 index 4c1f86c..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/paint/invalidation/table/cached-69296-expected.txt +++ /dev/null
@@ -1,34 +0,0 @@ -{ - "layers": [ - { - "name": "LayoutView #document", - "bounds": [800, 600], - "drawsContent": false, - "backgroundColor": "#FFFFFF" - }, - { - "name": "Scrolling Layer", - "bounds": [800, 600], - "drawsContent": false - }, - { - "name": "Scrolling Contents Layer", - "bounds": [800, 600], - "contentsOpaque": true, - "backgroundColor": "#FFFFFF", - "paintInvalidations": [ - { - "object": "LayoutTableRow TR id='row1'", - "rect": [20, 20, 160, 51], - "reason": "background" - }, - { - "object": "LayoutTableRow TR id='row1'", - "rect": [20, 20, 160, 51], - "reason": "background" - } - ] - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/paint/invalidation/table/cached-69296-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/paint/invalidation/table/cached-69296-expected.txt deleted file mode 100644 index 4c1f86c..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/paint/invalidation/table/cached-69296-expected.txt +++ /dev/null
@@ -1,34 +0,0 @@ -{ - "layers": [ - { - "name": "LayoutView #document", - "bounds": [800, 600], - "drawsContent": false, - "backgroundColor": "#FFFFFF" - }, - { - "name": "Scrolling Layer", - "bounds": [800, 600], - "drawsContent": false - }, - { - "name": "Scrolling Contents Layer", - "bounds": [800, 600], - "contentsOpaque": true, - "backgroundColor": "#FFFFFF", - "paintInvalidations": [ - { - "object": "LayoutTableRow TR id='row1'", - "rect": [20, 20, 160, 51], - "reason": "background" - }, - { - "object": "LayoutTableRow TR id='row1'", - "rect": [20, 20, 160, 51], - "reason": "background" - } - ] - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table/cached-69296-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table/cached-69296-expected.txt deleted file mode 100644 index 58ba65a..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/table/cached-69296-expected.txt +++ /dev/null
@@ -1,22 +0,0 @@ -{ - "layers": [ - { - "name": "LayoutView #document", - "bounds": [800, 600], - "drawsContent": false, - "backgroundColor": "#FFFFFF" - }, - { - "name": "Scrolling Layer", - "bounds": [800, 600], - "drawsContent": false - }, - { - "name": "Scrolling Contents Layer", - "bounds": [800, 600], - "contentsOpaque": true, - "backgroundColor": "#FFFFFF" - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/third_party/NotoColorEmoji/LICENSE b/third_party/WebKit/LayoutTests/third_party/NotoColorEmoji/LICENSE new file mode 100644 index 0000000..d952d62 --- /dev/null +++ b/third_party/WebKit/LayoutTests/third_party/NotoColorEmoji/LICENSE
@@ -0,0 +1,92 @@ +This Font Software is licensed under the SIL Open Font License, +Version 1.1. + +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font +creation efforts of academic and linguistic communities, and to +provide a free and open framework in which fonts may be shared and +improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply to +any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software +components as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, +deleting, or substituting -- in part or in whole -- any of the +components of the Original Version, by changing formats or by porting +the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, +modify, redistribute, and sell modified and unmodified copies of the +Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in +Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the +corresponding Copyright Holder. This restriction only applies to the +primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created using +the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/third_party/WebKit/LayoutTests/third_party/NotoColorEmoji/NotoColorEmoji.ttf b/third_party/WebKit/LayoutTests/third_party/NotoColorEmoji/NotoColorEmoji.ttf new file mode 100644 index 0000000..3117123 --- /dev/null +++ b/third_party/WebKit/LayoutTests/third_party/NotoColorEmoji/NotoColorEmoji.ttf Binary files differ
diff --git a/third_party/WebKit/LayoutTests/third_party/NotoColorEmoji/README.chromium b/third_party/WebKit/LayoutTests/third_party/NotoColorEmoji/README.chromium new file mode 100644 index 0000000..37a38326 --- /dev/null +++ b/third_party/WebKit/LayoutTests/third_party/NotoColorEmoji/README.chromium
@@ -0,0 +1,7 @@ +URL: https://github.com/googlei18n/noto-emoji +Version: v2018-08-10-unicode11 +License: OFL 1.1 +License File: LICENSE +Description: +Noto Color Emoji font, needed for emoji test cases, including emoji cluster +fallback. \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/virtual/fractional_scrolling/fast/scrolling/README.txt b/third_party/WebKit/LayoutTests/virtual/fractional_scrolling/fast/scrolling/README.txt new file mode 100644 index 0000000..22fd740 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/fractional_scrolling/fast/scrolling/README.txt
@@ -0,0 +1,3 @@ +# This suite runs the tests in fast/scrolling with Blink fractional scroll +# offsets enabled. +# See the virtual_test_suites() method in tools/blinkpy/web_tests/port/base.py.
diff --git a/third_party/WebKit/LayoutTests/virtual/fractional_scrolling_threaded/fast/scrolling/README.txt b/third_party/WebKit/LayoutTests/virtual/fractional_scrolling_threaded/fast/scrolling/README.txt new file mode 100644 index 0000000..b01dc38a --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/fractional_scrolling_threaded/fast/scrolling/README.txt
@@ -0,0 +1,3 @@ +# This suite runs the tests in fast/scrolling with Blink fractional scroll +# offsets and threaded scrolling enabled. +# See the virtual_test_suites() method in tools/blinkpy/web_tests/port/base.py.
diff --git a/third_party/blink/public/platform/task_type.h b/third_party/blink/public/platform/task_type.h index fb5425c..6589eb11 100644 --- a/third_party/blink/public/platform/task_type.h +++ b/third_party/blink/public/platform/task_type.h
@@ -181,6 +181,9 @@ // * //third_party/blink/renderer/core/workers kInternalWorker = 36, + // Translation task that freezes when the frame is not visible. + kInternalTranslation = 55, + // Tasks used at IntersectionObserver. kInternalIntersectionObserver = 44, @@ -202,7 +205,7 @@ kWorkerThreadTaskQueueV8 = 47, kWorkerThreadTaskQueueCompositor = 48, - kCount = 55, + kCount = 56, }; } // namespace blink
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom index b665e89a..2f0499c 100644 --- a/third_party/blink/public/platform/web_feature.mojom +++ b/third_party/blink/public/platform/web_feature.mojom
@@ -2062,6 +2062,7 @@ kV8AttemptOverrideReadOnlyOnPrototypeSloppy = 2609, kV8AttemptOverrideReadOnlyOnPrototypeStrict = 2610, kHTMLCanvasElementLowLatency = 2611, + kV8OptimizedFunctionWithOneShotBytecode = 2612, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots. // Also, run update_use_counter_feature_enum.py in
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h index 3e1b976..e0cf5f1 100644 --- a/third_party/blink/public/platform/web_url_request.h +++ b/third_party/blink/public/platform/web_url_request.h
@@ -270,6 +270,11 @@ BLINK_PLATFORM_EXPORT ExtraData* GetExtraData() const; BLINK_PLATFORM_EXPORT void SetExtraData(std::unique_ptr<ExtraData>); + // The request is downloaded to the network cache, but not rendered or + // executed. + BLINK_PLATFORM_EXPORT bool IsDownloadToNetworkCacheOnly() const; + BLINK_PLATFORM_EXPORT void SetDownloadToNetworkCacheOnly(bool); + BLINK_PLATFORM_EXPORT Priority GetPriority() const; BLINK_PLATFORM_EXPORT void SetPriority(Priority);
diff --git a/third_party/blink/renderer/bindings/OWNERS b/third_party/blink/renderer/bindings/OWNERS index 10235ec..b0d7b28 100644 --- a/third_party/blink/renderer/bindings/OWNERS +++ b/third_party/blink/renderer/bindings/OWNERS
@@ -10,7 +10,7 @@ mlippautz@chromium.org peria@chromium.org pfeldman@chromium.org -vivek.vg@samsung.com +vivekg@chromium.org yhirano@chromium.org yukishiino@chromium.org
diff --git a/third_party/blink/renderer/bindings/core/v8/dictionary.cc b/third_party/blink/renderer/bindings/core/v8/dictionary.cc index 39d148e..ef5dc17 100644 --- a/third_party/blink/renderer/bindings/core/v8/dictionary.cc +++ b/third_party/blink/renderer/bindings/core/v8/dictionary.cc
@@ -95,13 +95,16 @@ if (dictionary_object_.IsEmpty()) return false; - if (!V8CallBoolean(dictionary_object_->Has(V8Context(), key))) - return false; - - // Swallow a possible exception in v8::Object::Get(). + // Swallow possible exceptions in v8::Object::Get() and Has(). // TODO(bashi,yukishiino): Should rethrow the exception. // http://crbug.com/666661 v8::TryCatch try_catch(GetIsolate()); + + bool has_property; + if (!dictionary_object_->Has(V8Context(), key).To(&has_property) || + !has_property) + return false; + return dictionary_object_->Get(V8Context(), key).ToLocal(&result); }
diff --git a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc index 81b1e2d..63b593d 100644 --- a/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc +++ b/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc
@@ -458,11 +458,11 @@ v8::Local<v8::Object> creation_context, v8::Isolate* isolate) { if (!html_document->HasNamedItem(key)) - return V8Undefined(); + return v8::Local<v8::Value>(); DocumentNameCollection* items = html_document->DocumentNamedItems(key); if (items->IsEmpty()) - return V8Undefined(); + return v8::Local<v8::Value>(); if (items->HasExactlyOneItem()) { HTMLElement* element = items->Item(0);
diff --git a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc index deaff306..1a43379 100644 --- a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc +++ b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
@@ -214,6 +214,9 @@ case v8::Isolate::kAttemptOverrideReadOnlyOnPrototypeStrict: blink_feature = WebFeature::kV8AttemptOverrideReadOnlyOnPrototypeStrict; break; + case v8::Isolate::kOptimizedFunctionWithOneShotBytecode: + blink_feature = WebFeature::kV8OptimizedFunctionWithOneShotBytecode; + break; default: // This can happen if V8 has added counters that this version of Blink // does not know about. It's harmless.
diff --git a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc index 11f1bcd..10e94a4 100644 --- a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc +++ b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc
@@ -84,7 +84,7 @@ // values as undefined, rather than the more typical (for DOM) null. // This appears on the |upper| and |lower| attributes of IDBKeyRange. // Spec: http://www.w3.org/TR/IndexedDB/#idl-def-IDBKeyRange - return V8Undefined(); + return v8::Local<v8::Value>(); } v8::Local<v8::Context> context = isolate->GetCurrentContext(); @@ -93,7 +93,7 @@ case IDBKey::kInvalidType: case IDBKey::kTypeEnumMax: NOTREACHED(); - return V8Undefined(); + return v8::Local<v8::Value>(); case IDBKey::kNumberType: return v8::Number::New(isolate, key->Number()); case IDBKey::kStringType: @@ -111,15 +111,18 @@ ToV8(key->Array()[i].get(), creation_context, isolate); if (value.IsEmpty()) value = v8::Undefined(isolate); - if (!V8CallBoolean(array->CreateDataProperty(context, i, value))) - return V8Undefined(); + bool created_property; + if (!array->CreateDataProperty(context, i, value) + .To(&created_property) || + !created_property) + return v8::Local<v8::Value>(); } return array; } } NOTREACHED(); - return V8Undefined(); + return v8::Local<v8::Value>(); } // IDBAny is a variant type used to hold the values produced by the |result| @@ -219,7 +222,12 @@ v8::TryCatch block(isolate); v8::Local<v8::Context> context = isolate->GetCurrentContext(); for (uint32_t i = 0; i < length; ++i) { - if (!V8CallBoolean(array->HasOwnProperty(context, i))) + bool has_own_property; + if (!array->HasOwnProperty(context, i).To(&has_own_property)) { + exception_state.RethrowV8Exception(block.Exception()); + return nullptr; + } + if (!has_own_property) return nullptr; v8::Local<v8::Value> item; if (!array->Get(context, i).ToLocal(&item)) { @@ -345,7 +353,12 @@ } v8::Local<v8::String> key = V8String(isolate, element); - if (!V8CallBoolean(object->HasOwnProperty(context, key))) + bool has_own_property; + if (!object->HasOwnProperty(context, key).To(&has_own_property)) { + exception_state.RethrowV8Exception(block.Exception()); + return nullptr; + } + if (!has_own_property) return nullptr; if (!object->Get(context, key).ToLocal(&v8_value)) { exception_state.RethrowV8Exception(block.Exception()); @@ -447,8 +460,11 @@ DeserializeIDBValue(isolate, creation_context, values[i].get()); if (v8_value.IsEmpty()) v8_value = v8::Undefined(isolate); - if (!V8CallBoolean(array->CreateDataProperty(context, i, v8_value))) - return V8Undefined(); + bool created_property; + if (!array->CreateDataProperty(context, i, v8_value) + .To(&created_property) || + !created_property) + return v8::Local<v8::Value>(); } return array; @@ -532,7 +548,10 @@ return false; } else { value = v8::Object::New(isolate); - if (!V8CallBoolean(object->CreateDataProperty(context, property, value))) + bool created_property; + if (!object->CreateDataProperty(context, property, value) + .To(&created_property) || + !created_property) return false; } } @@ -551,10 +570,11 @@ v8::Local<v8::Object> object = value.As<v8::Object>(); v8::Local<v8::String> property = V8String(isolate, key_path_elements.back()); - if (!V8CallBoolean(object->CreateDataProperty(context, property, key))) - return false; - return true; + bool created_property; + if (!object->CreateDataProperty(context, property, key).To(&created_property)) + return false; + return created_property; } // Verify that an value can have an generated key inserted at the location
diff --git a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules_test.cc b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules_test.cc index 6753e600..c9194ea9 100644 --- a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules_test.cc +++ b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules_test.cc
@@ -37,6 +37,7 @@ #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" #include "third_party/blink/renderer/bindings/modules/v8/to_v8_for_modules.h" #include "third_party/blink/renderer/modules/indexeddb/idb_any.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key.h" @@ -194,13 +195,9 @@ v8::Isolate* isolate = scope.GetIsolate(); // object = { foo: "zoo" } - v8::Local<v8::Object> object = v8::Object::New(isolate); - ASSERT_TRUE(V8CallBoolean(object->Set(scope.GetContext(), - V8AtomicString(isolate, "foo"), - V8AtomicString(isolate, "zoo")))); - - ScriptValue script_value(scope.GetScriptState(), object); - + ScriptValue script_value = V8ObjectBuilder(scope.GetScriptState()) + .Add("foo", "zoo") + .GetScriptValue(); CheckKeyPathStringValue(isolate, script_value, "foo", "zoo"); CheckKeyPathNullValue(isolate, script_value, "bar"); } @@ -212,32 +209,23 @@ v8::Isolate* isolate = scope.GetIsolate(); // object = { foo: 456 } - v8::Local<v8::Object> object = v8::Object::New(isolate); - ASSERT_TRUE(V8CallBoolean(object->Set(scope.GetContext(), - V8AtomicString(isolate, "foo"), - v8::Number::New(isolate, 456)))); - - ScriptValue script_value(scope.GetScriptState(), object); - + ScriptValue script_value = V8ObjectBuilder(scope.GetScriptState()) + .AddNumber("foo", 456) + .GetScriptValue(); CheckKeyPathNumberValue(isolate, script_value, "foo", 456); CheckKeyPathNullValue(isolate, script_value, "bar"); } TEST(IDBKeyFromValueAndKeyPathTest, SubProperty) { V8TestingScope scope; + ScriptState* script_state = scope.GetScriptState(); v8::Isolate* isolate = scope.GetIsolate(); // object = { foo: { bar: "zee" } } - v8::Local<v8::Object> object = v8::Object::New(isolate); - v8::Local<v8::Object> sub_property = v8::Object::New(isolate); - ASSERT_TRUE(V8CallBoolean(sub_property->Set(scope.GetContext(), - V8AtomicString(isolate, "bar"), - V8AtomicString(isolate, "zee")))); - ASSERT_TRUE(V8CallBoolean(object->Set( - scope.GetContext(), V8AtomicString(isolate, "foo"), sub_property))); - - ScriptValue script_value(scope.GetScriptState(), object); - + ScriptValue script_value = + V8ObjectBuilder(script_state) + .Add("foo", V8ObjectBuilder(script_state).Add("bar", "zee")) + .GetScriptValue(); CheckKeyPathStringValue(isolate, script_value, "foo.bar", "zee"); CheckKeyPathNullValue(isolate, script_value, "bar"); } @@ -263,15 +251,11 @@ TEST(InjectIDBKeyTest, TopLevelPropertyStringValue) { V8TestingScope scope; - v8::Isolate* isolate = scope.GetIsolate(); // object = { foo: "zoo" } - v8::Local<v8::Object> object = v8::Object::New(isolate); - ASSERT_TRUE(V8CallBoolean(object->Set(scope.GetContext(), - V8AtomicString(isolate, "foo"), - V8AtomicString(isolate, "zoo")))); - - ScriptValue script_object(scope.GetScriptState(), object); + ScriptValue script_object = V8ObjectBuilder(scope.GetScriptState()) + .Add("foo", "zoo") + .GetScriptValue(); std::unique_ptr<IDBKey> idb_string_key = IDBKey::CreateString("myNewKey"); CheckInjection(scope.GetScriptState(), idb_string_key.get(), script_object, "bar"); @@ -284,18 +268,14 @@ TEST(InjectIDBKeyTest, SubProperty) { V8TestingScope scope; - v8::Isolate* isolate = scope.GetIsolate(); + ScriptState* script_state = scope.GetScriptState(); // object = { foo: { bar: "zee" } } - v8::Local<v8::Object> object = v8::Object::New(isolate); - v8::Local<v8::Object> sub_property = v8::Object::New(isolate); - ASSERT_TRUE(V8CallBoolean(sub_property->Set(scope.GetContext(), - V8AtomicString(isolate, "bar"), - V8AtomicString(isolate, "zee")))); - ASSERT_TRUE(V8CallBoolean(object->Set( - scope.GetContext(), V8AtomicString(isolate, "foo"), sub_property))); + ScriptValue script_object = + V8ObjectBuilder(script_state) + .Add("foo", V8ObjectBuilder(script_state).Add("bar", "zee")) + .GetScriptValue(); - ScriptValue script_object(scope.GetScriptState(), object); std::unique_ptr<IDBKey> idb_string_key = IDBKey::CreateString("myNewKey"); CheckInjection(scope.GetScriptState(), idb_string_key.get(), script_object, "foo.baz");
diff --git a/third_party/blink/renderer/bindings/scripts/v8_types.py b/third_party/blink/renderer/bindings/scripts/v8_types.py index 033ac59a..7ea42f9b 100644 --- a/third_party/blink/renderer/bindings/scripts/v8_types.py +++ b/third_party/blink/renderer/bindings/scripts/v8_types.py
@@ -1038,7 +1038,6 @@ 'unrestricted float': 'v8::Number::New({isolate}, {cpp_value})', 'double': 'v8::Number::New({isolate}, {cpp_value})', 'unrestricted double': 'v8::Number::New({isolate}, {cpp_value})', - 'void': 'v8Undefined()', 'StringOrNull': '{cpp_value}.IsNull() ? v8::Local<v8::Value>(v8::Null({isolate})) : V8String({isolate}, {cpp_value})', # Special cases 'Dictionary': '{cpp_value}.V8Value()',
diff --git a/third_party/blink/renderer/bindings/templates/methods.cc.tmpl b/third_party/blink/renderer/bindings/templates/methods.cc.tmpl index 534bc0f1..622221c 100644 --- a/third_party/blink/renderer/bindings/templates/methods.cc.tmpl +++ b/third_party/blink/renderer/bindings/templates/methods.cc.tmpl
@@ -535,7 +535,7 @@ v8::Local<v8::FunctionTemplate> interfaceTemplate = data->FindInterfaceTemplate(world, &{{v8_class}}::wrapperTypeInfo); v8::Local<v8::Signature> signature = v8::Signature::New(info.GetIsolate(), interfaceTemplate); - v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, {{v8_class_or_partial}}::{{method.name}}MethodCallback{{world_suffix}}, V8Undefined(), signature, {{method.length}}); + v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, {{v8_class_or_partial}}::{{method.name}}MethodCallback{{world_suffix}}, v8::Local<v8::Value>(), signature, {{method.length}}); // Return the function by default, unless the user script has overwritten it. V8SetReturnValue(info, methodTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked());
diff --git a/third_party/blink/renderer/bindings/tests/idls/core/test_dictionary.idl b/third_party/blink/renderer/bindings/tests/idls/core/test_dictionary.idl index 0ec4913..dffbfbe 100644 --- a/third_party/blink/renderer/bindings/tests/idls/core/test_dictionary.idl +++ b/third_party/blink/renderer/bindings/tests/idls/core/test_dictionary.idl
@@ -7,7 +7,7 @@ long longMember = 1; DOMString stringMember; TestInterface testInterfaceMember; - [TreatNullAs=EmptyString] ByteString byteStringMember; + [TreatNullAs=EmptyString] DOMString domStringTreatNullAsEmptyStringMember; USVString? usvStringOrNullMember = null; double? doubleOrNullMember = null; double restrictedDoubleMember = 3.14;
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h index bbb52642..672b330 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h +++ b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h
@@ -81,12 +81,6 @@ } inline void setBooleanMember(bool); - bool hasByteStringMember() const { return !byte_string_member_.IsNull(); } - const String& byteStringMember() const { - return byte_string_member_; - } - inline void setByteStringMember(const String&); - bool hasCallbackFunctionMember() const { return callback_function_member_; } V8VoidCallbackFunction* callbackFunctionMember() const { return callback_function_member_; @@ -106,6 +100,12 @@ } void setDictionaryMember(Dictionary); + bool hasDomStringTreatNullAsEmptyStringMember() const { return !dom_string_treat_null_as_empty_string_member_.IsNull(); } + const String& domStringTreatNullAsEmptyStringMember() const { + return dom_string_treat_null_as_empty_string_member_; + } + inline void setDomStringTreatNullAsEmptyStringMember(const String&); + bool hasDoubleOrNullMember() const { return has_double_or_null_member_; } double doubleOrNullMember() const { DCHECK(has_double_or_null_member_); @@ -485,10 +485,10 @@ int32_t applicable_to_type_long_member_; String applicable_to_type_string_member_; bool boolean_member_; - String byte_string_member_; TraceWrapperMember<V8VoidCallbackFunction> callback_function_member_; bool create_member_; Dictionary dictionary_member_; + String dom_string_treat_null_as_empty_string_member_; double double_or_null_member_; DoubleOrDoubleOrNullSequence double_or_null_or_double_or_null_sequence_member_; Vector<std::pair<String, base::Optional<double>>> double_or_null_record_member_; @@ -557,15 +557,15 @@ has_boolean_member_ = true; } -void TestDictionary::setByteStringMember(const String& value) { - byte_string_member_ = value; -} - void TestDictionary::setCreateMember(bool value) { create_member_ = value; has_create_member_ = true; } +void TestDictionary::setDomStringTreatNullAsEmptyStringMember(const String& value) { + dom_string_treat_null_as_empty_string_member_ = value; +} + void TestDictionary::setDoubleOrNullMember(double value) { double_or_null_member_ = value; has_double_or_null_member_ = true;
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc index 0515654..41b432a 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc
@@ -40,11 +40,11 @@ "applicableToTypeLongMember", "applicableToTypeStringMember", "booleanMember", - "byteStringMember", "callbackFunctionMember", "create", "deprecatedCreateMember", "dictionaryMember", + "domStringTreatNullAsEmptyStringMember", "doubleOrNullMember", "doubleOrNullOrDoubleOrNullSequenceMember", "doubleOrNullRecordMember", @@ -185,22 +185,8 @@ impl.setBooleanMember(boolean_member_cpp_value); } - v8::Local<v8::Value> byte_string_member_value; - if (!v8Object->Get(context, keys[5].Get(isolate)).ToLocal(&byte_string_member_value)) { - exceptionState.RethrowV8Exception(block.Exception()); - return; - } - if (byte_string_member_value.IsEmpty() || byte_string_member_value->IsUndefined()) { - // Do nothing. - } else { - V8StringResource<kTreatNullAsEmptyString> byte_string_member_cpp_value = NativeValueTraits<IDLByteStringBase<kTreatNullAsEmptyString>>::NativeValue(isolate, byte_string_member_value, exceptionState); - if (exceptionState.HadException()) - return; - impl.setByteStringMember(byte_string_member_cpp_value); - } - v8::Local<v8::Value> callback_function_member_value; - if (!v8Object->Get(context, keys[6].Get(isolate)).ToLocal(&callback_function_member_value)) { + if (!v8Object->Get(context, keys[5].Get(isolate)).ToLocal(&callback_function_member_value)) { exceptionState.RethrowV8Exception(block.Exception()); return; } @@ -212,7 +198,7 @@ } v8::Local<v8::Value> create_value; - if (!v8Object->Get(context, keys[7].Get(isolate)).ToLocal(&create_value)) { + if (!v8Object->Get(context, keys[6].Get(isolate)).ToLocal(&create_value)) { exceptionState.RethrowV8Exception(block.Exception()); return; } @@ -226,7 +212,7 @@ } v8::Local<v8::Value> deprecated_create_member_value; - if (!v8Object->Get(context, keys[8].Get(isolate)).ToLocal(&deprecated_create_member_value)) { + if (!v8Object->Get(context, keys[7].Get(isolate)).ToLocal(&deprecated_create_member_value)) { exceptionState.RethrowV8Exception(block.Exception()); return; } @@ -241,7 +227,7 @@ } v8::Local<v8::Value> dictionary_member_value; - if (!v8Object->Get(context, keys[9].Get(isolate)).ToLocal(&dictionary_member_value)) { + if (!v8Object->Get(context, keys[8].Get(isolate)).ToLocal(&dictionary_member_value)) { exceptionState.RethrowV8Exception(block.Exception()); return; } @@ -258,6 +244,20 @@ impl.setDictionaryMember(dictionary_member_cpp_value); } + v8::Local<v8::Value> dom_string_treat_null_as_empty_string_member_value; + if (!v8Object->Get(context, keys[9].Get(isolate)).ToLocal(&dom_string_treat_null_as_empty_string_member_value)) { + exceptionState.RethrowV8Exception(block.Exception()); + return; + } + if (dom_string_treat_null_as_empty_string_member_value.IsEmpty() || dom_string_treat_null_as_empty_string_member_value->IsUndefined()) { + // Do nothing. + } else { + V8StringResource<kTreatNullAsEmptyString> dom_string_treat_null_as_empty_string_member_cpp_value = dom_string_treat_null_as_empty_string_member_value; + if (!dom_string_treat_null_as_empty_string_member_cpp_value.Prepare(exceptionState)) + return; + impl.setDomStringTreatNullAsEmptyStringMember(dom_string_treat_null_as_empty_string_member_cpp_value); + } + v8::Local<v8::Value> double_or_null_member_value; if (!v8Object->Get(context, keys[10].Get(isolate)).ToLocal(&double_or_null_member_value)) { exceptionState.RethrowV8Exception(block.Exception()); @@ -1104,17 +1104,6 @@ return false; } - v8::Local<v8::Value> byte_string_member_value; - bool byte_string_member_has_value_or_default = false; - if (impl.hasByteStringMember()) { - byte_string_member_value = V8String(isolate, impl.byteStringMember()); - byte_string_member_has_value_or_default = true; - } - if (byte_string_member_has_value_or_default && - !create_property(5, byte_string_member_value)) { - return false; - } - v8::Local<v8::Value> callback_function_member_value; bool callback_function_member_has_value_or_default = false; if (impl.hasCallbackFunctionMember()) { @@ -1122,7 +1111,7 @@ callback_function_member_has_value_or_default = true; } if (callback_function_member_has_value_or_default && - !create_property(6, callback_function_member_value)) { + !create_property(5, callback_function_member_value)) { return false; } @@ -1133,7 +1122,7 @@ create_has_value_or_default = true; } if (create_has_value_or_default && - !create_property(7, create_value)) { + !create_property(6, create_value)) { return false; } @@ -1144,7 +1133,7 @@ deprecated_create_member_has_value_or_default = true; } if (deprecated_create_member_has_value_or_default && - !create_property(8, deprecated_create_member_value)) { + !create_property(7, deprecated_create_member_value)) { return false; } @@ -1156,7 +1145,18 @@ dictionary_member_has_value_or_default = true; } if (dictionary_member_has_value_or_default && - !create_property(9, dictionary_member_value)) { + !create_property(8, dictionary_member_value)) { + return false; + } + + v8::Local<v8::Value> dom_string_treat_null_as_empty_string_member_value; + bool dom_string_treat_null_as_empty_string_member_has_value_or_default = false; + if (impl.hasDomStringTreatNullAsEmptyStringMember()) { + dom_string_treat_null_as_empty_string_member_value = V8String(isolate, impl.domStringTreatNullAsEmptyStringMember()); + dom_string_treat_null_as_empty_string_member_has_value_or_default = true; + } + if (dom_string_treat_null_as_empty_string_member_has_value_or_default && + !create_property(9, dom_string_treat_null_as_empty_string_member_value)) { return false; }
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc index 78d201b1..72446be 100644 --- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc +++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_interface_check_security.cc
@@ -191,7 +191,7 @@ v8::Local<v8::FunctionTemplate> interfaceTemplate = data->FindInterfaceTemplate(world, &V8TestInterfaceCheckSecurity::wrapperTypeInfo); v8::Local<v8::Signature> signature = v8::Signature::New(info.GetIsolate(), interfaceTemplate); - v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, V8TestInterfaceCheckSecurity::doNotCheckSecurityVoidMethodMethodCallback, V8Undefined(), signature, 0); + v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, V8TestInterfaceCheckSecurity::doNotCheckSecurityVoidMethodMethodCallback, v8::Local<v8::Value>(), signature, 0); // Return the function by default, unless the user script has overwritten it. V8SetReturnValue(info, methodTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked()); @@ -223,7 +223,7 @@ v8::Local<v8::FunctionTemplate> interfaceTemplate = data->FindInterfaceTemplate(world, &V8TestInterfaceCheckSecurity::wrapperTypeInfo); v8::Local<v8::Signature> signature = v8::Signature::New(info.GetIsolate(), interfaceTemplate); - v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, V8TestInterfaceCheckSecurity::doNotCheckSecurityPerWorldBindingsVoidMethodMethodCallback, V8Undefined(), signature, 0); + v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, V8TestInterfaceCheckSecurity::doNotCheckSecurityPerWorldBindingsVoidMethodMethodCallback, v8::Local<v8::Value>(), signature, 0); // Return the function by default, unless the user script has overwritten it. V8SetReturnValue(info, methodTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked()); @@ -255,7 +255,7 @@ v8::Local<v8::FunctionTemplate> interfaceTemplate = data->FindInterfaceTemplate(world, &V8TestInterfaceCheckSecurity::wrapperTypeInfo); v8::Local<v8::Signature> signature = v8::Signature::New(info.GetIsolate(), interfaceTemplate); - v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, V8TestInterfaceCheckSecurity::doNotCheckSecurityPerWorldBindingsVoidMethodMethodCallbackForMainWorld, V8Undefined(), signature, 0); + v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, V8TestInterfaceCheckSecurity::doNotCheckSecurityPerWorldBindingsVoidMethodMethodCallbackForMainWorld, v8::Local<v8::Value>(), signature, 0); // Return the function by default, unless the user script has overwritten it. V8SetReturnValue(info, methodTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked()); @@ -287,7 +287,7 @@ v8::Local<v8::FunctionTemplate> interfaceTemplate = data->FindInterfaceTemplate(world, &V8TestInterfaceCheckSecurity::wrapperTypeInfo); v8::Local<v8::Signature> signature = v8::Signature::New(info.GetIsolate(), interfaceTemplate); - v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, V8TestInterfaceCheckSecurity::doNotCheckSecurityUnforgeableVoidMethodMethodCallback, V8Undefined(), signature, 0); + v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, V8TestInterfaceCheckSecurity::doNotCheckSecurityUnforgeableVoidMethodMethodCallback, v8::Local<v8::Value>(), signature, 0); // Return the function by default, unless the user script has overwritten it. V8SetReturnValue(info, methodTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked()); @@ -414,7 +414,7 @@ v8::Local<v8::FunctionTemplate> interfaceTemplate = data->FindInterfaceTemplate(world, &V8TestInterfaceCheckSecurity::wrapperTypeInfo); v8::Local<v8::Signature> signature = v8::Signature::New(info.GetIsolate(), interfaceTemplate); - v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, V8TestInterfaceCheckSecurity::doNotCheckSecurityVoidOverloadMethodMethodCallback, V8Undefined(), signature, test_interface_check_security_v8_internal::doNotCheckSecurityVoidOverloadMethodMethodLength()); + v8::Local<v8::FunctionTemplate> methodTemplate = data->FindOrCreateOperationTemplate(world, &domTemplateKey, V8TestInterfaceCheckSecurity::doNotCheckSecurityVoidOverloadMethodMethodCallback, v8::Local<v8::Value>(), signature, test_interface_check_security_v8_internal::doNotCheckSecurityVoidOverloadMethodMethodLength()); // Return the function by default, unless the user script has overwritten it. V8SetReturnValue(info, methodTemplate->GetFunction(info.GetIsolate()->GetCurrentContext()).ToLocalChecked());
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl index 544645b..5ff29d8 100644 --- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
@@ -161,7 +161,7 @@ const NinePieceImage& current_image = state.Style()->{{getter}}(); {# Check for equality in case we can bail out before creating a new NinePieceImage. #} {% if modifier_type == 'Outset' %} - if (StyleBuildingUtils::BorderImageLengthMatchesAllSides(current_image.Outset(), + if (style_building_utils::BorderImageLengthMatchesAllSides(current_image.Outset(), BorderImageLength(Length(0, kFixed)))) return; {% elif modifier_type == 'Repeat' %} @@ -172,20 +172,20 @@ // Masks have a different initial value for slices. Preserve the value of 0 // for backwards compatibility. if (current_image.Fill() == true && - StyleBuildingUtils::LengthMatchesAllSides(current_image.ImageSlices(), Length(0, kFixed))) + style_building_utils::LengthMatchesAllSides(current_image.ImageSlices(), Length(0, kFixed))) return; {% elif modifier_type == 'Slice' and not is_mask_box %} if (current_image.Fill() == false && - StyleBuildingUtils::LengthMatchesAllSides(current_image.ImageSlices(), Length(100, kPercent))) + style_building_utils::LengthMatchesAllSides(current_image.ImageSlices(), Length(100, kPercent))) return; {% elif modifier_type == 'Width' and is_mask_box %} // Masks have a different initial value for widths. Preserve the value of // 'auto' for backwards compatibility. - if (StyleBuildingUtils::BorderImageLengthMatchesAllSides(current_image.BorderSlices(), + if (style_building_utils::BorderImageLengthMatchesAllSides(current_image.BorderSlices(), BorderImageLength(Length(kAuto)))) return; {% elif modifier_type == 'Width' and not is_mask_box %} - if (StyleBuildingUtils::BorderImageLengthMatchesAllSides(current_image.BorderSlices(), + if (style_building_utils::BorderImageLengthMatchesAllSides(current_image.BorderSlices(), BorderImageLength(1.0))) return; {% endif %}
diff --git a/third_party/blink/renderer/controller/blink_initializer.cc b/third_party/blink/renderer/controller/blink_initializer.cc index 90ff552..e3a3468 100644 --- a/third_party/blink/renderer/controller/blink_initializer.cc +++ b/third_party/blink/renderer/controller/blink_initializer.cc
@@ -67,8 +67,10 @@ class EndOfTaskRunner : public Thread::TaskObserver { public: - void WillProcessTask() override { AnimationClock::NotifyTaskStart(); } - void DidProcessTask() override { + void WillProcessTask(const base::PendingTask&) override { + AnimationClock::NotifyTaskStart(); + } + void DidProcessTask(const base::PendingTask&) override { Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate()); V8Initializer::ReportRejectedPromisesOnMainThread(); }
diff --git a/third_party/blink/renderer/core/core_initializer.cc b/third_party/blink/renderer/core/core_initializer.cc index 34bc385..e85c717 100644 --- a/third_party/blink/renderer/core/core_initializer.cc +++ b/third_party/blink/renderer/core/core_initializer.cc
@@ -101,7 +101,7 @@ HTMLTokenizerNames::kNamesCount + HTTPNames::kNamesCount + InputModeNames::kNamesCount + InputTypeNames::kNamesCount + MediaFeatureNames::kNamesCount + MediaTypeNames::kNamesCount + - PerformanceEntryNames::kNamesCount; + performance_entry_names::kNamesCount; StringImpl::ReserveStaticStringsCapacityForSize( kCoreStaticStringsCount + StringImpl::AllStaticStrings().size()); @@ -127,7 +127,7 @@ InputTypeNames::init(); MediaFeatureNames::init(); MediaTypeNames::init(); - PerformanceEntryNames::init(); + performance_entry_names::init(); MediaQueryEvaluator::Init(); CSSParserTokenRange::InitStaticEOFToken();
diff --git a/third_party/blink/renderer/core/css/css_style_declaration.idl b/third_party/blink/renderer/core/css/css_style_declaration.idl index 1eebf5e..934c1c9 100644 --- a/third_party/blink/renderer/core/css/css_style_declaration.idl +++ b/third_party/blink/renderer/core/css/css_style_declaration.idl
@@ -33,7 +33,7 @@ // void setPropertyPriority(DOMString property, [TreatNullAs=EmptyString] DOMString priority); [CEReactions, RaisesException] DOMString removeProperty(DOMString property); readonly attribute CSSRule? parentRule; - [CEReactions, SetterCallWith=ExecutionContext, RaisesException=Setter, TreatNullAs=EmptyString] attribute DOMString cssFloat; + [CEReactions, SetterCallWith=ExecutionContext, RaisesException=Setter] attribute [TreatNullAs=EmptyString] DOMString cssFloat; // The camel-cased and dashed attribute getters have custom bindings. // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-camel-cased-attribute
diff --git a/third_party/blink/renderer/core/css/properties/style_building_utils.h b/third_party/blink/renderer/core/css/properties/style_building_utils.h index 744eef1f..730c294 100644 --- a/third_party/blink/renderer/core/css/properties/style_building_utils.h +++ b/third_party/blink/renderer/core/css/properties/style_building_utils.h
@@ -11,7 +11,7 @@ #include "third_party/blink/renderer/platform/geometry/length_box.h" namespace blink { -namespace StyleBuildingUtils { +namespace style_building_utils { inline bool BorderImageLengthMatchesAllSides( const BorderImageLengthBox& border_image_length_box, @@ -27,7 +27,7 @@ length_box.Top() == length && length_box.Bottom() == length); } -} // namespace StyleBuildingUtils +} // namespace style_building_utils } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PROPERTIES_STYLE_BUILDING_UTILS_H_
diff --git a/third_party/blink/renderer/core/css/rule_feature_set_test.cc b/third_party/blink/renderer/core/css/rule_feature_set_test.cc index 1d77034..9896470 100644 --- a/third_party/blink/renderer/core/css/rule_feature_set_test.cc +++ b/third_party/blink/renderer/core/css/rule_feature_set_test.cc
@@ -51,8 +51,9 @@ RuleFeatureSet::SelectorPreMatch result = RuleFeatureSet::SelectorPreMatch::kSelectorNeverMatches; for (unsigned i = 0; i < indices.size(); ++i) { - RuleData* rule_data = - new RuleData(style_rule, indices[i], 0, kRuleHasNoSpecialState); + RuleData* rule_data = RuleData::MaybeCreate(style_rule, indices[i], 0, + kRuleHasNoSpecialState); + DCHECK(rule_data); if (rule_feature_set_.CollectFeaturesFromRuleData(rule_data)) result = RuleFeatureSet::SelectorPreMatch::kSelectorMayMatch; }
diff --git a/third_party/blink/renderer/core/css/rule_set.cc b/third_party/blink/renderer/core/css/rule_set.cc index 0233c8a..b40527e 100644 --- a/third_party/blink/renderer/core/css/rule_set.cc +++ b/third_party/blink/renderer/core/css/rule_set.cc
@@ -63,6 +63,20 @@ return kPropertyWhitelistNone; } +RuleData* RuleData::MaybeCreate(StyleRule* rule, + unsigned selector_index, + unsigned position, + AddRuleFlags add_rule_flags) { + // The selector index field in RuleData is only 13 bits so we can't support + // selectors at index 8192 or beyond. + // See https://crbug.com/804179 + if (selector_index >= (1 << RuleData::kSelectorIndexBits)) + return nullptr; + if (position >= (1 << RuleData::kPositionBits)) + return nullptr; + return new RuleData(rule, selector_index, position, add_rule_flags); +} + RuleData::RuleData(StyleRule* rule, unsigned selector_index, unsigned position, @@ -228,13 +242,13 @@ void RuleSet::AddRule(StyleRule* rule, unsigned selector_index, AddRuleFlags add_rule_flags) { - // The selector index field in RuleData is only 13 bits so we can't support - // selectors at index 8192 or beyond. - // See https://crbug.com/804179 - if (selector_index >= 8192) - return; RuleData* rule_data = - new RuleData(rule, selector_index, rule_count_++, add_rule_flags); + RuleData::MaybeCreate(rule, selector_index, rule_count_, add_rule_flags); + if (!rule_data) { + // This can happen if selector_index or position is out of range. + return; + } + ++rule_count_; if (features_.CollectFeaturesFromRuleData(rule_data) == RuleFeatureSet::kSelectorNeverMatches) return;
diff --git a/third_party/blink/renderer/core/css/rule_set.h b/third_party/blink/renderer/core/css/rule_set.h index 44d4da9..4af5515 100644 --- a/third_party/blink/renderer/core/css/rule_set.h +++ b/third_party/blink/renderer/core/css/rule_set.h
@@ -79,10 +79,10 @@ // and makes it accessible cheaply. class CORE_EXPORT RuleData : public GarbageCollected<RuleData> { public: - RuleData(StyleRule*, - unsigned selector_index, - unsigned position, - AddRuleFlags); + static RuleData* MaybeCreate(StyleRule*, + unsigned selector_index, + unsigned position, + AddRuleFlags); unsigned GetPosition() const { return position_; } StyleRule* Rule() const { return rule_; } @@ -114,16 +114,25 @@ void Trace(blink::Visitor*); - private: - Member<StyleRule> rule_; // This number is picked fairly arbitrary. If lowered, be aware that there // might be sites and extensions using style rules with selector lists // exceeding the number of simple selectors to fit in this bitfield. // See https://crbug.com/312913 and https://crbug.com/704562 - unsigned selector_index_ : 13; + static constexpr size_t kSelectorIndexBits = 13; + // This number was picked fairly arbitrarily. We can probably lower it if we // need to. Some simple testing showed <100,000 RuleData's on large sites. - unsigned position_ : 18; + static constexpr size_t kPositionBits = 18; + + private: + RuleData(StyleRule*, + unsigned selector_index, + unsigned position, + AddRuleFlags); + + Member<StyleRule> rule_; + unsigned selector_index_ : kSelectorIndexBits; + unsigned position_ : kPositionBits; unsigned contains_uncommon_attribute_selector_ : 1; // 32 bits above unsigned specificity_ : 24;
diff --git a/third_party/blink/renderer/core/css/rule_set_test.cc b/third_party/blink/renderer/core/css/rule_set_test.cc index 511e351..4223f97 100644 --- a/third_party/blink/renderer/core/css/rule_set_test.cc +++ b/third_party/blink/renderer/core/css/rule_set_test.cc
@@ -35,6 +35,19 @@ namespace blink { +namespace { + +StyleRule* CreateDummyStyleRule() { + CSSTestHelper helper; + helper.AddCSSRules("#id { color: tomato; }"); + const RuleSet& rule_set = helper.GetRuleSet(); + const HeapVector<Member<const RuleData>>* rules = rule_set.IdRules("id"); + DCHECK_EQ(1u, rules->size()); + return rules->at(0)->Rule(); +} + +} // namespace + TEST(RuleSetTest, findBestRuleSetAndAdd_CustomPseudoElements) { CSSTestHelper helper; @@ -328,6 +341,13 @@ } TEST(RuleSetTest, SelectorIndexLimit) { + // It's not feasible to run this test for a large number of bits. If the + // number of bits have increased to a large number, consider removing this + // test and making do with RuleSetTest.RuleDataSelectorIndexLimit. + static_assert( + RuleData::kSelectorIndexBits == 13, + "Please manually consider whether this test should be removed."); + StringBuilder builder; // We use 13 bits to storing the selector start index in RuleData. This is a @@ -347,4 +367,42 @@ EXPECT_FALSE(rule_set.TagRules("span")); } +TEST(RuleSetTest, RuleDataSelectorIndexLimit) { + StyleRule* rule = CreateDummyStyleRule(); + AddRuleFlags flags = kRuleHasNoSpecialState; + const unsigned position = 0; + EXPECT_TRUE(RuleData::MaybeCreate(rule, 0, position, flags)); + EXPECT_FALSE(RuleData::MaybeCreate(rule, (1 << RuleData::kSelectorIndexBits), + position, flags)); + EXPECT_FALSE(RuleData::MaybeCreate( + rule, (1 << RuleData::kSelectorIndexBits) + 1, position, flags)); +} + +TEST(RuleSetTest, RuleDataPositionLimit) { + StyleRule* rule = CreateDummyStyleRule(); + AddRuleFlags flags = kRuleHasNoSpecialState; + const unsigned selector_index = 0; + EXPECT_TRUE(RuleData::MaybeCreate(rule, selector_index, 0, flags)); + EXPECT_FALSE(RuleData::MaybeCreate(rule, selector_index, + (1 << RuleData::kPositionBits), flags)); + EXPECT_FALSE(RuleData::MaybeCreate( + rule, selector_index, (1 << RuleData::kPositionBits) + 1, flags)); +} + +TEST(RuleSetTest, RuleCountNotIncreasedByInvalidRuleData) { + RuleSet* rule_set = RuleSet::Create(); + EXPECT_EQ(0u, rule_set->RuleCount()); + + AddRuleFlags flags = kRuleHasNoSpecialState; + StyleRule* rule = CreateDummyStyleRule(); + + // Add with valid selector_index=0. + rule_set->AddRule(rule, 0, flags); + EXPECT_EQ(1u, rule_set->RuleCount()); + + // Adding with invalid selector_index should not lead to a change in count. + rule_set->AddRule(rule, 1 << RuleData::kSelectorIndexBits, flags); + EXPECT_EQ(1u, rule_set->RuleCount()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 6f94f81a..5e947da 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -1999,7 +1999,8 @@ void Document::PropagateStyleToViewport() { DCHECK(InStyleRecalc()); - DCHECK(documentElement()); + if (!documentElement()) + return; HTMLElement* body = this->body(); @@ -2348,7 +2349,6 @@ ViewportDefiningElementDidChange(); } GetStyleEngine().MarkForWhitespaceReattachment(); - PropagateStyleToViewport(); if (document_element->NeedsReattachLayoutTree() || document_element->ChildNeedsReattachLayoutTree()) { TRACE_EVENT0("blink,blink_style", "Document::rebuildLayoutTree"); @@ -2359,13 +2359,13 @@ } } GetStyleEngine().ClearWhitespaceReattachSet(); - - View()->UpdateCountersAfterStyleChange(); - GetLayoutView()->RecalcOverflow(); - ClearChildNeedsStyleRecalc(); ClearChildNeedsReattachLayoutTree(); + PropagateStyleToViewport(); + View()->UpdateCountersAfterStyleChange(); + GetLayoutView()->RecalcOverflow(); + DCHECK(!NeedsStyleRecalc()); DCHECK(!ChildNeedsStyleRecalc()); DCHECK(!NeedsReattachLayoutTree());
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 2d2ea21d..ade9ff25 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -601,7 +601,7 @@ NOTREACHED(); } - // If you have a Document, use layoutView() instead which is faster. + // If you have a Document, use GetLayoutView() instead which is faster. void GetLayoutObject() const = delete; LayoutView* GetLayoutView() const { return layout_view_; }
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 9062818..97c4071 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3714,6 +3714,16 @@ return nullptr; } + // EnsureComputedStyle is expected to be called to forcibly compute style for + // elements in display:none subtrees on otherwise style-clean documents. If + // you hit this DCHECK, consider if you really need ComputedStyle for + // display:none elements. If not, use GetComputedStyle() instead. + // Regardlessly, you need to UpdateStyleAndLayoutTree() before calling + // EnsureComputedStyle. In some cases you might be fine using GetComputedStyle + // without updating the style, but in most cases you want a clean tree for + // that as well. + DCHECK(!GetDocument().NeedsLayoutTreeUpdateForNode(*this)); + // FIXME: Find and use the layoutObject from the pseudo element instead of the // actual element so that the 'length' properties, which are only known by the // layoutObject because it did the layout, will be correct and so that the
diff --git a/third_party/blink/renderer/core/dom/idle_deadline_test.cc b/third_party/blink/renderer/core/dom/idle_deadline_test.cc index 9e5073b8..5c04f0f 100644 --- a/third_party/blink/renderer/core/dom/idle_deadline_test.cc +++ b/third_party/blink/renderer/core/dom/idle_deadline_test.cc
@@ -48,11 +48,9 @@ return base::TimeTicks(); } - void AddTaskObserver( - base::MessageLoop::TaskObserver* task_observer) override {} + void AddTaskObserver(Thread::TaskObserver* task_observer) override {} - void RemoveTaskObserver( - base::MessageLoop::TaskObserver* task_observer) override {} + void RemoveTaskObserver(Thread::TaskObserver* task_observer) override {} void AddRAILModeObserver(scheduler::WebRAILModeObserver*) override {}
diff --git a/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc b/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc index 52bb88766..7195961 100644 --- a/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc +++ b/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc
@@ -55,11 +55,9 @@ return base::TimeTicks(); } - void AddTaskObserver( - base::MessageLoop::TaskObserver* task_observer) override {} + void AddTaskObserver(Thread::TaskObserver* task_observer) override {} - void RemoveTaskObserver( - base::MessageLoop::TaskObserver* task_observer) override {} + void RemoveTaskObserver(Thread::TaskObserver* task_observer) override {} void AddRAILModeObserver(scheduler::WebRAILModeObserver*) override {}
diff --git a/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc b/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc index 0a4cfbb..1b6aeb6 100644 --- a/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc +++ b/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
@@ -742,7 +742,7 @@ gfx::Vector2dF elastic_overscroll(10, -20); web_view->ApplyViewportChanges( - {gfx::Vector2dF(), elastic_overscroll, 1.0f, 0.0f}); + {gfx::ScrollOffset(), elastic_overscroll, 1.0f, 0.0f}); // Just elastic overscroll. { @@ -815,7 +815,7 @@ gfx::Vector2dF elastic_overscroll(10, -20); web_view->ApplyViewportChanges( - {gfx::Vector2dF(), elastic_overscroll, 1.0f, 0.0f}); + {gfx::ScrollOffset(), elastic_overscroll, 1.0f, 0.0f}); frame_test_helpers::ReloadFrame( web_view_helper.GetWebView()->MainFrameImpl()); LocalFrameView* view = ToLocalFrame(web_view->GetPage()->MainFrame())->View();
diff --git a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc index 1cce13f..6a45377 100644 --- a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc +++ b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.cc
@@ -476,13 +476,15 @@ agent_->FlushProtocolNotifications(); } -void WebDevToolsAgentImpl::WillProcessTask() { +void WebDevToolsAgentImpl::WillProcessTask( + const base::PendingTask& pending_task) { if (sessions_.IsEmpty()) return; ThreadDebugger::IdleFinished(V8PerIsolateData::MainThreadIsolate()); } -void WebDevToolsAgentImpl::DidProcessTask() { +void WebDevToolsAgentImpl::DidProcessTask( + const base::PendingTask& pending_task) { if (sessions_.IsEmpty()) return; ThreadDebugger::IdleStarted(V8PerIsolateData::MainThreadIsolate());
diff --git a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h index 45eae977..5a8ccedf 100644 --- a/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h +++ b/third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h
@@ -108,8 +108,8 @@ bool IsInspectorLayer(GraphicsLayer*) override; // Thread::TaskObserver implementation. - void WillProcessTask() override; - void DidProcessTask() override; + void WillProcessTask(const base::PendingTask&) override; + void DidProcessTask(const base::PendingTask&) override; Member<DevToolsAgent> agent_; HeapHashSet<Member<InspectorSession>> sessions_;
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index f98b4df4..12908cc 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -3436,7 +3436,7 @@ float scale_delta = web_view_impl->FakePageScaleAnimationPageScaleForTesting() / web_view_impl->PageScaleFactor(); - web_view_impl->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), + web_view_impl->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), scale_delta, 0, cc::BrowserControlsState::kBoth}); scale = web_view_impl->PageScaleFactor(); @@ -3628,7 +3628,7 @@ SimulateDoubleTap(web_view_helper.GetWebView(), top_point, scale); EXPECT_FLOAT_EQ(1, scale); web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 0.6f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 0.6f, 0, cc::BrowserControlsState::kBoth}); SimulateDoubleTap(web_view_helper.GetWebView(), bottom_point, scale); EXPECT_FLOAT_EQ(1, scale); @@ -3639,7 +3639,7 @@ // If we didn't yet get an auto-zoom update and a second double-tap arrives, // should go back to minimum scale. web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.1f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, 0, cc::BrowserControlsState::kBoth}); web_view_helper.GetWebView()->AnimateDoubleTapZoom(top_point); EXPECT_TRUE( @@ -3691,7 +3691,7 @@ // Zoom in to reset double_tap_zoom_in_effect flag. web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.1f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, 0, cc::BrowserControlsState::kBoth}); // 1 < minimumPageScale < doubleTapZoomAlreadyLegibleScale web_view_helper.GetWebView()->SetDefaultPageScaleLimits(1.1f, 4); @@ -3713,7 +3713,7 @@ // Zoom in to reset double_tap_zoom_in_effect flag. web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.1f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, 0, cc::BrowserControlsState::kBoth}); // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.95f, 4); @@ -3783,7 +3783,7 @@ // Zoom in to reset double_tap_zoom_in_effect flag. web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.1f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, 0, cc::BrowserControlsState::kBoth}); // 1 < maximumLegibleScaleFactor < minimumPageScale < // doubleTapZoomAlreadyLegibleScale @@ -3806,7 +3806,7 @@ // Zoom in to reset double_tap_zoom_in_effect flag. web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.1f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, 0, cc::BrowserControlsState::kBoth}); // minimumPageScale < 1 < maximumLegibleScaleFactor < // doubleTapZoomAlreadyLegibleScale @@ -3829,7 +3829,7 @@ // Zoom in to reset double_tap_zoom_in_effect flag. web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.1f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, 0, cc::BrowserControlsState::kBoth}); // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale < // maximumLegibleScaleFactor @@ -3903,7 +3903,7 @@ // Zoom in to reset double_tap_zoom_in_effect flag. web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.1f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, 0, cc::BrowserControlsState::kBoth}); // 1 < accessibilityFontScaleFactor < minimumPageScale < // doubleTapZoomAlreadyLegibleScale @@ -3926,7 +3926,7 @@ // Zoom in to reset double_tap_zoom_in_effect flag. web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.1f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, 0, cc::BrowserControlsState::kBoth}); // minimumPageScale < 1 < accessibilityFontScaleFactor < // doubleTapZoomAlreadyLegibleScale @@ -3949,7 +3949,7 @@ // Zoom in to reset double_tap_zoom_in_effect flag. web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.1f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.1f, 0, cc::BrowserControlsState::kBoth}); // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale < // accessibilityFontScaleFactor @@ -7264,7 +7264,7 @@ // Do a compositor scroll, verify that this is counted as a user scroll. scrollable_area->DidScroll(FloatPoint(0, 1)); web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.7f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.7f, 0, cc::BrowserControlsState::kBoth}); EXPECT_TRUE(client.WasFrameScrolled()); EXPECT_TRUE(initial_scroll_state.was_scrolled_by_user); @@ -7275,7 +7275,7 @@ // The page scale 1.0f and scroll. scrollable_area->DidScroll(FloatPoint(0, 2)); web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, 0, cc::BrowserControlsState::kBoth}); EXPECT_TRUE(client.WasFrameScrolled()); EXPECT_TRUE(initial_scroll_state.was_scrolled_by_user); @@ -7285,7 +7285,7 @@ // No scroll event if there is no scroll delta. scrollable_area->DidScroll(FloatPoint(0, 2)); web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, 0, cc::BrowserControlsState::kBoth}); EXPECT_FALSE(client.WasFrameScrolled()); EXPECT_FALSE(initial_scroll_state.was_scrolled_by_user); @@ -7294,7 +7294,7 @@ // Non zero page scale and scroll. scrollable_area->DidScroll(FloatPoint(9, 15)); web_view_helper.GetWebView()->ApplyViewportChanges( - {gfx::Vector2dF(), gfx::Vector2dF(), 0.6f, 0, + {gfx::ScrollOffset(), gfx::Vector2dF(), 0.6f, 0, cc::BrowserControlsState::kBoth}); EXPECT_TRUE(client.WasFrameScrolled()); EXPECT_TRUE(initial_scroll_state.was_scrolled_by_user); @@ -8117,14 +8117,14 @@ // Simulate the browser controls showing by 20px, thus shrinking the viewport // and allowing it to scroll an additional 20px. - web_view->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, + web_view->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, 20.0f / browser_controls_height, cc::BrowserControlsState::kBoth}); EXPECT_EQ(ScrollOffset(0, 1920), frame_view->LayoutViewport()->MaximumScrollOffset()); // Show more, make sure the scroll actually gets clamped. - web_view->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, + web_view->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, 20.0f / browser_controls_height, cc::BrowserControlsState::kBoth}); web_view->MainFrameImpl()->SetScrollOffset(WebSize(0, 2000)); @@ -8132,7 +8132,7 @@ frame_view->LayoutViewport()->GetScrollOffset()); // Hide until there's 10px showing. - web_view->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, + web_view->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, -30.0f / browser_controls_height, cc::BrowserControlsState::kBoth}); EXPECT_EQ(ScrollOffset(0, 1910), @@ -8141,7 +8141,7 @@ // Simulate a LayoutEmbeddedContent::resize. The frame is resized to // accomodate the browser controls and Blink's view of the browser controls // matches that of the CC - web_view->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, + web_view->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, 30.0f / browser_controls_height, cc::BrowserControlsState::kBoth}); web_view->ResizeWithBrowserControls(WebSize(100, 60), 40.0f, 0, true); @@ -8150,7 +8150,7 @@ frame_view->LayoutViewport()->MaximumScrollOffset()); // Now simulate hiding. - web_view->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, + web_view->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, -10.0f / browser_controls_height, cc::BrowserControlsState::kBoth}); EXPECT_EQ(ScrollOffset(0, 1930), @@ -8158,7 +8158,7 @@ // Reset to original state: 100px widget height, browser controls fully // hidden. - web_view->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, + web_view->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, -30.0f / browser_controls_height, cc::BrowserControlsState::kBoth}); web_view->ResizeWithBrowserControls(WebSize(100, 100), @@ -8171,13 +8171,13 @@ // should allow an extra 0.5px of scrolling in the visual viewport. Make // sure we're not losing any pixels when applying the adjustment on the // main frame. - web_view->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, + web_view->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, 1.0f / browser_controls_height, cc::BrowserControlsState::kBoth}); EXPECT_EQ(ScrollOffset(0, 1901), frame_view->LayoutViewport()->MaximumScrollOffset()); - web_view->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, + web_view->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, 2.0f / browser_controls_height, cc::BrowserControlsState::kBoth}); EXPECT_EQ(ScrollOffset(0, 1903),
diff --git a/third_party/blink/renderer/core/frame/frame_test.cc b/third_party/blink/renderer/core/frame/frame_test.cc index da0c1e3..c3afdf2 100644 --- a/third_party/blink/renderer/core/frame/frame_test.cc +++ b/third_party/blink/renderer/core/frame/frame_test.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/core/frame/frame.h" -#include "base/test/metrics/histogram_tester.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/loader/document_loader.h" @@ -190,33 +189,4 @@ LocalFrame::ConsumeTransientUserActivation(GetDocument().GetFrame())); } -TEST_F(FrameTest, UserActivationHistograms) { - RuntimeEnabledFeatures::SetUserActivationV2Enabled(true); - base::HistogramTester histograms; - - LocalFrame::HasTransientUserActivation(GetDocument().GetFrame()); - histograms.ExpectBucketCount("UserActivation.AvailabilityCheck.FrameResult", - 0, 1); - - LocalFrame::ConsumeTransientUserActivation(GetDocument().GetFrame()); - histograms.ExpectBucketCount("UserActivation.Consumption.FrameResult", 0, 1); - - LocalFrame::NotifyUserActivation(GetDocument().GetFrame()); - - LocalFrame::HasTransientUserActivation(GetDocument().GetFrame()); - LocalFrame::HasTransientUserActivation(GetDocument().GetFrame()); - histograms.ExpectBucketCount("UserActivation.AvailabilityCheck.FrameResult", - 3, 2); - - LocalFrame::ConsumeTransientUserActivation(GetDocument().GetFrame()); - histograms.ExpectBucketCount("UserActivation.Consumption.FrameResult", 3, 1); - - LocalFrame::ConsumeTransientUserActivation(GetDocument().GetFrame()); - histograms.ExpectBucketCount("UserActivation.Consumption.FrameResult", 0, 2); - - histograms.ExpectTotalCount("UserActivation.AvailabilityCheck.FrameResult", - 3); - histograms.ExpectTotalCount("UserActivation.Consumption.FrameResult", 3); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 7e2d796..65c604f4 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1463,45 +1463,10 @@ GetSecurityContext()->ReportFeaturePolicyViolation(feature); } -namespace { - -LocalFrame* user_activation_notifier_frame_ = nullptr; - -enum UserActivationFrameResultEnum { - kNullFailure = 0, - kNullSuccess = 1, - kSelfFailure = 2, - kSelfSuccess = 3, - kAncestorFailure = 4, - kAncestorSuccess = 5, - kDescendantFailure = 6, - kDescendantSuccess = 7, - kOtherFailure = 8, - kOtherSuccess = 9, - kMaxValue = kOtherSuccess -}; - -UserActivationFrameResultEnum determineFrameResultEnum( - const LocalFrame* const caller_frame, - const bool call_succeeded) { - if (!caller_frame || !user_activation_notifier_frame_) - return call_succeeded ? kNullSuccess : kNullFailure; - if (caller_frame == user_activation_notifier_frame_) - return call_succeeded ? kSelfSuccess : kSelfFailure; - if (user_activation_notifier_frame_->Tree().IsDescendantOf(caller_frame)) - return call_succeeded ? kAncestorSuccess : kAncestorFailure; - if (caller_frame->Tree().IsDescendantOf(user_activation_notifier_frame_)) - return call_succeeded ? kDescendantSuccess : kDescendantFailure; - return call_succeeded ? kOtherSuccess : kOtherFailure; -} - -} // namespace - // static std::unique_ptr<UserGestureIndicator> LocalFrame::NotifyUserActivation( LocalFrame* frame, UserGestureToken::Status status) { - user_activation_notifier_frame_ = frame; if (frame) frame->NotifyUserActivation(); return std::make_unique<UserGestureIndicator>(status); @@ -1512,7 +1477,6 @@ LocalFrame* frame, UserGestureToken* token) { DCHECK(!RuntimeEnabledFeatures::UserActivationV2Enabled()); - user_activation_notifier_frame_ = frame; if (frame) frame->NotifyUserActivation(); return std::make_unique<UserGestureIndicator>(token); @@ -1521,19 +1485,13 @@ // static bool LocalFrame::HasTransientUserActivation(LocalFrame* frame, bool check_if_main_thread) { - bool available; - if (RuntimeEnabledFeatures::UserActivationV2Enabled()) { - available = frame ? frame->HasTransientUserActivation() : false; - } else { - available = check_if_main_thread - ? UserGestureIndicator::ProcessingUserGestureThreadSafe() - : UserGestureIndicator::ProcessingUserGesture(); + return frame ? frame->HasTransientUserActivation() : false; } - UMA_HISTOGRAM_ENUMERATION("UserActivation.AvailabilityCheck.FrameResult", - determineFrameResultEnum(frame, available)); - return available; + return check_if_main_thread + ? UserGestureIndicator::ProcessingUserGestureThreadSafe() + : UserGestureIndicator::ProcessingUserGesture(); } // static @@ -1541,21 +1499,13 @@ LocalFrame* frame, bool check_if_main_thread, UserActivationUpdateSource update_source) { - bool consumed; - if (RuntimeEnabledFeatures::UserActivationV2Enabled()) { - consumed = - frame ? frame->ConsumeTransientUserActivation(update_source) : false; - } else { - consumed = check_if_main_thread - ? UserGestureIndicator::ConsumeUserGestureThreadSafe() - : UserGestureIndicator::ConsumeUserGesture(); + return frame ? frame->ConsumeTransientUserActivation(update_source) : false; } - UMA_HISTOGRAM_ENUMERATION("UserActivation.Consumption.FrameResult", - determineFrameResultEnum(frame, consumed)); - user_activation_notifier_frame_ = nullptr; - return consumed; + return check_if_main_thread + ? UserGestureIndicator::ConsumeUserGestureThreadSafe() + : UserGestureIndicator::ConsumeUserGesture(); } void LocalFrame::NotifyUserActivation() {
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.cc b/third_party/blink/renderer/core/frame/visual_viewport.cc index f72f6fec..071f9bd7 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport.cc
@@ -721,15 +721,6 @@ return &GetPage().GetChromeClient(); } -bool VisualViewport::ShouldUseIntegerScrollOffset() const { - LocalFrame* frame = MainFrame(); - if (frame && frame->GetSettings() && - !frame->GetSettings()->GetPreferCompositingToLCDTextEnabled()) - return true; - - return ScrollableArea::ShouldUseIntegerScrollOffset(); -} - void VisualViewport::SetScrollOffset(const ScrollOffset& offset, ScrollType scroll_type, ScrollBehavior scroll_behavior) {
diff --git a/third_party/blink/renderer/core/frame/visual_viewport.h b/third_party/blink/renderer/core/frame/visual_viewport.h index 4fe803da..9f1895e 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport.h +++ b/third_party/blink/renderer/core/frame/visual_viewport.h
@@ -186,7 +186,6 @@ // ScrollableArea implementation ChromeClient* GetChromeClient() const override; - bool ShouldUseIntegerScrollOffset() const override; void SetScrollOffset(const ScrollOffset&, ScrollType, ScrollBehavior = kScrollBehaviorInstant) override;
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc index 766bd84..a1e021d 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -1330,7 +1330,7 @@ EXPECT_EQ(IntSize(1000, 900), frame_view.FrameRect().Size()); // Simulate bringing down the browser controls by 20px. - WebView()->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1, 1, + WebView()->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1, 1, cc::BrowserControlsState::kBoth}); EXPECT_EQ(FloatSize(500, 430), visual_viewport.VisibleRect().Size()); @@ -1348,7 +1348,7 @@ frame_view.LayoutViewport()->GetScrollOffset()); // Simulate bringing up the browser controls by 10.5px. - WebView()->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1, + WebView()->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1, -10.5f / 20, cc::BrowserControlsState::kBoth}); EXPECT_FLOAT_SIZE_EQ(FloatSize(500, 440.5f), @@ -1384,7 +1384,7 @@ // Simulate bringing down the browser controls by 20px. Since we're zoomed in, // the browser controls take up half as much space (in document-space) than // they do at an unzoomed level. - WebView()->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1, 1, + WebView()->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1, 1, cc::BrowserControlsState::kBoth}); EXPECT_EQ(FloatSize(250, 215), visual_viewport.VisibleRect().Size()); @@ -1401,8 +1401,8 @@ // Scale back out, LocalFrameView max scroll shouldn't have changed. Visual // viewport should be moved up to accomodate larger view. - WebView()->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 0.5f, 0, - cc::BrowserControlsState::kBoth}); + WebView()->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 0.5f, + 0, cc::BrowserControlsState::kBoth}); EXPECT_EQ(1, visual_viewport.Scale()); EXPECT_EQ(expected, frame_view.LayoutViewport()->GetScrollOffset()); frame_view.LayoutViewport()->ScrollBy(ScrollOffset(10000, 10000), @@ -1414,12 +1414,12 @@ EXPECT_EQ(FloatSize(500, 860 - 430), visual_viewport.GetScrollOffset()); // Scale out, use a scale that causes fractional rects. - WebView()->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 0.8f, -1, - cc::BrowserControlsState::kBoth}); + WebView()->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 0.8f, + -1, cc::BrowserControlsState::kBoth}); EXPECT_EQ(FloatSize(625, 562.5), visual_viewport.VisibleRect().Size()); // Bring out the browser controls by 11 - WebView()->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1, + WebView()->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1, 11 / 20.f, cc::BrowserControlsState::kBoth}); EXPECT_EQ(FloatSize(625, 548.75), visual_viewport.VisibleRect().Size()); @@ -1586,7 +1586,7 @@ TEST_P(VisualViewportTest, TestTopControlHidingResizeDoesntClampMainFrame) { InitializeWithAndroidSettings(); WebView()->ResizeWithBrowserControls(WebView()->Size(), 500, 0, false); - WebView()->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1, 1, + WebView()->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1, 1, cc::BrowserControlsState::kBoth}); WebView()->ResizeWithBrowserControls(WebSize(1000, 1000), 500, 0, true); @@ -1597,7 +1597,7 @@ // Scroll the LocalFrameView to the bottom of the page but "hide" the browser // controls on the compositor side so the max scroll position should account // for the full viewport height. - WebView()->ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1, -1, + WebView()->ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1, -1, cc::BrowserControlsState::kBoth}); LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView(); frame_view.LayoutViewport()->SetScrollOffset(ScrollOffset(0, 10000), @@ -1872,7 +1872,7 @@ VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport(); // Apply some scroll and scale from the impl-side. - WebView()->ApplyViewportChanges({gfx::Vector2dF(300, 200), + WebView()->ApplyViewportChanges({gfx::ScrollOffset(300, 200), gfx::Vector2dF(0, 0), 2, 0, cc::BrowserControlsState::kBoth}); @@ -2502,8 +2502,8 @@ visual_viewport.GetScrollNode()->ContentsSize()); } - WebView().ApplyViewportChanges({gfx::Vector2dF(1, 1), gfx::Vector2dF(), 2, 1, - cc::BrowserControlsState::kBoth}); + WebView().ApplyViewportChanges({gfx::ScrollOffset(1, 1), gfx::Vector2dF(), 2, + 1, cc::BrowserControlsState::kBoth}); EXPECT_EQ(gfx::Size(400, 600), visual_viewport.ContainerLayer()->Size()); EXPECT_EQ(gfx::Size(400, 600), visual_viewport.ContainerLayer()->CcLayer()->bounds());
diff --git a/third_party/blink/renderer/core/frame/window.idl b/third_party/blink/renderer/core/frame/window.idl index b142a293c..0d0f6d4a 100644 --- a/third_party/blink/renderer/core/frame/window.idl +++ b/third_party/blink/renderer/core/frame/window.idl
@@ -74,7 +74,7 @@ [CrossOrigin, Custom=Setter] attribute Window opener; [Replaceable, CrossOrigin] readonly attribute Window? parent; [CheckSecurity=ReturnValue, Custom=Getter] readonly attribute Element? frameElement; - [CallWith=(ExecutionContext,CurrentWindow,EnteredWindow), RaisesException] Window? open(optional [TreatNullAs=EmptyString] URLString url="", optional DOMString target = "_blank", optional [TreatNullAs=EmptyString] DOMString features = ""); + [CallWith=(ExecutionContext,CurrentWindow,EnteredWindow), RaisesException] Window? open(optional URLString url="", optional DOMString target = "_blank", optional [TreatNullAs=EmptyString] DOMString features = ""); // indexed properties // https://html.spec.whatwg.org/C/browsers.html#windowproxy-getownproperty
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc index d58830a..61a1995c 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc
@@ -119,7 +119,7 @@ return parsed_style; } -void CanvasFontCache::DidProcessTask() { +void CanvasFontCache::DidProcessTask(const base::PendingTask& pending_task) { DCHECK(pruning_scheduled_); DCHECK(main_cache_purge_preventer_); while (fetched_fonts_.size() > MaxFonts()) {
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h index 70f148b..fc7dd5c7b 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h +++ b/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h
@@ -44,8 +44,8 @@ bool GetFontUsingDefaultStyle(const String&, Font&); // TaskObserver implementation - void DidProcessTask() override; - void WillProcessTask() override {} + void DidProcessTask(const base::PendingTask&) override; + void WillProcessTask(const base::PendingTask&) override {} // For testing bool IsInCache(const String&);
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc index 5d2afeb..aa8b1db 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
@@ -106,7 +106,7 @@ // When the pair is no longer reachable, their destruction order is non- // deterministic, so the first of the two to be destroyed needs to notify // the other in order to break the circular reference. This is to avoid - // an error when CanvasRenderingContext::didProcessTask() is invoked + // an error when CanvasRenderingContext::DidProcessTask() is invoked // after the HTMLCanvasElement is destroyed. if (Host()) { Host()->DetachContext(); @@ -131,7 +131,8 @@ } } -void CanvasRenderingContext::DidProcessTask() { +void CanvasRenderingContext::DidProcessTask( + const base::PendingTask& pending_task) { Platform::Current()->CurrentThread()->RemoveTaskObserver(this); finalize_frame_scheduled_ = false; // The end of a script task that drew content to the canvas is the point
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h index 461186f..9104d46d 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h +++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
@@ -138,8 +138,8 @@ void NeedsFinalizeFrame(); // Thread::TaskObserver implementation - void DidProcessTask() override; - void WillProcessTask() final {} + void DidProcessTask(const base::PendingTask&) override; + void WillProcessTask(const base::PendingTask&) final {} // Canvas2D-specific interface virtual bool Is2d() const { return false; }
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc index faf1ff6..0558a0b 100644 --- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc +++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -391,7 +391,7 @@ if (canvas2d_bridge_) { // Compute to determine whether disable accleration is needed if (IsAccelerated() && - CanvasHeuristicParameters::kGPUReadbackForcesNoAcceleration && + canvas_heuristic_parameters::kGPUReadbackForcesNoAcceleration && !RuntimeEnabledFeatures::Canvas2dFixedRenderingModeEnabled()) { if (gpu_readback_invoked_in_current_frame_) { gpu_readback_successive_frames_++; @@ -401,7 +401,7 @@ } if (gpu_readback_successive_frames_ >= - CanvasHeuristicParameters::kGPUReadbackMinSuccessiveFrames) { + canvas_heuristic_parameters::kGPUReadbackMinSuccessiveFrames) { DisableAcceleration(); } } @@ -1147,7 +1147,7 @@ } void HTMLCanvasElement::WillDrawImageTo2DContext(CanvasImageSource* source) { - if (CanvasHeuristicParameters::kEnableAccelerationToAvoidReadbacks && + if (canvas_heuristic_parameters::kEnableAccelerationToAvoidReadbacks && SharedGpuContext::AllowSoftwareToAcceleratedCanvasUpgrade() && source->IsAccelerated() && GetOrCreateCanvas2DLayerBridge() && !canvas2d_bridge_->IsAccelerated() && @@ -1207,7 +1207,7 @@ else image = CreateTransparentImage(Size()); } else { - if (CanvasHeuristicParameters::kDisableAccelerationToAvoidReadbacks && + if (canvas_heuristic_parameters::kDisableAccelerationToAvoidReadbacks && !RuntimeEnabledFeatures::Canvas2dFixedRenderingModeEnabled() && hint == kPreferNoAcceleration && canvas2d_bridge_ && canvas2d_bridge_->IsAccelerated()) {
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl b/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl index b52dca2..0026c35 100644 --- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl +++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl
@@ -7,7 +7,7 @@ enum ImageOrientation { "none", "flipY" }; enum ImageBitmapPixelFormat { "default", "uint8" }; enum PremultiplyAlpha { "none", "premultiply", "default" }; -enum ColorSpaceConversion { "none", "default", "preserve", "srgb", "linear-rgb", "rec2020", "p3" }; +enum ColorSpaceConversion { "none", "default", "srgb", "linear-rgb", "rec2020", "p3" }; enum ResizeQuality { "pixelated", "low", "medium", "high" }; dictionary ImageBitmapOptions { ImageOrientation imageOrientation = "none";
diff --git a/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc b/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc index 1ba0c5c..6e7f586f 100644 --- a/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc +++ b/third_party/blink/renderer/core/inspector/worker_inspector_controller.cc
@@ -156,9 +156,11 @@ message); } -void WorkerInspectorController::WillProcessTask() {} +void WorkerInspectorController::WillProcessTask( + const base::PendingTask& pending_task) {} -void WorkerInspectorController::DidProcessTask() { +void WorkerInspectorController::DidProcessTask( + const base::PendingTask& pending_task) { for (auto& it : sessions_) it.value->flushProtocolNotifications(); }
diff --git a/third_party/blink/renderer/core/inspector/worker_inspector_controller.h b/third_party/blink/renderer/core/inspector/worker_inspector_controller.h index 2383ed2..6208523b 100644 --- a/third_party/blink/renderer/core/inspector/worker_inspector_controller.h +++ b/third_party/blink/renderer/core/inspector/worker_inspector_controller.h
@@ -82,8 +82,8 @@ mojom::blink::DevToolsSessionStatePtr updates) override; // Thread::TaskObserver implementation. - void WillProcessTask() override; - void DidProcessTask() override; + void WillProcessTask(const base::PendingTask&) override; + void DidProcessTask(const base::PendingTask&) override; // blink::TraceEvent::EnabledStateObserver implementation: void OnTraceLogEnabled() override;
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 f2ba53cb..39376b6 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
@@ -1491,7 +1491,8 @@ if (!document_element_style) document_element_style = document_element->GetComputedStyle(); - if (!document_element_style || document_element_style->HasBackground()) + DCHECK(document_element_style); + if (document_element_style->HasBackground()) return false; if (GetNode() != GetDocument().FirstBodyElement())
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc index 07c8e3d7..c26bf92 100644 --- a/third_party/blink/renderer/core/layout/layout_text.cc +++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -217,8 +217,9 @@ for (InlineTextBox* box : TextBoxes()) box->Remove(); } else if (Parent()) { - if (!FirstInlineFragment() || - !NGPaintFragment::TryMarkLineBoxDirtyFor(*this)) + if (NGPaintFragment* first_fragment = FirstInlineFragment()) + first_fragment->MarkLineBoxDirty(); + else Parent()->DirtyLinesFromChangedChild(this); } }
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc index e6c5008..dff411d 100644 --- a/third_party/blink/renderer/core/layout/layout_view.cc +++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -43,6 +43,7 @@ #include "third_party/blink/renderer/core/layout/view_fragmentation_context.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h" #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" @@ -111,6 +112,13 @@ SetPreferredLogicalWidthsDirty(kMarkOnlyThis); SetPositionState(EPosition::kAbsolute); // to 0,0 :) + + // Update the cached bit here since the Document is made the effective root + // scroller before we've created the layout tree. + if (GetDocument().GetRootScrollerController().EffectiveRootScroller() == + GetDocument()) { + SetIsEffectiveRootScroller(true); + } } LayoutView::~LayoutView() = default;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h index b5d64cf..cef4eab 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h +++ b/third_party/blink/renderer/core/layout/ng/ng_block_break_token.h
@@ -44,13 +44,16 @@ LayoutUnit used_block_size, const NGBreakTokenVector& child_break_tokens, bool has_last_resort_break = false) { - void* token = ::WTF::Partitions::FastMalloc( + // We store the children list inline in the break token as a flexible + // array. Therefore, we need to make sure to allocate enough space for + // that array here, which requires a manual allocation + placement new. + void* data = ::WTF::Partitions::FastMalloc( sizeof(NGBlockBreakToken) + child_break_tokens.size() * sizeof(NGBreakToken*), ::WTF::GetStringWithTypeName<NGBlockBreakToken>()); - new (token) NGBlockBreakToken(node, used_block_size, child_break_tokens, - has_last_resort_break); - return base::AdoptRef(static_cast<NGBlockBreakToken*>(token)); + new (data) NGBlockBreakToken(node, used_block_size, child_break_tokens, + has_last_resort_break); + return base::AdoptRef(static_cast<NGBlockBreakToken*>(data)); } // Creates a break token for a node which cannot produce any more fragments.
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc index b959277..782a748 100644 --- a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc +++ b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
@@ -509,9 +509,10 @@ uint64_t pixels = IntrinsicSize(kDoNotRespectImageOrientation).Area(); if (!pixels) return true; - long long resource_length = GetResponse().DecodedBodyLength(); + DCHECK(image_); + double resource_length = image_->Data() ? image_->Data()->size() : 0; // Allow no more than 10 bits per compressed pixel - return (double)resource_length / pixels <= 1.25; + return resource_length / pixels <= 1.25; } void ImageResourceContent::DecodedSizeChangedTo(const blink::Image* image,
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc index 01c51eb..29c1530 100644 --- a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -1281,6 +1281,21 @@ GetDocument().GetRootScrollerController().EffectiveRootScroller()); } +// Test that the cached IsEffectiveRootScroller bit on LayoutObject is set +// correctly when the Document is the effective root scroller. It becomes the +// root scroller before Document has a LayoutView. +TEST_F(RootScrollerSimTest, DocumentEffectiveSetsCachedBit) { + WebView().Resize(WebSize(800, 600)); + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete(R"HTML( + <!DOCTYPE html> + )HTML"); + Compositor().BeginFrame(); + + EXPECT_TRUE(GetDocument().GetLayoutView()->IsEffectiveRootScroller()); +} + // Test that layout from outside a lifecycle wont select a new effective root // scroller. TEST_F(RootScrollerSimTest, NonLifecycleLayoutDoesntCauseReselection) { @@ -2548,8 +2563,8 @@ // Do a scroll gesture that hides the top controls and scrolls all the way // to the bottom. ASSERT_EQ(1, GetBrowserControls().ShownRatio()); - WebView().ApplyViewportChanges({gfx::Vector2dF(), gfx::Vector2dF(), 1, -1, - cc::BrowserControlsState::kBoth}); + WebView().ApplyViewportChanges({gfx::ScrollOffset(), gfx::Vector2dF(), 1, + -1, cc::BrowserControlsState::kBoth}); ASSERT_EQ(0, GetBrowserControls().ShownRatio()); Element* scroller = GetDocument()
diff --git a/third_party/blink/renderer/core/paint/filter_effect_builder.cc b/third_party/blink/renderer/core/paint/filter_effect_builder.cc index a924299..3dd4e661 100644 --- a/third_party/blink/renderer/core/paint/filter_effect_builder.cc +++ b/third_party/blink/renderer/core/paint/filter_effect_builder.cc
@@ -305,14 +305,14 @@ Filter* reference_filter = BuildReferenceFilter(reference_operation, nullptr); if (reference_filter && reference_filter->LastEffect()) { - PaintFilterBuilder::PopulateSourceGraphicImageFilters( + paint_filter_builder::PopulateSourceGraphicImageFilters( reference_filter->GetSourceGraphic(), nullptr, current_interpolation_space); FilterEffect* filter_effect = reference_filter->LastEffect(); current_interpolation_space = filter_effect->OperatingInterpolationSpace(); - auto paint_filter = PaintFilterBuilder::Build( + auto paint_filter = paint_filter_builder::Build( filter_effect, current_interpolation_space); if (!paint_filter) continue; @@ -385,7 +385,7 @@ // instead of calling this a "reference filter". const auto& reflection = ToBoxReflectFilterOperation(*op).Reflection(); filters.AppendReferenceFilter( - PaintFilterBuilder::BuildBoxReflectFilter(reflection, nullptr)); + paint_filter_builder::BuildBoxReflectFilter(reflection, nullptr)); break; } case FilterOperation::NONE: @@ -394,8 +394,9 @@ } if (current_interpolation_space != kInterpolationSpaceSRGB) { // Transform to device color space at the end of processing, if required. - sk_sp<PaintFilter> filter = PaintFilterBuilder::TransformInterpolationSpace( - nullptr, current_interpolation_space, kInterpolationSpaceSRGB); + sk_sp<PaintFilter> filter = + paint_filter_builder::TransformInterpolationSpace( + nullptr, current_interpolation_space, kInterpolationSpaceSRGB); filters.AppendReferenceFilter(std::move(filter)); }
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc index d653859..19dfa4e 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -469,6 +469,13 @@ return FragmentRange(nullptr, false); } +NGPaintFragment* NGPaintFragment::LastForSameLayoutObject() { + NGPaintFragment* fragment = this; + while (fragment->next_for_same_layout_object_) + fragment = fragment->next_for_same_layout_object_; + return fragment; +} + void NGPaintFragment::DirtyLinesFromChangedChild(LayoutObject* child) { if (child->IsInline()) MarkLineBoxesDirtyFor(*child); @@ -561,16 +568,24 @@ void NGPaintFragment::MarkLineBoxesDirtyFor(const LayoutObject& layout_object) { DCHECK(layout_object.IsInline()) << layout_object; - if (TryMarkLineBoxDirtyFor(layout_object)) + + if (TryMarkFirstLineBoxDirtyFor(layout_object)) return; + // Since |layout_object| isn't in fragment tree, check preceding siblings. // Note: Once we reuse lines below dirty lines, we should check next siblings. for (LayoutObject* previous = layout_object.PreviousSibling(); previous; previous = previous->PreviousSibling()) { + // If the previoius object had never been laid out, it should have already + // marked the line box dirty. + if (!previous->EverHadLayout()) + return; + if (previous->IsFloatingOrOutOfFlowPositioned()) continue; + // |previous| may not be in inline formatting context, e.g. <object>. - if (TryMarkLineBoxDirtyFor(*previous)) + if (TryMarkLastLineBoxDirtyFor(*previous)) return; } @@ -606,13 +621,27 @@ NOTREACHED() << this; // Should have a line box ancestor. } -bool NGPaintFragment::TryMarkLineBoxDirtyFor( +bool NGPaintFragment::TryMarkFirstLineBoxDirtyFor( const LayoutObject& layout_object) { + if (!layout_object.IsInLayoutNGInlineFormattingContext()) + return false; // Once we reuse lines below dirty lines, we should mark lines for all // inline fragments. - NGPaintFragment* const first_fragment = layout_object.FirstInlineFragment(); - if (first_fragment) { - first_fragment->MarkLineBoxDirty(); + if (NGPaintFragment* const fragment = layout_object.FirstInlineFragment()) { + fragment->MarkLineBoxDirty(); + return true; + } + return false; +} + +bool NGPaintFragment::TryMarkLastLineBoxDirtyFor( + const LayoutObject& layout_object) { + if (!layout_object.IsInLayoutNGInlineFormattingContext()) + return false; + // Once we reuse lines below dirty lines, we should mark lines for all + // inline fragments. + if (NGPaintFragment* const fragment = layout_object.FirstInlineFragment()) { + fragment->LastForSameLayoutObject()->MarkLineBoxDirty(); return true; } return false;
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h index ae111bcb..22bac89 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -232,7 +232,8 @@ } // Returns true when associated fragment of |layout_object| has line box. - static bool TryMarkLineBoxDirtyFor(const LayoutObject& layout_object); + static bool TryMarkFirstLineBoxDirtyFor(const LayoutObject& layout_object); + static bool TryMarkLastLineBoxDirtyFor(const LayoutObject& layout_object); // A range of fragments for |FragmentsFor()|. class CORE_EXPORT FragmentRange { @@ -307,9 +308,15 @@ // for a LayoutObject. static FragmentRange InlineFragmentsFor(const LayoutObject*); + NGPaintFragment* LastForSameLayoutObject(); + // Called when lines containing |child| is dirty. static void DirtyLinesFromChangedChild(LayoutObject* child); + // Mark this line box was changed, in order to re-use part of an inline + // formatting context. + void MarkLineBoxDirty(); + // Computes LocalVisualRect for an inline LayoutObject in the // LayoutObject::LocalVisualRect semantics; i.e., physical coordinates with // flipped block-flow direction. See layout/README.md for the coordinate @@ -343,10 +350,6 @@ // Dirty line boxes containing |layout_object|. static void MarkLineBoxesDirtyFor(const LayoutObject& layout_object); - // Mark this line box was changed, in order to re-use part of an inline - // formatting context. - void MarkLineBoxDirty(); - // // Following fields are computed in the layout phase. //
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc index 2c5c889..bf94c52 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc
@@ -580,6 +580,28 @@ EXPECT_FALSE(ToList(container.Children())[2]->IsDirty()); } +TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyWrappedLine) { + SetBodyInnerHTML(R"HTML( + <style> + #container { + font-size: 10px; + width: 10ch; + } + </style> + <div id=container> + 1234567 + 123456<span id="target">7</span> + </div>)HTML"); + Element& target = *GetDocument().getElementById("target"); + target.remove(); + + const NGPaintFragment& container = *GetPaintFragmentByElementId("container"); + const NGPaintFragment& line0 = *container.FirstChild(); + const NGPaintFragment& line1 = *line0.NextSibling(); + EXPECT_FALSE(line0.IsDirty()); + EXPECT_TRUE(line1.IsDirty()); +} + TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyInsideInlineBlock) { SetBodyInnerHTML(R"HTML( <div id=container>
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 eb9e489..0309dbc8 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
@@ -291,17 +291,6 @@ : nullptr; } -bool PaintLayerScrollableArea::ShouldUseIntegerScrollOffset() const { - if (!HasBeenDisposed()) { - Frame* frame = GetLayoutBox()->GetFrame(); - if (frame->GetSettings() && - !frame->GetSettings()->GetPreferCompositingToLCDTextEnabled()) - return true; - } - - return ScrollableArea::ShouldUseIntegerScrollOffset(); -} - bool PaintLayerScrollableArea::IsActive() const { Page* page = GetLayoutBox()->GetFrame()->GetPage(); return page && page->GetFocusController().IsActive();
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h index e1a848c..141c90d 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -284,7 +284,6 @@ GraphicsLayer* LayerForScrollCorner() const override; bool ShouldScrollOnMainThread() const override; - bool ShouldUseIntegerScrollOffset() const override; bool IsActive() const override; bool IsScrollCornerVisible() const override; IntRect ScrollCornerRect() const override;
diff --git a/third_party/blink/renderer/core/paint/svg_filter_painter.cc b/third_party/blink/renderer/core/paint/svg_filter_painter.cc index 7381094..4937fa5 100644 --- a/third_party/blink/renderer/core/paint/svg_filter_painter.cc +++ b/third_party/blink/renderer/core/paint/svg_filter_painter.cc
@@ -67,7 +67,7 @@ DrawingRecorder recorder(context, object, DisplayItem::kSVGFilter); sk_sp<PaintFilter> image_filter = - PaintFilterBuilder::Build(effect, kInterpolationSpaceSRGB); + paint_filter_builder::Build(effect, kInterpolationSpaceSRGB); context.Save(); // Clip drawing of filtered image to the minimum required paint rect. @@ -153,8 +153,8 @@ if (filter_data->state_ == FilterData::kRecordingContent) { DCHECK(filter->GetSourceGraphic()); sk_sp<PaintRecord> content = recording_context.EndContent(bounds); - PaintFilterBuilder::BuildSourceGraphic(filter->GetSourceGraphic(), - std::move(content), bounds); + paint_filter_builder::BuildSourceGraphic(filter->GetSourceGraphic(), + std::move(content), bounds); filter_data->state_ = FilterData::kReadyToPaint; }
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc index e02b970..1892aa3 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
@@ -139,11 +139,24 @@ } void TextPaintTimingDetector::NotifyNodeRemoved(DOMNodeId node_id) { - if (recorded_text_node_ids_.find(node_id) != recorded_text_node_ids_.end()) { - // We assume that the removed node's id wouldn't be recycled, so we don't - // bother to remove these records from largest_text_heap_ or - // latest_text_heap_, to reduce computation. - recorded_text_node_ids_.erase(node_id); + if (recorded_text_node_ids_.find(node_id) == recorded_text_node_ids_.end()) + return; + // We assume that removed nodes' id would not be recycled, and it's expensive + // to remove records from largest_text_heap_ and latest_text_heap_, so we + // intentionally keep the records of removed nodes in largest_text_heap_ and + // latest_text_heap_. + recorded_text_node_ids_.erase(node_id); + if (recorded_text_node_ids_.size() == 0) { + const bool largest_text_paint_invalidated = + largest_text_paint_ != base::TimeTicks(); + const bool last_text_paint_invalidated = + last_text_paint_ != base::TimeTicks(); + if (largest_text_paint_invalidated) + largest_text_paint_ = base::TimeTicks(); + if (last_text_paint_invalidated) + last_text_paint_ = base::TimeTicks(); + if (largest_text_paint_invalidated || last_text_paint_invalidated) + frame_view_->GetPaintTracker().DidChangePerformanceTiming(); } }
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h index 9ef7abbe..4cbf0e5 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector.h +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
@@ -62,8 +62,8 @@ void OnPrePaintFinished(); void NotifyNodeRemoved(DOMNodeId); void Dispose() { timer_.Stop(); } - base::TimeTicks LargestTextPaint() { return largest_text_paint_; } - base::TimeTicks LastTextPaint() { return last_text_paint_; } + base::TimeTicks LargestTextPaint() const { return largest_text_paint_; } + base::TimeTicks LastTextPaint() const { return last_text_paint_; } void Trace(blink::Visitor*); private:
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc index 8794b40f..1b2c2085 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
@@ -169,15 +169,49 @@ </div> )HTML"); UpdateAllLifecyclePhasesAndSimulateSwapTime(); - GetDocument().getElementById("parent")->RemoveChild( - GetDocument().getElementById("earlyLargeText")); - UpdateAllLifecyclePhasesAndSimulateSwapTime(); TextRecord* record = GetPaintTracker() .GetTextPaintTimingDetector() .FindLargestPaintCandidate(); + EXPECT_TRUE(record); + EXPECT_EQ(record->text, + "(large text)(large text)(large text)(large text)(large " + "text)(large text)"); + + GetDocument().getElementById("parent")->RemoveChild( + GetDocument().getElementById("earlyLargeText")); + UpdateAllLifecyclePhasesAndSimulateSwapTime(); + record = GetPaintTracker() + .GetTextPaintTimingDetector() + .FindLargestPaintCandidate(); EXPECT_EQ(record->text, "small text"); } +TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_ReportLastNullCandidate) { + SetBodyInnerHTML(R"HTML( + <div id='parent'> + <div id='remove'>text</div> + </div> + )HTML"); + UpdateAllLifecyclePhasesAndSimulateSwapTime(); + SimulateAnalyze(); + TextRecord* record = GetPaintTracker() + .GetTextPaintTimingDetector() + .FindLargestPaintCandidate(); + EXPECT_TRUE(record); + EXPECT_EQ(record->text, "text"); + EXPECT_NE(LargestPaintStoredResult(), base::TimeTicks()); + + GetDocument().getElementById("parent")->RemoveChild( + GetDocument().getElementById("remove")); + UpdateAllLifecyclePhasesAndSimulateSwapTime(); + SimulateAnalyze(); + record = GetPaintTracker() + .GetTextPaintTimingDetector() + .FindLargestPaintCandidate(); + EXPECT_FALSE(record); + EXPECT_EQ(LargestPaintStoredResult(), base::TimeTicks()); +} + TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_CompareVisualSizeNotActualSize) { SetBodyInnerHTML(R"HTML( @@ -336,4 +370,30 @@ EXPECT_EQ(record->text, "5000"); } +TEST_F(TextPaintTimingDetectorTest, LastTextPaint_ReportLastNullCandidate) { + SetBodyInnerHTML(R"HTML( + <div id='parent'> + <div id='remove'>text</div> + </div> + )HTML"); + UpdateAllLifecyclePhasesAndSimulateSwapTime(); + SimulateAnalyze(); + TextRecord* record = GetPaintTracker() + .GetTextPaintTimingDetector() + .FindLargestPaintCandidate(); + EXPECT_TRUE(record); + EXPECT_EQ(record->text, "text"); + EXPECT_NE(LastPaintStoredResult(), base::TimeTicks()); + + GetDocument().getElementById("parent")->RemoveChild( + GetDocument().getElementById("remove")); + UpdateAllLifecyclePhasesAndSimulateSwapTime(); + SimulateAnalyze(); + record = GetPaintTracker() + .GetTextPaintTimingDetector() + .FindLargestPaintCandidate(); + EXPECT_FALSE(record); + EXPECT_EQ(LastPaintStoredResult(), base::TimeTicks()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/timing/performance_element_timing.cc b/third_party/blink/renderer/core/timing/performance_element_timing.cc index c892b0d8..a2917af 100644 --- a/third_party/blink/renderer/core/timing/performance_element_timing.cc +++ b/third_party/blink/renderer/core/timing/performance_element_timing.cc
@@ -27,7 +27,7 @@ PerformanceElementTiming::~PerformanceElementTiming() = default; AtomicString PerformanceElementTiming::entryType() const { - return PerformanceEntryNames::element; + return performance_entry_names::kElement; } PerformanceEntryType PerformanceElementTiming::EntryTypeEnum() const {
diff --git a/third_party/blink/renderer/core/timing/performance_entry.cc b/third_party/blink/renderer/core/timing/performance_entry.cc index 6d44473..86025870d 100644 --- a/third_party/blink/renderer/core/timing/performance_entry.cc +++ b/third_party/blink/renderer/core/timing/performance_entry.cc
@@ -61,27 +61,27 @@ PerformanceEntry::EntryType PerformanceEntry::ToEntryTypeEnum( const AtomicString& entry_type) { - if (entry_type == PerformanceEntryNames::longtask) + if (entry_type == performance_entry_names::kLongtask) return kLongTask; - if (entry_type == PerformanceEntryNames::mark) + if (entry_type == performance_entry_names::kMark) return kMark; - if (entry_type == PerformanceEntryNames::measure) + if (entry_type == performance_entry_names::kMeasure) return kMeasure; - if (entry_type == PerformanceEntryNames::resource) + if (entry_type == performance_entry_names::kResource) return kResource; - if (entry_type == PerformanceEntryNames::navigation) + if (entry_type == performance_entry_names::kNavigation) return kNavigation; - if (entry_type == PerformanceEntryNames::taskattribution) + if (entry_type == performance_entry_names::kTaskattribution) return kTaskAttribution; - if (entry_type == PerformanceEntryNames::paint) + if (entry_type == performance_entry_names::kPaint) return kPaint; - if (entry_type == PerformanceEntryNames::event) + if (entry_type == performance_entry_names::kEvent) return kEvent; - if (entry_type == PerformanceEntryNames::firstInput) + if (entry_type == performance_entry_names::kFirstInput) return kFirstInput; - if (entry_type == PerformanceEntryNames::element) + if (entry_type == performance_entry_names::kElement) return kElement; - if (entry_type == PerformanceEntryNames::layoutJank) + if (entry_type == performance_entry_names::kLayoutJank) return kLayoutJank; return kInvalid; }
diff --git a/third_party/blink/renderer/core/timing/performance_entry_names.json5 b/third_party/blink/renderer/core/timing/performance_entry_names.json5 index c2c2959..0ecf8753 100644 --- a/third_party/blink/renderer/core/timing/performance_entry_names.json5 +++ b/third_party/blink/renderer/core/timing/performance_entry_names.json5
@@ -1,6 +1,6 @@ { metadata: { - namespace: "PerformanceEntry", + namespace: "performance_entry_names", export: "CORE_EXPORT", },
diff --git a/third_party/blink/renderer/core/timing/performance_event_timing.cc b/third_party/blink/renderer/core/timing/performance_event_timing.cc index a31aacdf..de16cc8 100644 --- a/third_party/blink/renderer/core/timing/performance_event_timing.cc +++ b/third_party/blink/renderer/core/timing/performance_event_timing.cc
@@ -19,7 +19,7 @@ // TODO(npm): enable this DCHECK once https://crbug.com/852846 is fixed. // DCHECK_LE(start_time, processing_start); DCHECK_LE(processing_start, processing_end); - return new PerformanceEventTiming(event_type, PerformanceEntryNames::event, + return new PerformanceEventTiming(event_type, performance_entry_names::kEvent, start_time, processing_start, processing_end, cancelable); } @@ -28,7 +28,7 @@ PerformanceEventTiming* PerformanceEventTiming::CreateFirstInputTiming( PerformanceEventTiming* entry) { PerformanceEventTiming* first_input = new PerformanceEventTiming( - entry->name(), PerformanceEntryNames::firstInput, entry->startTime(), + entry->name(), performance_entry_names::kFirstInput, entry->startTime(), entry->processingStart(), entry->processingEnd(), entry->cancelable()); first_input->SetDuration(entry->duration()); return first_input; @@ -50,7 +50,7 @@ PerformanceEventTiming::~PerformanceEventTiming() = default; PerformanceEntryType PerformanceEventTiming::EntryTypeEnum() const { - return entry_type_ == PerformanceEntryNames::event + return entry_type_ == performance_entry_names::kEvent ? PerformanceEntry::EntryType::kEvent : PerformanceEntry::EntryType::kFirstInput; }
diff --git a/third_party/blink/renderer/core/timing/performance_layout_jank.cc b/third_party/blink/renderer/core/timing/performance_layout_jank.cc index 776c402..4634426 100644 --- a/third_party/blink/renderer/core/timing/performance_layout_jank.cc +++ b/third_party/blink/renderer/core/timing/performance_layout_jank.cc
@@ -21,7 +21,7 @@ PerformanceLayoutJank::~PerformanceLayoutJank() = default; AtomicString PerformanceLayoutJank::entryType() const { - return PerformanceEntryNames::layoutJank; + return performance_entry_names::kLayoutJank; } PerformanceEntryType PerformanceLayoutJank::EntryTypeEnum() const {
diff --git a/third_party/blink/renderer/core/timing/performance_long_task_timing.cc b/third_party/blink/renderer/core/timing/performance_long_task_timing.cc index 8db17dc..aa80087e 100644 --- a/third_party/blink/renderer/core/timing/performance_long_task_timing.cc +++ b/third_party/blink/renderer/core/timing/performance_long_task_timing.cc
@@ -57,7 +57,7 @@ PerformanceLongTaskTiming::~PerformanceLongTaskTiming() = default; AtomicString PerformanceLongTaskTiming::entryType() const { - return PerformanceEntryNames::longtask; + return performance_entry_names::kLongtask; } PerformanceEntryType PerformanceLongTaskTiming::EntryTypeEnum() const {
diff --git a/third_party/blink/renderer/core/timing/performance_mark.cc b/third_party/blink/renderer/core/timing/performance_mark.cc index 18e421e0..c757a78 100644 --- a/third_party/blink/renderer/core/timing/performance_mark.cc +++ b/third_party/blink/renderer/core/timing/performance_mark.cc
@@ -23,7 +23,7 @@ } AtomicString PerformanceMark::entryType() const { - return PerformanceEntryNames::mark; + return performance_entry_names::kMark; } PerformanceEntryType PerformanceMark::EntryTypeEnum() const {
diff --git a/third_party/blink/renderer/core/timing/performance_measure.cc b/third_party/blink/renderer/core/timing/performance_measure.cc index d31f4be..0a6c3db 100644 --- a/third_party/blink/renderer/core/timing/performance_measure.cc +++ b/third_party/blink/renderer/core/timing/performance_measure.cc
@@ -31,7 +31,7 @@ } AtomicString PerformanceMeasure::entryType() const { - return PerformanceEntryNames::measure; + return performance_entry_names::kMeasure; } PerformanceEntryType PerformanceMeasure::EntryTypeEnum() const {
diff --git a/third_party/blink/renderer/core/timing/performance_navigation_timing.cc b/third_party/blink/renderer/core/timing/performance_navigation_timing.cc index 607eb33..69bd24b4 100644 --- a/third_party/blink/renderer/core/timing/performance_navigation_timing.cc +++ b/third_party/blink/renderer/core/timing/performance_navigation_timing.cc
@@ -36,7 +36,7 @@ PerformanceNavigationTiming::~PerformanceNavigationTiming() = default; AtomicString PerformanceNavigationTiming::entryType() const { - return PerformanceEntryNames::navigation; + return performance_entry_names::kNavigation; } PerformanceEntryType PerformanceNavigationTiming::EntryTypeEnum() const { @@ -119,7 +119,7 @@ } AtomicString PerformanceNavigationTiming::initiatorType() const { - return PerformanceEntryNames::navigation; + return performance_entry_names::kNavigation; } bool PerformanceNavigationTiming::GetAllowRedirectDetails() const {
diff --git a/third_party/blink/renderer/core/timing/performance_paint_timing.cc b/third_party/blink/renderer/core/timing/performance_paint_timing.cc index d6d0ce5c..7d74bbb 100644 --- a/third_party/blink/renderer/core/timing/performance_paint_timing.cc +++ b/third_party/blink/renderer/core/timing/performance_paint_timing.cc
@@ -39,7 +39,7 @@ PerformancePaintTiming::~PerformancePaintTiming() = default; AtomicString PerformancePaintTiming::entryType() const { - return PerformanceEntryNames::paint; + return performance_entry_names::kPaint; } PerformanceEntryType PerformancePaintTiming::EntryTypeEnum() const {
diff --git a/third_party/blink/renderer/core/timing/performance_resource_timing.cc b/third_party/blink/renderer/core/timing/performance_resource_timing.cc index 3a28e13..c884494 100644 --- a/third_party/blink/renderer/core/timing/performance_resource_timing.cc +++ b/third_party/blink/renderer/core/timing/performance_resource_timing.cc
@@ -88,7 +88,7 @@ PerformanceResourceTiming::~PerformanceResourceTiming() = default; AtomicString PerformanceResourceTiming::entryType() const { - return PerformanceEntryNames::resource; + return performance_entry_names::kResource; } PerformanceEntryType PerformanceResourceTiming::EntryTypeEnum() const {
diff --git a/third_party/blink/renderer/core/timing/task_attribution_timing.cc b/third_party/blink/renderer/core/timing/task_attribution_timing.cc index e52f95416..3ed5fab 100644 --- a/third_party/blink/renderer/core/timing/task_attribution_timing.cc +++ b/third_party/blink/renderer/core/timing/task_attribution_timing.cc
@@ -28,7 +28,7 @@ TaskAttributionTiming::~TaskAttributionTiming() = default; AtomicString TaskAttributionTiming::entryType() const { - return PerformanceEntryNames::taskattribution; + return performance_entry_names::kTaskattribution; } PerformanceEntryType TaskAttributionTiming::EntryTypeEnum() const {
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc index 3096b9b..364a572 100644 --- a/third_party/blink/renderer/core/workers/worker_thread.cc +++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -243,14 +243,14 @@ thread->ClearWorkerBackingThread(); } -void WorkerThread::WillProcessTask() { +void WorkerThread::WillProcessTask(const base::PendingTask& pending_task) { DCHECK(IsCurrentThread()); // No tasks should get executed after we have closed. DCHECK(!GlobalScope()->IsClosing()); } -void WorkerThread::DidProcessTask() { +void WorkerThread::DidProcessTask(const base::PendingTask& pending_task) { DCHECK(IsCurrentThread()); Microtask::PerformCheckpoint(GetIsolate()); GlobalScope()->ScriptController()->GetRejectedPromises()->ProcessQueue();
diff --git a/third_party/blink/renderer/core/workers/worker_thread.h b/third_party/blink/renderer/core/workers/worker_thread.h index 36e19742..ac88d94 100644 --- a/third_party/blink/renderer/core/workers/worker_thread.h +++ b/third_party/blink/renderer/core/workers/worker_thread.h
@@ -140,8 +140,8 @@ static void TerminateAllWorkersForTesting(); // Thread::TaskObserver. - void WillProcessTask() override; - void DidProcessTask() override; + void WillProcessTask(const base::PendingTask&) override; + void DidProcessTask(const base::PendingTask&) override; virtual WorkerBackingThread& GetWorkerBackingThread() = 0; virtual void ClearWorkerBackingThread() = 0;
diff --git a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc index eb57879..2daf073 100644 --- a/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc +++ b/third_party/blink/renderer/core/xml/parser/xml_document_parser.cc
@@ -397,7 +397,10 @@ if (parser_paused_) return; - if (saw_error_) + // StopParsing() calls InsertErrorMessageBlock() if there was a parsing + // error. Avoid showing the error message block twice. + // TODO(crbug.com/898775): Rationalize this. + if (saw_error_ && !IsStopped()) InsertErrorMessageBlock(); else UpdateLeafTextNode(); @@ -1580,6 +1583,9 @@ } void XMLDocumentParser::StopParsing() { + // See comment before InsertErrorMessageBlock() in XMLDocumentParser::end. + if (saw_error_) + InsertErrorMessageBlock(); DocumentParser::StopParsing(); if (Context()) xmlStopParser(Context());
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc index 5bd0cdfe..582c6a8 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -1312,21 +1312,21 @@ // Heuristic for disabling acceleration based on anticipated texture upload // overhead. - // See comments in CanvasHeuristicParameters.h for explanation. + // See comments in canvas_heuristic_parameters.h for explanation. if (CanCreateCanvas2dResourceProvider() && IsAccelerated() && !image_source->IsAccelerated()) { float src_area = src_rect.Width() * src_rect.Height(); if (src_area > - CanvasHeuristicParameters::kDrawImageTextureUploadHardSizeLimit) { + canvas_heuristic_parameters::kDrawImageTextureUploadHardSizeLimit) { this->DisableAcceleration(); - } else if (src_area > CanvasHeuristicParameters:: + } else if (src_area > canvas_heuristic_parameters:: kDrawImageTextureUploadSoftSizeLimit) { SkRect bounds = dst_rect; SkMatrix ctm = DrawingCanvas()->getTotalMatrix(); ctm.mapRect(&bounds); float dst_area = dst_rect.Width() * dst_rect.Height(); if (src_area > - dst_area * CanvasHeuristicParameters:: + dst_area * canvas_heuristic_parameters:: kDrawImageTextureUploadSoftSizeLimitScaleThreshold) { this->DisableAcceleration(); }
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc index 3674c02..b419a47 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -557,8 +557,9 @@ ModifiableState().SetUnparsedFont(new_font_safe_copy); } -void CanvasRenderingContext2D::DidProcessTask() { - CanvasRenderingContext::DidProcessTask(); +void CanvasRenderingContext2D::DidProcessTask( + const base::PendingTask& pending_task) { + CanvasRenderingContext::DidProcessTask(pending_task); // This should be the only place where canvas() needs to be checked for // nullness because the circular refence with HTMLCanvasElement means the // canvas and the context keep each other alive. As long as the pair is
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h index 5a34779..df2a8d29 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
@@ -141,7 +141,7 @@ void RestoreCanvasMatrixClipStack(cc::PaintCanvas*) const override; // TaskObserver implementation - void DidProcessTask() final; + void DidProcessTask(const base::PendingTask&) final; void StyleDidChange(const ComputedStyle* old_style, const ComputedStyle& new_style) override;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc index c71b69a..7106cbf 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc
@@ -308,7 +308,7 @@ if (last_effect) { // TODO(chrishtr): Taint the origin if needed. crbug.com/792506. resolved_filter_ = - PaintFilterBuilder::Build(last_effect, kInterpolationSpaceSRGB); + paint_filter_builder::Build(last_effect, kInterpolationSpaceSRGB); } return resolved_filter_; @@ -362,7 +362,7 @@ if (FilterEffect* last_effect = filter_effect_builder.BuildFilterEffect( filter_style->Filter(), !context->OriginClean())) { resolved_filter_ = - PaintFilterBuilder::Build(last_effect, kInterpolationSpaceSRGB); + paint_filter_builder::Build(last_effect, kInterpolationSpaceSRGB); if (resolved_filter_) { context->UpdateFilterReferences(filter_style->Filter()); if (last_effect->OriginTainted())
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc index 8ca5bf232..7ee1086 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -644,7 +644,8 @@ // This is the only method that is callable after DetachHost // Test passes by not crashing. - Context2d()->DidProcessTask(); + base::PendingTask dummy_pending_task(FROM_HERE, base::Closure()); + Context2d()->DidProcessTask(dummy_pending_task); // Test passes by not crashing during teardown } @@ -682,7 +683,7 @@ DummyExceptionStateForTesting exception_state; for (int i = 0; - i < CanvasHeuristicParameters::kGPUReadbackMinSuccessiveFrames - 1; + i < canvas_heuristic_parameters::kGPUReadbackMinSuccessiveFrames - 1; i++) { Context2d()->getImageData(0, 0, 1, 1, exception_state); CanvasElement().FinalizeFrame(); @@ -697,7 +698,7 @@ CanvasElement().FinalizeFrame(); EXPECT_FALSE(exception_state.HadException()); - if (CanvasHeuristicParameters::kGPUReadbackForcesNoAcceleration) { + if (canvas_heuristic_parameters::kGPUReadbackForcesNoAcceleration) { EXPECT_FALSE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); EXPECT_EQ(0u, GetGlobalAcceleratedContextCount()); EXPECT_EQ(0, GetGlobalGPUMemoryUsage());
diff --git a/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc b/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc index 50a9a6f..91e9cb5 100644 --- a/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc +++ b/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc
@@ -181,12 +181,16 @@ return; ScriptState* script_state = resolver_->GetScriptState(); + v8::Isolate* isolate = script_state->GetIsolate(); ScriptState::Scope scope(script_state); + // Crashes if longer than v8::String::kMaxLength. v8::Local<v8::String> json_string = - V8StringFromUtf8(script_state->GetIsolate(), utf8_data, length); + v8::String::NewFromUtf8(isolate, utf8_data, v8::NewStringType::kNormal, + length) + .ToLocalChecked(); - v8::TryCatch exception_catcher(script_state->GetIsolate()); + v8::TryCatch exception_catcher(isolate); v8::Local<v8::Value> json_dictionary; if (v8::JSON::Parse(script_state->GetContext(), json_string) .ToLocal(&json_dictionary))
diff --git a/third_party/blink/renderer/platform/bindings/v8_binding.h b/third_party/blink/renderer/platform/bindings/v8_binding.h index f5209d21c..ba28fbf 100644 --- a/third_party/blink/renderer/platform/bindings/v8_binding.h +++ b/third_party/blink/renderer/platform/bindings/v8_binding.h
@@ -328,19 +328,6 @@ .ToLocalChecked(); } -inline v8::Local<v8::String> V8StringFromUtf8(v8::Isolate* isolate, - const char* bytes, - int length) { - DCHECK(isolate); - return v8::String::NewFromUtf8(isolate, bytes, v8::NewStringType::kNormal, - length) - .ToLocalChecked(); -} - -inline v8::Local<v8::Value> V8Undefined() { - return v8::Local<v8::Value>(); -} - inline v8::MaybeLocal<v8::Value> V8DateOrNaN(v8::Isolate* isolate, double value) { DCHECK(isolate); @@ -364,8 +351,10 @@ v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); for (int i = 0; i < length; ++i) { v8::Local<v8::Integer> integer = v8::Integer::New(info.GetIsolate(), i); - if (!V8CallBoolean(properties->CreateDataProperty(context, i, integer))) + bool created; + if (!properties->CreateDataProperty(context, i, integer).To(&created)) return; + DCHECK(created); } V8SetReturnValue(info, properties); }
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc index 26346e5..4c89398 100644 --- a/third_party/blink/renderer/platform/exported/web_url_request.cc +++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -348,6 +348,14 @@ resource_request_->SetExtraData(std::move(extra_data)); } +bool WebURLRequest::IsDownloadToNetworkCacheOnly() const { + return resource_request_->IsDownloadToNetworkCacheOnly(); +} + +void WebURLRequest::SetDownloadToNetworkCacheOnly(bool download_to_cache_only) { + resource_request_->SetDownloadToNetworkCacheOnly(download_to_cache_only); +} + ResourceRequest& WebURLRequest::ToMutableResourceRequest() { DCHECK(resource_request_); return *resource_request_;
diff --git a/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc b/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc index f530122..616b61d 100644 --- a/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc +++ b/third_party/blink/renderer/platform/graphics/bitmap_image_test.cc
@@ -136,8 +136,7 @@ }; static scoped_refptr<SharedBuffer> ReadFile(const char* file_name) { - String file_path = test::BlinkLayoutTestsDir(); - file_path.append(file_name); + String file_path = test::PlatformTestDataPath(file_name); return test::ReadFromFile(file_path); } @@ -245,7 +244,7 @@ }; TEST_F(BitmapImageTest, destroyDecodedData) { - LoadImage("/images/resources/animated-10color.gif"); + LoadImage("animated-10color.gif"); image_->PaintImageForCurrentFrame(); size_t total_size = DecodedSize(); EXPECT_GT(total_size, 0u); @@ -255,13 +254,12 @@ } TEST_F(BitmapImageTest, maybeAnimated) { - LoadImage("/images/resources/gif-loop-count.gif"); + LoadImage("gif-loop-count.gif"); EXPECT_TRUE(image_->MaybeAnimated()); } TEST_F(BitmapImageTest, isAllDataReceived) { - scoped_refptr<SharedBuffer> image_data = - ReadFile("/images/resources/green.jpg"); + scoped_refptr<SharedBuffer> image_data = ReadFile("green.jpg"); ASSERT_TRUE(image_data.get()); scoped_refptr<BitmapImage> image = BitmapImage::Create(); @@ -281,14 +279,14 @@ } TEST_F(BitmapImageTest, noColorProfile) { - LoadImage("/images/resources/green.jpg"); + LoadImage("green.jpg"); image_->PaintImageForCurrentFrame(); EXPECT_EQ(1024u, DecodedSize()); EXPECT_FALSE(image_->HasColorProfile()); } TEST_F(BitmapImageTest, jpegHasColorProfile) { - LoadImage("/images/resources/icc-v2-gbr.jpg"); + LoadImage("icc-v2-gbr.jpg"); image_->PaintImageForCurrentFrame(); EXPECT_EQ(227700u, DecodedSize()); EXPECT_TRUE(image_->HasColorProfile()); @@ -296,7 +294,6 @@ TEST_F(BitmapImageTest, pngHasColorProfile) { LoadImage( - "/images/resources/" "palatted-color-png-gamma-one-color-profile.png"); image_->PaintImageForCurrentFrame(); EXPECT_EQ(65536u, DecodedSize()); @@ -304,21 +301,21 @@ } TEST_F(BitmapImageTest, webpHasColorProfile) { - LoadImage("/images/resources/webp-color-profile-lossy.webp"); + LoadImage("webp-color-profile-lossy.webp"); image_->PaintImageForCurrentFrame(); EXPECT_EQ(2560000u, DecodedSize()); EXPECT_TRUE(image_->HasColorProfile()); } TEST_F(BitmapImageTest, icoHasWrongFrameDimensions) { - LoadImage("/images/resources/wrong-frame-dimensions.ico"); + LoadImage("wrong-frame-dimensions.ico"); // This call would cause crash without fix for 408026 ImageForDefaultFrame(); } TEST_F(BitmapImageTest, correctDecodedDataSize) { // Requesting any one frame shouldn't result in decoding any other frames. - LoadImage("/images/resources/anim_none.gif"); + LoadImage("anim_none.gif"); image_->PaintImageForCurrentFrame(); int frame_size = static_cast<int>(image_->Size().Area() * sizeof(ImageFrame::PixelData)); @@ -326,7 +323,7 @@ } TEST_F(BitmapImageTest, recachingFrameAfterDataChanged) { - LoadImage("/images/resources/green.jpg"); + LoadImage("green.jpg"); image_->PaintImageForCurrentFrame(); EXPECT_GT(LastDecodedSizeChange(), 0); image_observer_->last_decoded_size_changed_delta_ = 0; @@ -341,8 +338,7 @@ } TEST_F(BitmapImageTest, ConstantImageIdForPartiallyLoadedImages) { - scoped_refptr<SharedBuffer> image_data = - ReadFile("/images/resources/green.jpg"); + scoped_refptr<SharedBuffer> image_data = ReadFile("green.jpg"); ASSERT_TRUE(image_data.get()); // Create a new buffer to partially supply the data. @@ -397,7 +393,7 @@ } TEST_F(BitmapImageTest, ImageForDefaultFrame_MultiFrame) { - LoadImage("/images/resources/anim_none.gif"); + LoadImage("anim_none.gif"); // Multi-frame images create new StaticBitmapImages for each call. auto default_image1 = image_->ImageForDefaultFrame(); @@ -413,39 +409,39 @@ } TEST_F(BitmapImageTest, ImageForDefaultFrame_SingleFrame) { - LoadImage("/images/resources/green.jpg"); + LoadImage("green.jpg"); // Default frame images for single-frame cases is the image itself. EXPECT_EQ(image_->ImageForDefaultFrame(), image_); } TEST_F(BitmapImageTest, GifDecoderFrame0) { - LoadImage("/images/resources/green-red-blue-yellow-animated.gif"); + LoadImage("green-red-blue-yellow-animated.gif"); auto bitmap = GenerateBitmap(0u); SkColor color = SkColorSetARGB(255, 0, 128, 0); VerifyBitmap(bitmap, color); } TEST_F(BitmapImageTest, GifDecoderFrame1) { - LoadImage("/images/resources/green-red-blue-yellow-animated.gif"); + LoadImage("green-red-blue-yellow-animated.gif"); auto bitmap = GenerateBitmap(1u); VerifyBitmap(bitmap, SK_ColorRED); } TEST_F(BitmapImageTest, GifDecoderFrame2) { - LoadImage("/images/resources/green-red-blue-yellow-animated.gif"); + LoadImage("green-red-blue-yellow-animated.gif"); auto bitmap = GenerateBitmap(2u); VerifyBitmap(bitmap, SK_ColorBLUE); } TEST_F(BitmapImageTest, GifDecoderFrame3) { - LoadImage("/images/resources/green-red-blue-yellow-animated.gif"); + LoadImage("green-red-blue-yellow-animated.gif"); auto bitmap = GenerateBitmap(3u); VerifyBitmap(bitmap, SK_ColorYELLOW); } TEST_F(BitmapImageTest, GifDecoderMultiThreaded) { - LoadImage("/images/resources/green-red-blue-yellow-animated.gif"); + LoadImage("green-red-blue-yellow-animated.gif"); auto paint_image = image_->PaintImageForTesting(); ASSERT_EQ(paint_image.FrameCount(), 4u); @@ -476,110 +472,98 @@ } TEST_F(BitmapImageTest, APNGDecoder00) { - LoadImage("/images/resources/apng00.png"); + LoadImage("apng00.png"); auto actual_bitmap = GenerateBitmap(0u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng00-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng00-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } // Jump to the final frame of each image. TEST_F(BitmapImageTest, APNGDecoder01) { - LoadImage("/images/resources/apng01.png"); + LoadImage("apng01.png"); auto actual_bitmap = GenerateBitmap(9u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng01-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng01-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, APNGDecoder02) { - LoadImage("/images/resources/apng02.png"); + LoadImage("apng02.png"); auto actual_bitmap = GenerateBitmap(9u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng02-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng02-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, APNGDecoder04) { - LoadImage("/images/resources/apng04.png"); + LoadImage("apng04.png"); auto actual_bitmap = GenerateBitmap(12u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng04-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng04-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, APNGDecoder08) { - LoadImage("/images/resources/apng08.png"); + LoadImage("apng08.png"); auto actual_bitmap = GenerateBitmap(12u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng08-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng08-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, APNGDecoder10) { - LoadImage("/images/resources/apng10.png"); + LoadImage("apng10.png"); auto actual_bitmap = GenerateBitmap(3u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng10-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng10-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, APNGDecoder11) { - LoadImage("/images/resources/apng11.png"); + LoadImage("apng11.png"); auto actual_bitmap = GenerateBitmap(9u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng11-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng11-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, APNGDecoder12) { - LoadImage("/images/resources/apng12.png"); + LoadImage("apng12.png"); auto actual_bitmap = GenerateBitmap(9u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng12-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng12-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, APNGDecoder14) { - LoadImage("/images/resources/apng14.png"); + LoadImage("apng14.png"); auto actual_bitmap = GenerateBitmap(12u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng14-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng14-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, APNGDecoder18) { - LoadImage("/images/resources/apng18.png"); + LoadImage("apng18.png"); auto actual_bitmap = GenerateBitmap(12u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng18-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng18-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, APNGDecoder19) { - LoadImage("/images/resources/apng19.png"); + LoadImage("apng19.png"); auto actual_bitmap = GenerateBitmap(12u); - auto expected_bitmap = - GenerateBitmapForImage("/images/resources/apng19-ref.png"); + auto expected_bitmap = GenerateBitmapForImage("apng19-ref.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, APNGDecoderDisposePrevious) { - LoadImage("/images/resources/crbug722072.png"); + LoadImage("crbug722072.png"); auto actual_bitmap = GenerateBitmap(3u); - auto expected_bitmap = GenerateBitmapForImage("/images/resources/green.png"); + auto expected_bitmap = GenerateBitmapForImage("green.png"); VerifyBitmap(actual_bitmap, expected_bitmap); } TEST_F(BitmapImageTest, GIFRepetitionCount) { - LoadImage("/images/resources/three-frames_loop-three-times.gif"); + LoadImage("three-frames_loop-three-times.gif"); auto paint_image = image_->PaintImageForCurrentFrame(); EXPECT_EQ(paint_image.repetition_count(), 3); EXPECT_EQ(paint_image.FrameCount(), 3u); } -// This test is failing on all bots. See https://crbug.com/898372 -TEST_F(BitmapImageTest, DISABLED_DecoderAndCacheMipLevels) { +TEST_F(BitmapImageTest, DecoderAndCacheMipLevels) { // Here, we want to test that the mip level calculated by the cc matches // exactly a size supported by the decoder. This is to make sure that the // rounding used in cc matches the rounding in the decoder. The image in this @@ -591,7 +575,7 @@ // we limit to 315 * 237 * 4 bytes, we'll be forcing the maximum scale factor // numerator to be 4 (assuming a denominator of 8). platform_->SetMaxDecodedImageBytes(315 * 237 * 4); - LoadImage("/images/resources/original-cat-420-629x473.jpg"); + LoadImage("original-cat-420-629x473.jpg"); auto paint_image = image_->PaintImageForCurrentFrame(); // The size of the PaintImage is based on the maximum bytes allowed for @@ -838,17 +822,13 @@ const DecodedImageTypeHistogramTest::ParamType kDecodedImageTypeHistogramTestparams[] = { - {"/images/resources/green.jpg", BitmapImageMetrics::kImageJPEG}, - {"/images/resources/" - "palatted-color-png-gamma-one-color-profile.png", + {"green.jpg", BitmapImageMetrics::kImageJPEG}, + {"palatted-color-png-gamma-one-color-profile.png", BitmapImageMetrics::kImagePNG}, - {"/images/resources/animated-10color.gif", - BitmapImageMetrics::kImageGIF}, - {"/images/resources/webp-color-profile-lossy.webp", - BitmapImageMetrics::kImageWebP}, - {"/images/resources/wrong-frame-dimensions.ico", - BitmapImageMetrics::kImageICO}, - {"/images/resources/lenna.bmp", BitmapImageMetrics::kImageBMP}}; + {"animated-10color.gif", BitmapImageMetrics::kImageGIF}, + {"webp-color-profile-lossy.webp", BitmapImageMetrics::kImageWebP}, + {"wrong-frame-dimensions.ico", BitmapImageMetrics::kImageICO}, + {"lenna.bmp", BitmapImageMetrics::kImageBMP}}; INSTANTIATE_TEST_CASE_P( DecodedImageTypeHistogramTest, @@ -864,14 +844,14 @@ const DecodedImageOrientationHistogramTest::ParamType kDecodedImageOrientationHistogramTestParams[] = { - {"/images/resources/exif-orientation-1-ul.jpg", kOriginTopLeft}, - {"/images/resources/exif-orientation-2-ur.jpg", kOriginTopRight}, - {"/images/resources/exif-orientation-3-lr.jpg", kOriginBottomRight}, - {"/images/resources/exif-orientation-4-lol.jpg", kOriginBottomLeft}, - {"/images/resources/exif-orientation-5-lu.jpg", kOriginLeftTop}, - {"/images/resources/exif-orientation-6-ru.jpg", kOriginRightTop}, - {"/images/resources/exif-orientation-7-rl.jpg", kOriginRightBottom}, - {"/images/resources/exif-orientation-8-llo.jpg", kOriginLeftBottom}}; + {"exif-orientation-1-ul.jpg", kOriginTopLeft}, + {"exif-orientation-2-ur.jpg", kOriginTopRight}, + {"exif-orientation-3-lr.jpg", kOriginBottomRight}, + {"exif-orientation-4-lol.jpg", kOriginBottomLeft}, + {"exif-orientation-5-lu.jpg", kOriginLeftTop}, + {"exif-orientation-6-ru.jpg", kOriginRightTop}, + {"exif-orientation-7-rl.jpg", kOriginRightBottom}, + {"exif-orientation-8-llo.jpg", kOriginLeftBottom}}; INSTANTIATE_TEST_CASE_P( DecodedImageOrientationHistogramTest, @@ -887,15 +867,14 @@ const DecodedImageDensityHistogramTest100px::ParamType kDecodedImageDensityHistogramTest100pxParams[] = { // 64x64 too small to report any metric - {"/images/resources/rgb-jpeg-red.jpg", + {"rgb-jpeg-red.jpg", DecodedImageDensityHistogramTest100px::kNoSamplesReported}, // 439x154, 23220 bytes --> 2.74 bpp - {"/images/resources/cropped_mandrill.jpg", 274}, + {"cropped_mandrill.jpg", 274}, // 320x320, 74017 bytes --> 5.78 - {"/images/resources/blue-wheel-srgb-color-profile.jpg", 578}, + {"blue-wheel-srgb-color-profile.jpg", 578}, // 632x475 too big for the 100-399px range. - {"/images/resources/cat.jpg", - DecodedImageDensityHistogramTest100px::kNoSamplesReported}}; + {"cat.jpg", DecodedImageDensityHistogramTest100px::kNoSamplesReported}}; INSTANTIATE_TEST_CASE_P( DecodedImageDensityHistogramTest100px, @@ -911,13 +890,13 @@ const DecodedImageDensityHistogramTest400px::ParamType kDecodedImageDensityHistogramTest400pxParams[] = { // 439x154, only one dimension is big enough. - {"/images/resources/cropped_mandrill.jpg", + {"cropped_mandrill.jpg", DecodedImageDensityHistogramTest400px::kNoSamplesReported}, // 320x320, not big enough. - {"/images/resources/blue-wheel-srgb-color-profile.jpg", + {"blue-wheel-srgb-color-profile.jpg", DecodedImageDensityHistogramTest400px::kNoSamplesReported}, // 632x475, 68826 bytes --> 1.83 - {"/images/resources/cat.jpg", 183}}; + {"cat.jpg", 183}}; INSTANTIATE_TEST_CASE_P( DecodedImageDensityHistogramTest400px,
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc index cbb8fac..ee355a1 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -632,7 +632,7 @@ } base::CheckedNumeric<int> threshold_size = size_.Width(); threshold_size *= size_.Height(); - threshold_size *= CanvasHeuristicParameters::kExpensiveOverdrawThreshold; + threshold_size *= canvas_heuristic_parameters::kExpensiveOverdrawThreshold; if (!threshold_size.IsValid()) { DisableDeferral(kDisableDeferralReasonExpensiveOverdrawHeuristic); return;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h b/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h index d95bad3e..f70a866e 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h +++ b/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h
@@ -9,7 +9,7 @@ namespace blink { -namespace CanvasHeuristicParameters { +namespace canvas_heuristic_parameters { enum { // Disable Deferral overdraw parameters @@ -80,7 +80,7 @@ }; // enum -} // namespace CanvasHeuristicParameters +} // namespace canvas_heuristic_parameters } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc index 2621ad56..983308e 100644 --- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc +++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -646,9 +646,9 @@ ->GetGpuFeatureInfo() .IsWorkaroundEnabled(gpu::DISABLE_2D_CANVAS_AUTO_FLUSH)) { context_flushes.enable = - CanvasHeuristicParameters::kEnableGrContextFlushes; + canvas_heuristic_parameters::kEnableGrContextFlushes; context_flushes.max_draws_before_flush = - CanvasHeuristicParameters::kMaxDrawsBeforeContextFlush; + canvas_heuristic_parameters::kMaxDrawsBeforeContextFlush; } if (ColorParams().NeedsSkColorSpaceXformCanvas()) { canvas_ = std::make_unique<cc::SkiaPaintCanvas>(
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_blend.cc b/third_party/blink/renderer/platform/graphics/filters/fe_blend.cc index dc633651..51aa105 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_blend.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_blend.cc
@@ -46,10 +46,10 @@ } sk_sp<PaintFilter> FEBlend::CreateImageFilter() { - sk_sp<PaintFilter> foreground( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); - sk_sp<PaintFilter> background( - PaintFilterBuilder::Build(InputEffect(1), OperatingInterpolationSpace())); + sk_sp<PaintFilter> foreground(paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace())); + sk_sp<PaintFilter> background(paint_filter_builder::Build( + InputEffect(1), OperatingInterpolationSpace())); SkBlendMode mode = WebCoreCompositeToSkiaComposite(kCompositeSourceOver, mode_); PaintFilter::CropRect crop_rect = GetCropRect();
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.cc b/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.cc index 1b956a6..f16cee8 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.cc
@@ -28,9 +28,9 @@ } sk_sp<PaintFilter> FEBoxReflect::CreateImageFilter() { - return PaintFilterBuilder::BuildBoxReflectFilter( - reflection_, - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); + return paint_filter_builder::BuildBoxReflectFilter( + reflection_, paint_filter_builder::Build(InputEffect(0), + OperatingInterpolationSpace())); } } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc b/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc index a1046f3..3782178a 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc
@@ -153,8 +153,8 @@ } sk_sp<PaintFilter> FEColorMatrix::CreateImageFilter() { - sk_sp<PaintFilter> input( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); + sk_sp<PaintFilter> input(paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace())); sk_sp<SkColorFilter> filter = CreateColorFilter(type_, values_); PaintFilter::CropRect rect = GetCropRect(); return sk_make_sp<ColorFilterPaintFilter>(std::move(filter), std::move(input),
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.cc b/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.cc index ba73a1f8..6aaf717e 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.cc
@@ -134,8 +134,8 @@ } sk_sp<PaintFilter> FEComponentTransfer::CreateImageFilter() { - sk_sp<PaintFilter> input( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); + sk_sp<PaintFilter> input(paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace())); unsigned char r_values[256], g_values[256], b_values[256], a_values[256]; GetValues(r_values, g_values, b_values, a_values);
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_composite.cc b/third_party/blink/renderer/platform/graphics/filters/fe_composite.cc index b62ac9f..cb35b13 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_composite.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_composite.cc
@@ -191,11 +191,11 @@ sk_sp<PaintFilter> FEComposite::CreateImageFilterInternal( bool requires_pm_color_validation) { sk_sp<PaintFilter> foreground( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace(), - !MayProduceInvalidPreMultipliedPixels())); + paint_filter_builder::Build(InputEffect(0), OperatingInterpolationSpace(), + !MayProduceInvalidPreMultipliedPixels())); sk_sp<PaintFilter> background( - PaintFilterBuilder::Build(InputEffect(1), OperatingInterpolationSpace(), - !MayProduceInvalidPreMultipliedPixels())); + paint_filter_builder::Build(InputEffect(1), OperatingInterpolationSpace(), + !MayProduceInvalidPreMultipliedPixels())); PaintFilter::CropRect crop_rect = GetCropRect(); if (type_ == FECOMPOSITE_OPERATOR_ARITHMETIC) {
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc b/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc index 181432e..621548d 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc
@@ -140,8 +140,8 @@ if (!ParametersValid()) return CreateTransparentBlack(); - sk_sp<PaintFilter> input( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); + sk_sp<PaintFilter> input(paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace())); SkISize kernel_size( SkISize::Make(kernel_size_.Width(), kernel_size_.Height())); // parametersValid() above checks that the kernel area fits in int.
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.cc b/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.cc index 79d35126..763d1ebc 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.cc
@@ -113,16 +113,16 @@ } sk_sp<PaintFilter> FEDisplacementMap::CreateImageFilter() { - sk_sp<PaintFilter> color = - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace()); + sk_sp<PaintFilter> color = paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace()); // FEDisplacementMap must be a pass-through filter if // the origin is tainted. See: // https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions. if (InputEffect(1)->OriginTainted()) return color; - sk_sp<PaintFilter> displ = - PaintFilterBuilder::Build(InputEffect(1), OperatingInterpolationSpace()); + sk_sp<PaintFilter> displ = paint_filter_builder::Build( + InputEffect(1), OperatingInterpolationSpace()); SkDisplacementMapEffect::ChannelSelectorType type_x = ToSkiaMode(x_channel_selector_); SkDisplacementMapEffect::ChannelSelectorType type_y =
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.cc b/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.cc index 11399577..2f62c79 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.cc
@@ -75,8 +75,8 @@ } sk_sp<PaintFilter> FEDropShadow::CreateImageFilter() { - sk_sp<PaintFilter> input( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); + sk_sp<PaintFilter> input(paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace())); float dx = GetFilter()->ApplyHorizontalScale(dx_); float dy = GetFilter()->ApplyVerticalScale(dy_); float std_x = GetFilter()->ApplyHorizontalScale(std_x_);
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc b/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc index 53325c61..1c643ab6 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc
@@ -81,8 +81,8 @@ } sk_sp<PaintFilter> FEGaussianBlur::CreateImageFilter() { - sk_sp<PaintFilter> input( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); + sk_sp<PaintFilter> input(paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace())); float std_x = GetFilter()->ApplyHorizontalScale(std_x_); float std_y = GetFilter()->ApplyVerticalScale(std_y_); PaintFilter::CropRect rect = GetCropRect();
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_lighting.cc b/third_party/blink/renderer/platform/graphics/filters/fe_lighting.cc index 4ec7082..232a37cb 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_lighting.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_lighting.cc
@@ -58,8 +58,8 @@ return CreateTransparentBlack(); PaintFilter::CropRect rect = GetCropRect(); Color light_color = AdaptColorToOperatingInterpolationSpace(lighting_color_); - sk_sp<PaintFilter> input( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); + sk_sp<PaintFilter> input(paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace())); switch (light_source_->GetType()) { case LS_DISTANT: { DistantLightSource* distant_light_source =
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_merge.cc b/third_party/blink/renderer/platform/graphics/filters/fe_merge.cc index 57aec41..734f304 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_merge.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_merge.cc
@@ -40,8 +40,8 @@ auto input_refs = std::make_unique<sk_sp<PaintFilter>[]>(size); for (unsigned i = 0; i < size; ++i) { - input_refs[i] = PaintFilterBuilder::Build(InputEffect(i), - OperatingInterpolationSpace()); + input_refs[i] = paint_filter_builder::Build(InputEffect(i), + OperatingInterpolationSpace()); } PaintFilter::CropRect rect = GetCropRect(); return sk_make_sp<MergePaintFilter>(input_refs.get(), size, &rect);
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_morphology.cc b/third_party/blink/renderer/platform/graphics/filters/fe_morphology.cc index 40842ec..d1d640a8 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_morphology.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_morphology.cc
@@ -90,8 +90,8 @@ } sk_sp<PaintFilter> FEMorphology::CreateImageFilter() { - sk_sp<PaintFilter> input( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); + sk_sp<PaintFilter> input(paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace())); int radius_x = clampTo<int>(GetFilter()->ApplyHorizontalScale(radius_x_)); int radius_y = clampTo<int>(GetFilter()->ApplyVerticalScale(radius_y_)); PaintFilter::CropRect rect = GetCropRect();
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_offset.cc b/third_party/blink/renderer/platform/graphics/filters/fe_offset.cc index 01236fd..7db7816 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_offset.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_offset.cc
@@ -67,7 +67,8 @@ return sk_make_sp<OffsetPaintFilter>( SkFloatToScalar(filter->ApplyHorizontalScale(dx_)), SkFloatToScalar(filter->ApplyVerticalScale(dy_)), - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace()), + paint_filter_builder::Build(InputEffect(0), + OperatingInterpolationSpace()), &crop_rect); }
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc b/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc index 31292c4..22b1e32 100644 --- a/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc +++ b/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc
@@ -39,8 +39,8 @@ } sk_sp<PaintFilter> FETile::CreateImageFilter() { - sk_sp<PaintFilter> input( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); + sk_sp<PaintFilter> input(paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace())); if (!input) return nullptr;
diff --git a/third_party/blink/renderer/platform/graphics/filters/image_filter_builder_test.cc b/third_party/blink/renderer/platform/graphics/filters/image_filter_builder_test.cc index 1f15afc0..ad4f8c7 100644 --- a/third_party/blink/renderer/platform/graphics/filters/image_filter_builder_test.cc +++ b/third_party/blink/renderer/platform/graphics/filters/image_filter_builder_test.cc
@@ -69,7 +69,7 @@ reference_filter->SetLastEffect(merge_effect); // Get PaintFilter resulting tree - sk_sp<PaintFilter> filter = PaintFilterBuilder::Build( + sk_sp<PaintFilter> filter = paint_filter_builder::Build( reference_filter->LastEffect(), kInterpolationSpaceSRGB); // Let's check that the resulting tree looks like this :
diff --git a/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.cc b/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.cc index 5761430..77db2ff 100644 --- a/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.cc +++ b/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.cc
@@ -40,7 +40,7 @@ #include "third_party/skia/include/effects/SkXfermodeImageFilter.h" namespace blink { -namespace PaintFilterBuilder { +namespace paint_filter_builder { void PopulateSourceGraphicImageFilters( FilterEffect* source_graphic, @@ -184,5 +184,5 @@ std::move(input), nullptr); } -} // namespace PaintFilterBuilder +} // namespace paint_filter_builder } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h b/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h index bff2da3..f7400e1 100644 --- a/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h +++ b/third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h
@@ -37,7 +37,7 @@ class FilterEffect; class FloatRect; -namespace PaintFilterBuilder { +namespace paint_filter_builder { PLATFORM_EXPORT sk_sp<PaintFilter> Build( FilterEffect*, @@ -61,7 +61,7 @@ const BoxReflection&, sk_sp<PaintFilter> input); -} // namespace PaintFilterBuilder +} // namespace paint_filter_builder } // namespace blink #endif
diff --git a/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc b/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc index 0d08d1e..23dc80c 100644 --- a/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc +++ b/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc
@@ -40,8 +40,8 @@ } sk_sp<PaintFilter> SourceAlpha::CreateImageFilter() { - sk_sp<PaintFilter> source_graphic( - PaintFilterBuilder::Build(InputEffect(0), OperatingInterpolationSpace())); + sk_sp<PaintFilter> source_graphic(paint_filter_builder::Build( + InputEffect(0), OperatingInterpolationSpace())); SkScalar matrix[20] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SK_Scalar1, 0}; sk_sp<SkColorFilter> color_filter =
diff --git a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc index 9e72195..dfd261c 100644 --- a/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc +++ b/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc
@@ -743,7 +743,7 @@ TEST_P(GeometryMapperTest, ReflectionWithPaintOffset) { CompositorFilterOperations filters; - filters.AppendReferenceFilter(PaintFilterBuilder::BuildBoxReflectFilter( + filters.AppendReferenceFilter(paint_filter_builder::BuildBoxReflectFilter( BoxReflection(BoxReflection::kHorizontalReflection, 0), nullptr)); auto effect = CreateFilterEffect(e0(), filters, FloatPoint(100, 100)); local_state.SetEffect(effect.get());
diff --git a/third_party/blink/renderer/platform/heap/gc_task_runner.h b/third_party/blink/renderer/platform/heap/gc_task_runner.h index 5c262d85..b088bd8 100644 --- a/third_party/blink/renderer/platform/heap/gc_task_runner.h +++ b/third_party/blink/renderer/platform/heap/gc_task_runner.h
@@ -51,9 +51,9 @@ DCHECK(!nesting_ || nesting_ == 1); } - void WillProcessTask() override { nesting_++; } + void WillProcessTask(const base::PendingTask&) override { nesting_++; } - void DidProcessTask() override { + void DidProcessTask(const base::PendingTask&) override { // In the production code WebKit::initialize is called from inside the // message loop so we can get didProcessTask() without corresponding // willProcessTask once. This is benign.
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index 802ceea..8c98a0f3 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -753,13 +753,8 @@ DCHECK(!options.cors_flag); params.MutableOptions().cors_flag = CORS::CalculateCORSFlag( params.Url(), origin.get(), resource_request.GetFetchRequestMode()); - // Cross-origin requests are only allowed certain registered schemes. - if (options.cors_flag && !SchemeRegistry::ShouldTreatURLSchemeAsCORSEnabled( - params.Url().Protocol())) { - // This won't create a CORS related console error. - // TODO(yhirano): Fix this. - return ResourceRequestBlockedReason::kOther; - } + // TODO(yhirano): Reject requests for non CORS-enabled schemes. + // See https://crrev.com/c/1298828. resource_request.SetAllowStoredCredentials(CORS::CalculateCredentialsFlag( resource_request.GetFetchCredentialsMode(), CORS::CalculateResponseTainting(
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 6a86bcf..4c5c35a 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -392,6 +392,13 @@ if (request.IsAutomaticUpgrade()) { LogMixedAutoupgradeStatus(MixedContentAutoupgradeStatus::kStarted); } + if (resource_->GetResourceRequest().IsDownloadToNetworkCacheOnly()) { + // The download-to-cache requests are throttled in net/, they are fire-and + // forget, and cannot unregister properly from the scheduler once they are + // finished. + throttle_option = + ResourceLoadScheduler::ThrottleOption::kCanNotBeStoppedOrThrottled; + } scheduler_->Request(this, throttle_option, request.Priority(), request.IntraPriorityValue(), &scheduler_client_id_); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc index 493d44ba..1c8aaca 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -60,6 +60,7 @@ allow_stale_response_(false), cache_mode_(mojom::FetchCacheMode::kDefault), skip_service_worker_(false), + download_to_cache_only_(false), priority_(ResourceLoadPriority::kLowest), intra_priority_value_(0), requestor_id_(0),
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h index f67de80..c0d99958 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -260,6 +260,12 @@ } } + bool IsDownloadToNetworkCacheOnly() const { return download_to_cache_only_; } + + void SetDownloadToNetworkCacheOnly(bool download_to_cache_only) { + download_to_cache_only_ = download_to_cache_only; + } + mojom::RequestContextType GetRequestContext() const { return request_context_; } @@ -421,6 +427,7 @@ bool allow_stale_response_ : 1; mojom::FetchCacheMode cache_mode_; bool skip_service_worker_ : 1; + bool download_to_cache_only_ : 1; ResourceLoadPriority priority_; int intra_priority_value_; int requestor_id_;
diff --git a/third_party/blink/renderer/platform/scheduler/BUILD.gn b/third_party/blink/renderer/platform/scheduler/BUILD.gn index b430215..cc1609aa 100644 --- a/third_party/blink/renderer/platform/scheduler/BUILD.gn +++ b/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -112,6 +112,8 @@ "util/tracing_helper.h", "worker/compositor_metrics_helper.cc", "worker/compositor_metrics_helper.h", + "worker/compositor_thread.cc", + "worker/compositor_thread.h", "worker/compositor_thread_scheduler.cc", "worker/compositor_thread_scheduler.h", "worker/non_main_thread_scheduler_helper.cc",
diff --git a/third_party/blink/renderer/platform/scheduler/common/thread.cc b/third_party/blink/renderer/platform/scheduler/common/thread.cc index 810def0..a0aa1664 100644 --- a/third_party/blink/renderer/platform/scheduler/common/thread.cc +++ b/third_party/blink/renderer/platform/scheduler/common/thread.cc
@@ -9,6 +9,7 @@ #include "build/build_config.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h" +#include "third_party/blink/renderer/platform/scheduler/worker/compositor_thread.h" #include "third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread.h" #include "third_party/blink/renderer/platform/web_task_runner.h" @@ -62,24 +63,6 @@ return compositor_thread; } -// TODO(yutak): This should live in a separate header. -class WebThreadForCompositor : public scheduler::WorkerThread { - public: - explicit WebThreadForCompositor(const ThreadCreationParams& params) - : scheduler::WorkerThread(params) {} - ~WebThreadForCompositor() override = default; - - private: - // WorkerThread: - std::unique_ptr<blink::scheduler::NonMainThreadSchedulerImpl> - CreateNonMainThreadScheduler() override { - return std::make_unique<scheduler::CompositorThreadScheduler>( - base::sequence_manager::CreateSequenceManagerOnCurrentThread()); - } - - DISALLOW_COPY_AND_ASSIGN(WebThreadForCompositor); -}; - } // namespace ThreadCreationParams::ThreadCreationParams(WebThreadType thread_type) @@ -99,20 +82,6 @@ return *this; } -Thread::TaskObserverAdapter::TaskObserverAdapter( - Thread::TaskObserver* task_observer) - : task_observer_(task_observer) {} - -void Thread::TaskObserverAdapter::WillProcessTask( - const base::PendingTask& pending_task) { - task_observer_->WillProcessTask(); -} - -void Thread::TaskObserverAdapter::DidProcessTask( - const base::PendingTask& pending_task) { - task_observer_->DidProcessTask(); -} - std::unique_ptr<Thread> Thread::CreateThread( const ThreadCreationParams& params) { auto thread = std::make_unique<scheduler::WorkerThread>(params); @@ -137,7 +106,8 @@ #if defined(OS_ANDROID) params.thread_options.priority = base::ThreadPriority::DISPLAY; #endif - auto compositor_thread = std::make_unique<WebThreadForCompositor>(params); + auto compositor_thread = + std::make_unique<scheduler::CompositorThread>(params); compositor_thread->Init(); UpdateThreadTLSAndWait(compositor_thread.get()); GetCompositorThread() = std::move(compositor_thread); @@ -166,9 +136,7 @@ Thread::Thread() = default; -Thread::~Thread() { - DCHECK(task_observer_map_.IsEmpty()); -} +Thread::~Thread() = default; bool Thread::IsCurrentThread() const { return ThreadTLSSlot() == this; @@ -176,21 +144,12 @@ void Thread::AddTaskObserver(TaskObserver* task_observer) { CHECK(IsCurrentThread()); - auto add_result = task_observer_map_.insert(task_observer, nullptr); - if (!add_result.stored_value->value) { - add_result.stored_value->value = - std::make_unique<TaskObserverAdapter>(task_observer); - } - Scheduler()->AddTaskObserver(add_result.stored_value->value.get()); + Scheduler()->AddTaskObserver(task_observer); } void Thread::RemoveTaskObserver(TaskObserver* task_observer) { CHECK(IsCurrentThread()); - auto iterator = task_observer_map_.find(task_observer); - if (iterator == task_observer_map_.end()) - return; - Scheduler()->RemoveTaskObserver(iterator->value.get()); - task_observer_map_.erase(iterator); + Scheduler()->RemoveTaskObserver(task_observer); } #if defined(OS_WIN)
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 c6daad5a..8398bbb 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
@@ -452,6 +452,8 @@ // when recovering from debugger JavaScript statetment. case TaskType::kInternalTest: return UnpausableTaskQueueTraits(); + case TaskType::kInternalTranslation: + return ForegroundOnlyTaskQueueTraits(); case TaskType::kDeprecatedNone: case TaskType::kMainThreadTaskQueueV8: case TaskType::kMainThreadTaskQueueCompositor: @@ -704,7 +706,8 @@ if (!voter) return; DCHECK(parent_page_scheduler_); - bool queue_paused = frame_paused_ && queue->CanBePaused(); + bool queue_disabled = false; + queue_disabled |= frame_paused_ && queue->CanBePaused(); // Per-frame freezable task queues will be frozen after 5 mins in background // on Android, and if the browser freezes the page in the background. They // will be resumed when the page is visible. @@ -713,7 +716,12 @@ // Override freezing if keep-active is true. if (queue_frozen && !queue->FreezeWhenKeepActive()) queue_frozen = !parent_page_scheduler_->KeepActive(); - voter->SetQueueEnabled(!queue_paused && !queue_frozen); + queue_disabled |= queue_frozen; + // Per-frame freezable queues of tasks which are specified as getting frozen + // immediately when their frame becomes invisible get frozen. They will be + // resumed when the frame becomes visible again. + queue_disabled |= !frame_visible_ && !queue->CanRunInBackground(); + voter->SetQueueEnabled(!queue_disabled); } SchedulingLifecycleState FrameSchedulerImpl::CalculateLifecycleState( @@ -979,5 +987,10 @@ return QueueTraits(); } +MainThreadTaskQueue::QueueTraits +FrameSchedulerImpl::ForegroundOnlyTaskQueueTraits() { + return ThrottleableTaskQueueTraits().SetCanRunInBackground(false); +} + } // namespace scheduler } // namespace blink
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 b0aada2..2513a49f 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
@@ -244,6 +244,7 @@ static MainThreadTaskQueue::QueueTraits DeferrableTaskQueueTraits(); static MainThreadTaskQueue::QueueTraits PausableTaskQueueTraits(); static MainThreadTaskQueue::QueueTraits UnpausableTaskQueueTraits(); + static MainThreadTaskQueue::QueueTraits ForegroundOnlyTaskQueueTraits(); const FrameScheduler::FrameType frame_type_;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc index a9855ee1..aa6a0979 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -115,6 +115,11 @@ return NonLoadingTaskQueue(FrameSchedulerImpl::UnpausableTaskQueueTraits()); } + scoped_refptr<TaskQueue> ForegroundOnlyTaskQueue() { + return NonLoadingTaskQueue( + FrameSchedulerImpl::ForegroundOnlyTaskQueueTraits()); + } + scoped_refptr<MainThreadTaskQueue> GetTaskQueue(TaskType type) { return frame_scheduler_->GetTaskQueue(type); } @@ -369,6 +374,24 @@ EXPECT_EQ(5, counter); } +TEST_F(FrameSchedulerImplTest, FreezeForegroundOnlyTasks) { + int counter = 0; + ForegroundOnlyTaskQueue()->task_runner()->PostTask( + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + + page_scheduler_->SetPageVisible(false); + + EXPECT_EQ(0, counter); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, counter); + + page_scheduler_->SetPageVisible(true); + + EXPECT_EQ(0, counter); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, counter); +} + TEST_F(FrameSchedulerImplStopNonTimersInBackgroundEnabledTest, PageFreezeAndUnfreezeFlagEnabled) { int counter = 0; @@ -394,7 +417,7 @@ page_scheduler_->SetPageFrozen(false); EXPECT_EQ(1, counter); - // Same as RunUntilIdle but also advances the cock if necessary. + // Same as RunUntilIdle but also advances the clock if necessary. task_environment_.FastForwardUntilNoTasksRemain(); EXPECT_EQ(5, counter); } @@ -1581,6 +1604,8 @@ EXPECT_EQ(GetTaskQueue(TaskType::kNetworking), LoadingTaskQueue()); EXPECT_EQ(GetTaskQueue(TaskType::kNetworkingControl), LoadingControlTaskQueue()); + EXPECT_EQ(GetTaskQueue(TaskType::kInternalTranslation), + ForegroundOnlyTaskQueue()); } class ThrottleAndFreezeTaskTypesExperimentTest : public FrameSchedulerImplTest {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h index 8c277499..232e05b 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
@@ -97,7 +97,8 @@ : can_be_deferred(false), can_be_throttled(false), can_be_paused(false), - can_be_frozen(false) {} + can_be_frozen(false), + can_run_in_background(true) {} QueueTraits(const QueueTraits&) = default; @@ -121,11 +122,17 @@ return *this; } + QueueTraits SetCanRunInBackground(bool value) { + can_run_in_background = value; + return *this; + } + bool operator==(const QueueTraits& other) const { return can_be_deferred == other.can_be_deferred && can_be_throttled == other.can_be_throttled && can_be_paused == other.can_be_paused && - can_be_frozen == other.can_be_frozen; + can_be_frozen == other.can_be_frozen && + can_run_in_background == other.can_run_in_background; } // Return a key suitable for WTF::HashMap. @@ -136,6 +143,7 @@ key |= can_be_throttled << 2; key |= can_be_paused << 3; key |= can_be_frozen << 4; + key |= can_run_in_background << 5; return key; } @@ -143,6 +151,7 @@ bool can_be_throttled : 1; bool can_be_paused : 1; bool can_be_frozen : 1; + bool can_run_in_background : 1; }; struct QueueCreationParams { @@ -186,6 +195,11 @@ return *this; } + QueueCreationParams SetCanRunInBackground(bool value) { + queue_traits = queue_traits.SetCanRunInBackground(value); + return *this; + } + QueueCreationParams SetQueueTraits(QueueTraits value) { queue_traits = value; return *this; @@ -241,6 +255,10 @@ bool CanBeFrozen() const { return queue_traits_.can_be_frozen; } + bool CanRunInBackground() const { + return queue_traits_.can_run_in_background; + } + bool FreezeWhenKeepActive() const { return freeze_when_keep_active_; } QueueTraits GetQueueTraits() const { return queue_traits_; }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc index b1399eb7..774a2d9 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_unittest.cc
@@ -27,6 +27,8 @@ const int kWorkBatchSize = 2; +using ::testing::_; + class MockTask { public: MOCK_METHOD0(Run, void()); @@ -34,8 +36,8 @@ class MockTaskObserver : public Thread::TaskObserver { public: - MOCK_METHOD0(WillProcessTask, void()); - MOCK_METHOD0(DidProcessTask, void()); + MOCK_METHOD1(WillProcessTask, void(const base::PendingTask&)); + MOCK_METHOD1(DidProcessTask, void(const base::PendingTask&)); }; class MainThreadTest : public testing::Test { @@ -79,9 +81,9 @@ { testing::InSequence sequence; - EXPECT_CALL(observer, WillProcessTask()); + EXPECT_CALL(observer, WillProcessTask(_)); EXPECT_CALL(task, Run()); - EXPECT_CALL(observer, DidProcessTask()); + EXPECT_CALL(observer, DidProcessTask(_)); } message_loop_.task_runner()->PostTask( @@ -98,9 +100,9 @@ SetWorkBatchSizeForTesting(kWorkBatchSize); { testing::InSequence sequence; - EXPECT_CALL(observer, WillProcessTask()); + EXPECT_CALL(observer, WillProcessTask(_)); EXPECT_CALL(task, Run()); - EXPECT_CALL(observer, DidProcessTask()); + EXPECT_CALL(observer, DidProcessTask(_)); } message_loop_.task_runner()->PostTask( @@ -118,13 +120,13 @@ SetWorkBatchSizeForTesting(kWorkBatchSize); { testing::InSequence sequence; - EXPECT_CALL(observer, WillProcessTask()); + EXPECT_CALL(observer, WillProcessTask(_)); EXPECT_CALL(task1, Run()); - EXPECT_CALL(observer, DidProcessTask()); + EXPECT_CALL(observer, DidProcessTask(_)); - EXPECT_CALL(observer, WillProcessTask()); + EXPECT_CALL(observer, WillProcessTask(_)); EXPECT_CALL(task2, Run()); - EXPECT_CALL(observer, DidProcessTask()); + EXPECT_CALL(observer, DidProcessTask(_)); } message_loop_.task_runner()->PostTask( @@ -145,17 +147,17 @@ SetWorkBatchSizeForTesting(kWorkBatchSize); { testing::InSequence sequence; - EXPECT_CALL(observer, WillProcessTask()); + EXPECT_CALL(observer, WillProcessTask(_)); EXPECT_CALL(task1, Run()); - EXPECT_CALL(observer, DidProcessTask()); + EXPECT_CALL(observer, DidProcessTask(_)); - EXPECT_CALL(observer, WillProcessTask()); + EXPECT_CALL(observer, WillProcessTask(_)); EXPECT_CALL(task2, Run()); - EXPECT_CALL(observer, DidProcessTask()); + EXPECT_CALL(observer, DidProcessTask(_)); - EXPECT_CALL(observer, WillProcessTask()); + EXPECT_CALL(observer, WillProcessTask(_)); EXPECT_CALL(task3, Run()); - EXPECT_CALL(observer, DidProcessTask()); + EXPECT_CALL(observer, DidProcessTask(_)); } message_loop_.task_runner()->PostTask( @@ -186,14 +188,14 @@ testing::InSequence sequence; // One callback for EnterRunLoop. - EXPECT_CALL(observer, WillProcessTask()); + EXPECT_CALL(observer, WillProcessTask(_)); // A pair for ExitRunLoopTask. - EXPECT_CALL(observer, WillProcessTask()); - EXPECT_CALL(observer, DidProcessTask()); + EXPECT_CALL(observer, WillProcessTask(_)); + EXPECT_CALL(observer, DidProcessTask(_)); // A final callback for EnterRunLoop. - EXPECT_CALL(observer, DidProcessTask()); + EXPECT_CALL(observer, DidProcessTask(_)); } message_loop_.task_runner()->PostTask(
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc b/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc index f81e030a..75feaa7 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
@@ -117,6 +117,8 @@ return "WorkerThreadTaskQueueCompositor"; case TaskType::kWorkerAnimation: return "WorkerAnimation"; + case TaskType::kInternalTranslation: + return "InternalTranslation"; case TaskType::kCount: return "Count"; }
diff --git a/third_party/blink/renderer/platform/scheduler/public/thread.h b/third_party/blink/renderer/platform/scheduler/public/thread.h index 780e2cf..0774757 100644 --- a/third_party/blink/renderer/platform/scheduler/public/thread.h +++ b/third_party/blink/renderer/platform/scheduler/public/thread.h
@@ -32,7 +32,6 @@ #include "base/threading/thread.h" #include "third_party/blink/public/platform/web_thread_type.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" namespace base { class SingleThreadTaskRunner; @@ -78,13 +77,8 @@ // An IdleTask is expected to complete before the deadline it is passed. using IdleTask = base::OnceCallback<void(base::TimeTicks deadline)>; - // TODO(yutak): Migrate to base::MessageLoop::TaskObserver. - class PLATFORM_EXPORT TaskObserver { - public: - virtual ~TaskObserver() = default; - virtual void WillProcessTask() = 0; - virtual void DidProcessTask() = 0; - }; + // TaskObserver is an observer fired before and after a task is executed. + using TaskObserver = base::MessageLoop::TaskObserver; // Creates a new thread. This may be called from a non-main thread (e.g. // nested Web workers). @@ -148,20 +142,6 @@ virtual ThreadScheduler* Scheduler() = 0; private: - class TaskObserverAdapter : public base::MessageLoop::TaskObserver { - public: - explicit TaskObserverAdapter(Thread::TaskObserver*); - ~TaskObserverAdapter() override = default; - void WillProcessTask(const base::PendingTask&) override; - void DidProcessTask(const base::PendingTask&) override; - - private: - Thread::TaskObserver* task_observer_; - }; - - using TaskObserverMap = - WTF::HashMap<TaskObserver*, std::unique_ptr<TaskObserverAdapter>>; - // For Platform and ScopedMainThreadOverrider. Return the thread object // previously set (if any). // @@ -173,8 +153,6 @@ // used only in Platform, and other users should ignore this. virtual bool IsSimpleMainThread() const { return false; } - TaskObserverMap task_observer_map_; - DISALLOW_COPY_AND_ASSIGN(Thread); };
diff --git a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread.cc b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread.cc new file mode 100644 index 0000000..0236b1f --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread.cc
@@ -0,0 +1,25 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/scheduler/worker/compositor_thread.h" + +#include "base/task/sequence_manager/sequence_manager.h" +#include "third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h" + +namespace blink { +namespace scheduler { + +CompositorThread::CompositorThread(const ThreadCreationParams& params) + : WorkerThread(params) {} + +CompositorThread::~CompositorThread() = default; + +std::unique_ptr<NonMainThreadSchedulerImpl> +CompositorThread::CreateNonMainThreadScheduler() { + return std::make_unique<CompositorThreadScheduler>( + base::sequence_manager::CreateSequenceManagerOnCurrentThread()); +} + +} // namespace scheduler +} // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread.h b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread.h new file mode 100644 index 0000000..d6c7025a --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread.h
@@ -0,0 +1,29 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_COMPOSITOR_THREAD_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_COMPOSITOR_THREAD_H_ + +#include "base/macros.h" +#include "third_party/blink/renderer/platform/scheduler/worker/worker_thread.h" + +namespace blink { +namespace scheduler { + +class PLATFORM_EXPORT CompositorThread : public WorkerThread { + public: + explicit CompositorThread(const ThreadCreationParams& params); + ~CompositorThread() override; + + private: + std::unique_ptr<NonMainThreadSchedulerImpl> CreateNonMainThreadScheduler() + override; + + DISALLOW_COPY_AND_ASSIGN(CompositorThread); +}; + +} // namespace scheduler +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_COMPOSITOR_THREAD_H_
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc index ab18ef4..32e37691 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
@@ -147,6 +147,7 @@ case TaskType::kWorkerThreadTaskQueueCompositor: case TaskType::kExperimentalWebSchedulingUserInteraction: case TaskType::kExperimentalWebSchedulingBestEffort: + case TaskType::kInternalTranslation: case TaskType::kCount: NOTREACHED(); break;
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc index 44389dba..547e4b6 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_unittest.cc
@@ -38,9 +38,13 @@ ~TestObserver() override = default; - void WillProcessTask() override { calls_->append(" willProcessTask"); } + void WillProcessTask(const base::PendingTask&) override { + calls_->append(" willProcessTask"); + } - void DidProcessTask() override { calls_->append(" didProcessTask"); } + void DidProcessTask(const base::PendingTask&) override { + calls_->append(" didProcessTask"); + } private: std::string* calls_; // NOT OWNED
diff --git a/third_party/WebKit/LayoutTests/images/resources/anim_none.gif b/third_party/blink/renderer/platform/testing/data/anim_none.gif similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/anim_none.gif rename to third_party/blink/renderer/platform/testing/data/anim_none.gif Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/animated-10color.gif b/third_party/blink/renderer/platform/testing/data/animated-10color.gif new file mode 100644 index 0000000..64b0c43 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/animated-10color.gif Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng00-ref.png b/third_party/blink/renderer/platform/testing/data/apng00-ref.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng00-ref.png rename to third_party/blink/renderer/platform/testing/data/apng00-ref.png Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/apng00.png b/third_party/blink/renderer/platform/testing/data/apng00.png new file mode 100644 index 0000000..5fd0078 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/apng00.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng01-ref.png b/third_party/blink/renderer/platform/testing/data/apng01-ref.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng01-ref.png rename to third_party/blink/renderer/platform/testing/data/apng01-ref.png Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/apng01.png b/third_party/blink/renderer/platform/testing/data/apng01.png new file mode 100644 index 0000000..96d40571 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/apng01.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng02-ref.png b/third_party/blink/renderer/platform/testing/data/apng02-ref.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng02-ref.png rename to third_party/blink/renderer/platform/testing/data/apng02-ref.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng02.png b/third_party/blink/renderer/platform/testing/data/apng02.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng02.png rename to third_party/blink/renderer/platform/testing/data/apng02.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng04-ref.png b/third_party/blink/renderer/platform/testing/data/apng04-ref.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng04-ref.png rename to third_party/blink/renderer/platform/testing/data/apng04-ref.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng04.png b/third_party/blink/renderer/platform/testing/data/apng04.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng04.png rename to third_party/blink/renderer/platform/testing/data/apng04.png Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/apng08-ref.png b/third_party/blink/renderer/platform/testing/data/apng08-ref.png new file mode 100644 index 0000000..91bf2b9d --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/apng08-ref.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng08.png b/third_party/blink/renderer/platform/testing/data/apng08.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng08.png rename to third_party/blink/renderer/platform/testing/data/apng08.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng10-ref.png b/third_party/blink/renderer/platform/testing/data/apng10-ref.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng10-ref.png rename to third_party/blink/renderer/platform/testing/data/apng10-ref.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng10.png b/third_party/blink/renderer/platform/testing/data/apng10.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng10.png rename to third_party/blink/renderer/platform/testing/data/apng10.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng11-ref.png b/third_party/blink/renderer/platform/testing/data/apng11-ref.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng11-ref.png rename to third_party/blink/renderer/platform/testing/data/apng11-ref.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng11.png b/third_party/blink/renderer/platform/testing/data/apng11.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng11.png rename to third_party/blink/renderer/platform/testing/data/apng11.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng12-ref.png b/third_party/blink/renderer/platform/testing/data/apng12-ref.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng12-ref.png rename to third_party/blink/renderer/platform/testing/data/apng12-ref.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng12.png b/third_party/blink/renderer/platform/testing/data/apng12.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng12.png rename to third_party/blink/renderer/platform/testing/data/apng12.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng14-ref.png b/third_party/blink/renderer/platform/testing/data/apng14-ref.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng14-ref.png rename to third_party/blink/renderer/platform/testing/data/apng14-ref.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng14.png b/third_party/blink/renderer/platform/testing/data/apng14.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng14.png rename to third_party/blink/renderer/platform/testing/data/apng14.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng18-ref.png b/third_party/blink/renderer/platform/testing/data/apng18-ref.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng18-ref.png rename to third_party/blink/renderer/platform/testing/data/apng18-ref.png Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/apng18.png b/third_party/blink/renderer/platform/testing/data/apng18.png new file mode 100644 index 0000000..f0274e22 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/apng18.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng19-ref.png b/third_party/blink/renderer/platform/testing/data/apng19-ref.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng19-ref.png rename to third_party/blink/renderer/platform/testing/data/apng19-ref.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/apng19.png b/third_party/blink/renderer/platform/testing/data/apng19.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/apng19.png rename to third_party/blink/renderer/platform/testing/data/apng19.png Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/blue-wheel-srgb-color-profile.jpg b/third_party/blink/renderer/platform/testing/data/blue-wheel-srgb-color-profile.jpg new file mode 100644 index 0000000..4df68d3 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/blue-wheel-srgb-color-profile.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/cat.jpg b/third_party/blink/renderer/platform/testing/data/cat.jpg new file mode 100644 index 0000000..e24b629 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/cat.jpg Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/crbug722072.png b/third_party/blink/renderer/platform/testing/data/crbug722072.png similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/crbug722072.png rename to third_party/blink/renderer/platform/testing/data/crbug722072.png Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/cropped_mandrill.jpg b/third_party/blink/renderer/platform/testing/data/cropped_mandrill.jpg new file mode 100644 index 0000000..e1a233ad --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/cropped_mandrill.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/exif-orientation-1-ul.jpg b/third_party/blink/renderer/platform/testing/data/exif-orientation-1-ul.jpg new file mode 100644 index 0000000..102e82c --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/exif-orientation-1-ul.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/exif-orientation-2-ur.jpg b/third_party/blink/renderer/platform/testing/data/exif-orientation-2-ur.jpg new file mode 100644 index 0000000..70c14d4 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/exif-orientation-2-ur.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/exif-orientation-3-lr.jpg b/third_party/blink/renderer/platform/testing/data/exif-orientation-3-lr.jpg new file mode 100644 index 0000000..a0a718f --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/exif-orientation-3-lr.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/exif-orientation-4-lol.jpg b/third_party/blink/renderer/platform/testing/data/exif-orientation-4-lol.jpg new file mode 100644 index 0000000..c75ea6a --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/exif-orientation-4-lol.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/exif-orientation-5-lu.jpg b/third_party/blink/renderer/platform/testing/data/exif-orientation-5-lu.jpg new file mode 100644 index 0000000..7f96232c --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/exif-orientation-5-lu.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/exif-orientation-6-ru.jpg b/third_party/blink/renderer/platform/testing/data/exif-orientation-6-ru.jpg new file mode 100644 index 0000000..deffbcd --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/exif-orientation-6-ru.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/exif-orientation-7-rl.jpg b/third_party/blink/renderer/platform/testing/data/exif-orientation-7-rl.jpg new file mode 100644 index 0000000..8da2ae2 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/exif-orientation-7-rl.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/exif-orientation-8-llo.jpg b/third_party/blink/renderer/platform/testing/data/exif-orientation-8-llo.jpg new file mode 100644 index 0000000..294c4b8 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/exif-orientation-8-llo.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/gif-loop-count.gif b/third_party/blink/renderer/platform/testing/data/gif-loop-count.gif new file mode 100644 index 0000000..2b51a62 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/gif-loop-count.gif Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/green-red-blue-yellow-animated.gif b/third_party/blink/renderer/platform/testing/data/green-red-blue-yellow-animated.gif similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/green-red-blue-yellow-animated.gif rename to third_party/blink/renderer/platform/testing/data/green-red-blue-yellow-animated.gif Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/green.jpg b/third_party/blink/renderer/platform/testing/data/green.jpg new file mode 100644 index 0000000..f5f700b --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/green.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/green.png b/third_party/blink/renderer/platform/testing/data/green.png new file mode 100644 index 0000000..28a1faa --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/green.png Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/icc-v2-gbr.jpg b/third_party/blink/renderer/platform/testing/data/icc-v2-gbr.jpg new file mode 100644 index 0000000..0984e9b3 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/icc-v2-gbr.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/lenna.bmp b/third_party/blink/renderer/platform/testing/data/lenna.bmp new file mode 100644 index 0000000..8851ea9 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/lenna.bmp Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/original-cat-420-629x473.jpg b/third_party/blink/renderer/platform/testing/data/original-cat-420-629x473.jpg similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/original-cat-420-629x473.jpg rename to third_party/blink/renderer/platform/testing/data/original-cat-420-629x473.jpg Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/palatted-color-png-gamma-one-color-profile.png b/third_party/blink/renderer/platform/testing/data/palatted-color-png-gamma-one-color-profile.png new file mode 100644 index 0000000..ad7c3dc --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/palatted-color-png-gamma-one-color-profile.png Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/rgb-jpeg-red.jpg b/third_party/blink/renderer/platform/testing/data/rgb-jpeg-red.jpg new file mode 100644 index 0000000..9a69dbbe --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/rgb-jpeg-red.jpg Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/resources/three-frames_loop-three-times.gif b/third_party/blink/renderer/platform/testing/data/three-frames_loop-three-times.gif similarity index 100% rename from third_party/WebKit/LayoutTests/images/resources/three-frames_loop-three-times.gif rename to third_party/blink/renderer/platform/testing/data/three-frames_loop-three-times.gif Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/webp-color-profile-lossy.webp b/third_party/blink/renderer/platform/testing/data/webp-color-profile-lossy.webp new file mode 100644 index 0000000..fdff0a9 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/webp-color-profile-lossy.webp Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/data/wrong-frame-dimensions.ico b/third_party/blink/renderer/platform/testing/data/wrong-frame-dimensions.ico new file mode 100644 index 0000000..dee64c74 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/wrong-frame-dimensions.ico Binary files differ
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index b7bab87..d956c2f 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -159,6 +159,9 @@ # PartitionAlloc 'base::PartitionFree', + # For MessageLoop::TaskObserver. + 'base::PendingTask', + # cc painting types. 'cc::PaintCanvas', 'cc::PaintFlags', @@ -217,12 +220,14 @@ 'url::.+', # Nested namespaces under the blink namespace + 'canvas_heuristic_parameters::.+', 'cssvalue::.+', 'encoding::.+', 'event_handling_util::.+', 'event_util::.+', 'media_constraints_impl::.+', 'network_utils::.+', + 'paint_filter_builder::.+', 'root_scroller_util::.+', 'scheduler::.+', 'touch_action_util::.+',
diff --git a/third_party/flatbuffers/BUILD.gn b/third_party/flatbuffers/BUILD.gn index f02db1d0..87c4ca20 100644 --- a/third_party/flatbuffers/BUILD.gn +++ b/third_party/flatbuffers/BUILD.gn
@@ -16,7 +16,9 @@ # The part of FlatBuffers that Chrome is interested in. source_set("flatbuffers") { sources = [ + "src/include/flatbuffers/base.h", "src/include/flatbuffers/flatbuffers.h", + "src/include/flatbuffers/stl_emulation.h", ] configs -= [ "//build/config/compiler:chromium_code" ] @@ -38,7 +40,6 @@ "src/grpc/src/compiler/java_generator.cc", "src/grpc/src/compiler/java_generator.h", "src/grpc/src/compiler/schema_interface.h", - "src/include/flatbuffers/base.h", "src/include/flatbuffers/code_generators.h", "src/include/flatbuffers/flatbuffers.h", "src/include/flatbuffers/flatc.h", @@ -50,7 +51,6 @@ "src/include/flatbuffers/reflection.h", "src/include/flatbuffers/reflection_generated.h", "src/include/flatbuffers/registry.h", - "src/include/flatbuffers/stl_emulation.h", "src/include/flatbuffers/util.h", "src/src/code_generators.cpp", "src/src/flatc.cpp",
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 5bea2b74..7d081ff 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-9-1-277 -Revision: 428854931e683b405da20d2f404073f51c5a183d +Version: VER-2-9-1-279 +Revision: f56830ed406f90f6f53ee6367f2068a0f27bf90b License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses" License File: src/docs/FTL.TXT
diff --git a/third_party/libaddressinput/BUILD.gn b/third_party/libaddressinput/BUILD.gn index f540dee..a1de923 100644 --- a/third_party/libaddressinput/BUILD.gn +++ b/third_party/libaddressinput/BUILD.gn
@@ -43,23 +43,39 @@ # This target provides basic functionality which is cooked into the build. static_library("util") { sources = [ - "chromium/addressinput_util.cc", "chromium/json.cc", "src/cpp/src/address_data.cc", "src/cpp/src/address_field.cc", "src/cpp/src/address_field_util.cc", + "src/cpp/src/address_field_util.h", "src/cpp/src/address_formatter.cc", "src/cpp/src/address_metadata.cc", "src/cpp/src/address_ui.cc", "src/cpp/src/format_element.cc", + "src/cpp/src/format_element.h", + "src/cpp/src/grit.h", "src/cpp/src/language.cc", + "src/cpp/src/language.h", "src/cpp/src/localization.cc", "src/cpp/src/lookup_key.cc", + "src/cpp/src/lookup_key.h", "src/cpp/src/region_data_constants.cc", + "src/cpp/src/region_data_constants.h", "src/cpp/src/rule.cc", + "src/cpp/src/rule.h", "src/cpp/src/util/cctype_tolower_equal.cc", + "src/cpp/src/util/cctype_tolower_equal.h", + "src/cpp/src/util/json.h", + "src/cpp/src/util/lru_cache_using_std.h", + "src/cpp/src/util/md5.cc", + "src/cpp/src/util/md5.h", + "src/cpp/src/util/re2ptr.h", + "src/cpp/src/util/size.h", + "src/cpp/src/util/string_compare.h", "src/cpp/src/util/string_split.cc", + "src/cpp/src/util/string_split.h", "src/cpp/src/util/string_util.cc", + "src/cpp/src/util/string_util.h", ] configs -= [ "//build/config/compiler:chromium_code" ] @@ -85,6 +101,8 @@ # for validation rules. static_library("libaddressinput") { sources = [ + "chromium/addressinput_util.cc", + "chromium/addressinput_util.h", "chromium/chrome_address_validator.cc", "chromium/chrome_address_validator.h", "chromium/chrome_metadata_source.cc", @@ -95,6 +113,7 @@ "chromium/fallback_data_store.h", "chromium/input_suggester.cc", "chromium/input_suggester.h", + "chromium/storage_test_runner.h", "chromium/string_compare.cc", "chromium/trie.cc", "chromium/trie.h", @@ -105,16 +124,25 @@ "src/cpp/src/null_storage.cc", "src/cpp/src/ondemand_supplier.cc", "src/cpp/src/ondemand_supply_task.cc", + "src/cpp/src/ondemand_supply_task.h", "src/cpp/src/post_box_matchers.cc", + "src/cpp/src/post_box_matchers.h", "src/cpp/src/preload_supplier.cc", "src/cpp/src/region_data.cc", "src/cpp/src/region_data_builder.cc", "src/cpp/src/retriever.cc", + "src/cpp/src/retriever.h", "src/cpp/src/rule_retriever.cc", - "src/cpp/src/util/md5.cc", + "src/cpp/src/rule_retriever.h", "src/cpp/src/validating_storage.cc", + "src/cpp/src/validating_storage.h", "src/cpp/src/validating_util.cc", + "src/cpp/src/validating_util.h", "src/cpp/src/validation_task.cc", + "src/cpp/src/validation_task.h", + "src/cpp/test/fake_storage.h", + "src/cpp/test/mock_source.h", + "src/cpp/test/testdata_source.h", ] configs -= [ "//build/config/compiler:chromium_code" ] @@ -242,6 +270,7 @@ ":libaddressinput", ":strings", ":test_support", + ":util", "//base/test:run_all_unittests", "//components/prefs", "//mojo/core/embedder",
diff --git a/third_party/libjingle_xmpp/BUILD.gn b/third_party/libjingle_xmpp/BUILD.gn index 14a45c1..5755001 100644 --- a/third_party/libjingle_xmpp/BUILD.gn +++ b/third_party/libjingle_xmpp/BUILD.gn
@@ -56,7 +56,6 @@ ] all_dependent_configs = [ ":libjingle_xmpp_common_config", - "//third_party/webrtc_overrides:jingle_unexported_configs", ] }
diff --git a/third_party/webrtc_overrides/BUILD.gn b/third_party/webrtc_overrides/BUILD.gn index 7fe842b9..731dd68e 100644 --- a/third_party/webrtc_overrides/BUILD.gn +++ b/third_party/webrtc_overrides/BUILD.gn
@@ -10,24 +10,6 @@ ] } -config("jingle_unexported_configs") { - include_dirs = [ - "../../third_party/webrtc_overrides", - "../../testing/gtest/include", - "../../third_party/libyuv/include", - "../../third_party/usrsctp/usrsctplib", - "../../third_party/webrtc", - ] -} - -config("jingle_public_configs") { - include_dirs = [ - "../../third_party/webrtc_overrides", - "../../testing/gtest/include", - "../../third_party/webrtc", - ] -} - source_set("webrtc") { public_deps = [ # TODO(kjellander): Start cleaning up this target as soon as @@ -39,10 +21,6 @@ "//third_party/webrtc/p2p:rtc_p2p", ] - if (is_win) { - cflags = [ "/wd4005" ] - } - # When Chromium is built for NACL or Chromecast, WebRTC provides a # field_trial implementation so there is no need to depend on # ":field_trial". @@ -61,11 +39,9 @@ } configs += [ - ":jingle_unexported_configs", "//third_party/webrtc:common_config", ] public_configs = [ - ":jingle_public_configs", "//third_party/webrtc:common_inherited_config", ] } @@ -76,11 +52,9 @@ "init_webrtc.h", ] configs += [ - ":jingle_unexported_configs", "//third_party/webrtc:common_config", ] public_configs = [ - ":jingle_public_configs", "//third_party/webrtc:common_inherited_config", ] public_deps = [ @@ -115,11 +89,9 @@ source_set("libjingle_webrtc_common") { configs += [ - ":jingle_unexported_configs", "//third_party/webrtc:common_config", ] public_configs = [ - ":jingle_public_configs", "//third_party/webrtc:common_inherited_config", ]
diff --git a/tools/cfi/blacklist.txt b/tools/cfi/blacklist.txt index 0bf9292..b3ae491e 100644 --- a/tools/cfi/blacklist.txt +++ b/tools/cfi/blacklist.txt
@@ -20,10 +20,6 @@ type:*RemoveIUnknown* src:*atlcomcli.h -# invalid downcasts for IPC messages -# https://crbug.com/520760 -src:*nacl_message_scanner.cc* - # src/base/win/event_trace_provider_unittest.cc type:*EtwTraceProvider*
diff --git a/tools/determinism/deterministic_build_whitelist.pyl b/tools/determinism/deterministic_build_whitelist.pyl index 84fb67f..61cef57 100644 --- a/tools/determinism/deterministic_build_whitelist.pyl +++ b/tools/determinism/deterministic_build_whitelist.pyl
@@ -30,10 +30,6 @@ # https://crbug.com/330263 'linux': [ 'ppapi_nacl_tests_pnacl_newlib_x64.nexe', - - # TODO(tikuta): Remove this when crbug.com/870611 is fixed. - 'remoting-webapp.v2.zip', - 'zucchini_apply_fuzzer_seed_corpus.zip', 'browser_tests.isolated',
diff --git a/tools/gritsettings/translation_expectations.pyl b/tools/gritsettings/translation_expectations.pyl index 957e685..bc6da827 100644 --- a/tools/gritsettings/translation_expectations.pyl +++ b/tools/gritsettings/translation_expectations.pyl
@@ -20,9 +20,12 @@ "te", "th", "tr", "uk", "vi", "zh-CN", "zh-TW", ], "files": [ + "android_webview/java/strings/android_webview_strings.grd", "android_webview/ui/aw_strings.grd", "ash/ash_strings.grd", "ash/components/ash_components_strings.grd", + "chrome/android/java/strings/android_chrome_strings.grd", + "chrome/android/webapk/strings/android_webapk_strings.grd", "chrome/app/chromium_strings.grd", "chrome/app/generated_resources.grd", "chrome/app/google_chrome_strings.grd", @@ -30,11 +33,14 @@ "chrome/browser/resources/chromeos/select_to_speak/strings/select_to_speak_strings.grd", "chrome/credential_provider/gaiacp/gaia_resources.grd", "chromeos/chromeos_strings.grd", + "components/autofill/android/java/strings/autofill_strings.grd", "components/components_chromium_strings.grd", "components/components_google_chrome_strings.grd", "components/components_strings.grd", + "components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd", "components/policy/resources/policy_templates.grd", "content/app/strings/content_strings.grd", + "content/public/android/java/strings/android_content_strings.grd", "device/bluetooth/bluetooth_strings.grd", "device/fido/fido_strings.grd", "extensions/strings/extensions_strings.grd", @@ -50,27 +56,11 @@ "remoting/resources/remoting_strings.grd", "third_party/libaddressinput/chromium/address_input_strings.grd", "ui/accessibility/extensions/strings/accessibility_extensions_strings.grd", + "ui/android/java/strings/android_ui_strings.grd", "ui/chromeos/ui_chromeos_strings.grd", "ui/strings/ui_strings.grd", ], }, - "android_grds": { - "languages": [ - "am", "ar", "bg", "ca", "cs", "da", "de", "el", "en-GB", "es", "es-419", - "fa", "fi", "fil", "fr", "hi", "hr", "hu", "id", "it", "iw", "ja", "ko", - "lt", "lv", "nl", "no", "pl", "pt-BR", "pt-PT", "ro", "ru", "sk", "sl", - "sr", "sv", "sw", "th", "tr", "uk", "vi", "zh-CN", "zh-TW", - ], - "files": [ - "android_webview/java/strings/android_webview_strings.grd", - "chrome/android/java/strings/android_chrome_strings.grd", - "chrome/android/webapk/strings/android_webapk_strings.grd", - "components/autofill/android/java/strings/autofill_strings.grd", - "components/embedder_support/android/java/strings/web_contents_delegate_android_strings.grd", - "content/public/android/java/strings/android_content_strings.grd", - "ui/android/java/strings/android_ui_strings.grd", - ], - }, # Grd files that contain <message> or <translations> elements, but that # shouldn't be translated as part of the normal translation process. Each # entry needs an explanation for why it shouldn't be translated.
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index bd1b9595..2cfe793a 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -10914,6 +10914,11 @@ </description> </action> +<action name="MobileFakeboxNTPTapped"> + <owner>stkhapugin@chromium.org</owner> + <description>User pressed the fakebox on NTP. iOS only.</description> +</action> + <action name="MobileFirstEditInOmnibox"> <obsolete>Deprecated as of 12/2015</obsolete> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> @@ -11454,6 +11459,13 @@ </description> </action> +<action name="MobileOmniboxFocused"> + <owner>stkhapugin@chromium.org</owner> + <description> + Omnibox focused (either directly or through one of the shortcuts). iOS only. + </description> +</action> + <action name="MobileOmniboxRefineSuggestion"> <obsolete> Deprecated 07/2017. Replaced by MobileOmniboxRefineSuggestion.Query and
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c8f5d1fc..ab7d76f7 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -20579,6 +20579,7 @@ <int value="2609" label="V8AttemptOverrideReadOnlyOnPrototypeSloppy"/> <int value="2610" label="V8AttemptOverrideReadOnlyOnPrototypeStrict"/> <int value="2611" label="HTMLCanvasElementLowLatency"/> + <int value="2612" label="V8OptimizedFunctionWithOneShotBytecode"/> </enum> <enum name="FeaturePolicyFeature"> @@ -42960,6 +42961,7 @@ <int value="50" label="NetworkingWithURLLoaderAnnotation"/> <int value="51" label="WorkerAnimation"/> <int value="52" label="MainThreadTaskQueueCleanup"/> + <int value="55" label="InternalTranslation"/> </enum> <enum name="RendererSchedulerTaskUseCase"> @@ -50502,19 +50504,6 @@ <int value="0" label="Used Omnibox"/> </enum> -<enum name="UserActivationFrameResultEnum"> - <int value="0" label="NullFailure"/> - <int value="1" label="NullSuccess"/> - <int value="2" label="SelfFailure"/> - <int value="3" label="SelfSuccess"/> - <int value="4" label="AncestorFailure"/> - <int value="5" label="AncestorSuccess"/> - <int value="6" label="DescendantFailure"/> - <int value="7" label="DescendantSuccess"/> - <int value="8" label="OtherFailure"/> - <int value="9" label="OtherSuccess"/> -</enum> - <enum name="UserCertContentDisposition"> <int value="0" label="No Content-Disposition"/> <int value="1" label="Content-Disposition"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 0adc2e5..468c6a7 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -114039,24 +114039,6 @@ </summary> </histogram> -<histogram name="UserActivation.AvailabilityCheck.FrameResult" - enum="UserActivationFrameResultEnum"> - <owner>mustaq@chromium.org</owner> - <summary> - Outcomes (success/failure) of transient user activation availability check - attempts for each type of caller frame (null, ancestor, descedant, other). - </summary> -</histogram> - -<histogram name="UserActivation.Consumption.FrameResult" - enum="UserActivationFrameResultEnum"> - <owner>mustaq@chromium.org</owner> - <summary> - Outcomes (success/failure) of user activation consumption attempts for each - type of caller frame (null, ancestor, descedant, other). - </summary> -</histogram> - <histogram name="UserCert.ContentDisposition" enum="UserCertContentDisposition"> <obsolete> Removed in M57.
diff --git a/tools/perf/benchmarks/startup_mobile.py b/tools/perf/benchmarks/startup_mobile.py index 46af7b8..d1a326b 100644 --- a/tools/perf/benchmarks/startup_mobile.py +++ b/tools/perf/benchmarks/startup_mobile.py
@@ -25,11 +25,27 @@ # should be disabled on non-Android to avoid failures at # benchmark_smoke_unittest.BenchmarkSmokeTest. # -# The recommended way to run this benchmark is: -# shell> CHROMIUM_OUTPUT_DIR=gn_android/Release tools/perf/run_benchmark \ -# -v startup.mobile --browser=android-chrome \ -# --output-dir=/tmp/avoid-polluting-chrome-tree - +# === Mini-HOWTO. +# +# 1. Configure for Release Official flavor to get the most representative +# results: +# shell> gn gen --args='use_goma=true target_os="android" target_cpu="arm" \ +# is_debug=false is_official_build=true' gn_android/ReleaseOfficial +# +# 2. Build Monochrome: +# shell> autoninja -C gn_android/ReleaseOfficial monochrome_apk +# +# 3. Invoke Telemetry: +# shell> CHROMIUM_OUTPUT_DIR=gn_android/ReleaseOfficial \ +# tools/perf/run_benchmark -v startup.mobile \ +# --browser=android-chrome \ +# --output-dir=/tmp/avoid-polluting-chrome-tree \ +# --also-run-disabled-tests +# +# The "--also-run-disabled-tests" is necessary because the benchmark is disabled +# in expectations.config to avoid failures on Android versions below M. This +# override is also used on internal bots. See: http://crbug.com/894744 and +# http://crbug.com/849907. class _MobileStartupSharedState(story_module.SharedState): def __init__(self, test, finder_options, story_set):
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py index cd11a46..a650da04 100644 --- a/tools/perf/benchmarks/system_health_smoke_test.py +++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -83,6 +83,7 @@ 'system_health.memory_desktop/load:news:cnn', 'system_health.memory_desktop/load:tools:stackoverflow', 'system_health.memory_desktop/load:games:alphabetty', + 'system_health.memory_desktop/browse:search:google_india', # crbug.com/698006 'system_health.memory_desktop/load:tools:drive',
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 539a1fd3..ddb8b30a 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -123,7 +123,7 @@ 'num_shards': 7 } ], - 'platform': 'android', + 'platform': 'android-chrome', 'dimension': { 'pool': 'chrome.tests.perf-fyi', 'os': 'Android', @@ -878,6 +878,8 @@ browser_name = 'reference' elif tester_config['platform'] == 'android': browser_name = 'android-chromium' + elif tester_config['platform'] == 'android-chrome': + browser_name = 'android-chrome' elif tester_config['platform'] == 'android-webview': browser_name = 'android-webview' elif (tester_config['platform'] == 'win'
diff --git a/tools/perf/core/perf_json_config_validator.py b/tools/perf/core/perf_json_config_validator.py index dfefede8..63803ab 100644 --- a/tools/perf/core/perf_json_config_validator.py +++ b/tools/perf/core/perf_json_config_validator.py
@@ -86,9 +86,10 @@ if not browser_options.webview_embedder_apk: raise ValueError('%s must set --webview-embedder-apk flag' % builder_name) elif 'Android' in builder_name or 'android' in builder_name: - if browser_options.browser != 'android-chromium': - raise ValueError("%s must use 'android-chromium' browser" % - builder_name) + if browser_options.browser not in ('android-chromium', 'android-chrome'): + raise ValueError( + "%s must use 'android-chromium' or 'android-chrome' browser" % + builder_name) elif builder_name in ('win-10-perf', 'Win 7 Nvidia GPU Perf'): if browser_options.browser != 'release_x64': raise ValueError("%s must use 'release_x64' browser type" %
diff --git a/tools/perf/page_sets/data/system_health_desktop.json b/tools/perf/page_sets/data/system_health_desktop.json index a39449d0..d4a8eea 100644 --- a/tools/perf/page_sets/data/system_health_desktop.json +++ b/tools/perf/page_sets/data/system_health_desktop.json
@@ -60,6 +60,9 @@ "browse:search:google_india": { "DEFAULT": "system_health_desktop_039.wprgo" }, + "browse:search:google_india:2018": { + "DEFAULT": "system_health_desktop_b576da862c.wprgo" + }, "browse:social:facebook_infinite_scroll": { "DEFAULT": "system_health_desktop_055.wprgo" },
diff --git a/tools/perf/page_sets/data/system_health_desktop_b576da862c.wprgo.sha1 b/tools/perf/page_sets/data/system_health_desktop_b576da862c.wprgo.sha1 new file mode 100644 index 0000000..5fe0d572 --- /dev/null +++ b/tools/perf/page_sets/data/system_health_desktop_b576da862c.wprgo.sha1
@@ -0,0 +1 @@ +b576da862c7f2960521eeb8a29b0b9c6639439a2 \ No newline at end of file
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py index 26c5eea..384687af 100644 --- a/tools/perf/page_sets/system_health/browsing_stories.py +++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -473,6 +473,45 @@ action_runner.ScrollPage() +class GoogleIndiaDesktopStory2018(_ArticleBrowsingStory): + """ + A typical google search story in India: + 1. Start at self.URL + 2. Scroll down the page. + 3. Refine the query & click search box + 4. Scroll down the page. + 5. Click the next page result + 6. Scroll the search result page. + + """ + NAME = 'browse:search:google_india:2018' + URL = 'https://www.google.co.in/search?q=%E0%A4%AB%E0%A5%82%E0%A4%B2&hl=hi' + _SEARCH_BOX_SELECTOR = 'input[name="q"]' + _SEARCH_BUTTON_SELECTOR = 'button[name="btnG"]' + _SEARCH_PAGE_2_SELECTOR = 'a[aria-label="Page 2"]' + SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY + TAGS = [story_tags.INTERNATIONAL, story_tags.YEAR_2018] + + def _DidLoadDocument(self, action_runner): + # Refine search query in the search box. + action_runner.WaitForElement(self._SEARCH_BOX_SELECTOR) + action_runner.ExecuteJavaScript( + 'document.querySelector({{ selector }}).select()', + selector=self._SEARCH_BOX_SELECTOR) + action_runner.Wait(1) + action_runner.EnterText(u'वितरण', character_delay_ms=250) + action_runner.Wait(2) + action_runner.ClickElement(selector=self._SEARCH_BUTTON_SELECTOR) + + # Scroll down & click next search result page. + action_runner.Wait(2) + action_runner.ScrollPageToElement(selector=self._SEARCH_PAGE_2_SELECTOR) + action_runner.Wait(2) + action_runner.ClickElement(selector=self._SEARCH_PAGE_2_SELECTOR) + action_runner.Wait(2) + action_runner.ScrollPage() + + ############################################################################## # Media browsing stories. ##############################################################################
diff --git a/tools/perf/test_results/analysis.py b/tools/perf/test_results/analysis.py index 52bf722..6f319d6 100644 --- a/tools/perf/test_results/analysis.py +++ b/tools/perf/test_results/analysis.py
@@ -79,7 +79,7 @@ days_ago = time_ago.dt.total_seconds() / SECONDS_IN_A_DAY df['weight'] = numpy.power(0.5, days_ago / half_life) df['flakiness'] *= df['weight'] - latest_build = df['build_number'].max() + latest_build = df['build_number'].iloc[0] grouped = df.groupby(['builder', 'test_suite', 'test_case']) df = grouped['flakiness'].sum().to_frame()
diff --git a/tools/ubsan/vptr_blacklist.txt b/tools/ubsan/vptr_blacklist.txt index 3e24d8a..39da577 100644 --- a/tools/ubsan/vptr_blacklist.txt +++ b/tools/ubsan/vptr_blacklist.txt
@@ -134,8 +134,3 @@ # "vptr". See crbug.com/609786. src:*/third_party/libc\+\+abi/trunk/src/private_typeinfo.cpp - -############################################################################# -# invalid downcasts for IPC messages -# https://crbug.com/520760 -src:*nacl_message_scanner.cc
diff --git a/ui/android/java/strings/android_ui_strings.grd b/ui/android/java/strings/android_ui_strings.grd index 910b1be..9bf37d6 100644 --- a/ui/android/java/strings/android_ui_strings.grd +++ b/ui/android/java/strings/android_ui_strings.grd
@@ -50,6 +50,7 @@ <file lang="am" path="translations/android_ui_strings_am.xtb" /> <file lang="ar" path="translations/android_ui_strings_ar.xtb" /> <file lang="bg" path="translations/android_ui_strings_bg.xtb" /> + <file lang="bn" path="translations/android_ui_strings_bn.xtb" /> <file lang="ca" path="translations/android_ui_strings_ca.xtb" /> <file lang="cs" path="translations/android_ui_strings_cs.xtb" /> <file lang="da" path="translations/android_ui_strings_da.xtb" /> @@ -58,10 +59,12 @@ <file lang="en-GB" path="translations/android_ui_strings_en-GB.xtb" /> <file lang="es" path="translations/android_ui_strings_es.xtb" /> <file lang="es-419" path="translations/android_ui_strings_es-419.xtb" /> + <file lang="et" path="translations/android_ui_strings_et.xtb" /> <file lang="fa" path="translations/android_ui_strings_fa.xtb" /> <file lang="fi" path="translations/android_ui_strings_fi.xtb" /> <file lang="fil" path="translations/android_ui_strings_fil.xtb" /> <file lang="fr" path="translations/android_ui_strings_fr.xtb" /> + <file lang="gu" path="translations/android_ui_strings_gu.xtb" /> <file lang="hi" path="translations/android_ui_strings_hi.xtb" /> <file lang="hr" path="translations/android_ui_strings_hr.xtb" /> <file lang="hu" path="translations/android_ui_strings_hu.xtb" /> @@ -70,8 +73,12 @@ <file lang="iw" path="translations/android_ui_strings_iw.xtb" /> <file lang="ja" path="translations/android_ui_strings_ja.xtb" /> <file lang="ko" path="translations/android_ui_strings_ko.xtb" /> + <file lang="kn" path="translations/android_ui_strings_kn.xtb" /> <file lang="lt" path="translations/android_ui_strings_lt.xtb" /> <file lang="lv" path="translations/android_ui_strings_lv.xtb" /> + <file lang="ml" path="translations/android_ui_strings_ml.xtb" /> + <file lang="mr" path="translations/android_ui_strings_mr.xtb" /> + <file lang="ms" path="translations/android_ui_strings_ms.xtb" /> <file lang="nl" path="translations/android_ui_strings_nl.xtb" /> <file lang="no" path="translations/android_ui_strings_no.xtb" /> <file lang="pl" path="translations/android_ui_strings_pl.xtb" /> @@ -84,6 +91,8 @@ <file lang="sr" path="translations/android_ui_strings_sr.xtb" /> <file lang="sv" path="translations/android_ui_strings_sv.xtb" /> <file lang="sw" path="translations/android_ui_strings_sw.xtb" /> + <file lang="ta" path="translations/android_ui_strings_ta.xtb" /> + <file lang="te" path="translations/android_ui_strings_te.xtb" /> <file lang="th" path="translations/android_ui_strings_th.xtb" /> <file lang="tr" path="translations/android_ui_strings_tr.xtb" /> <file lang="uk" path="translations/android_ui_strings_uk.xtb" />
diff --git a/ui/android/java/strings/translations/android_ui_strings_bn.xtb b/ui/android/java/strings/translations/android_ui_strings_bn.xtb new file mode 100644 index 0000000..8342dc02 --- /dev/null +++ b/ui/android/java/strings/translations/android_ui_strings_bn.xtb
@@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="bn"> +<translation id="6315516427814392808">Unable to complete previous operation due to low memory</translation> +<translation id="6555463879959038093">Failed to copy to the clipboard</translation> +<translation id="793640675459356075">Failed to open selected file</translation> +</translationbundle> \ No newline at end of file
diff --git a/ui/android/java/strings/translations/android_ui_strings_et.xtb b/ui/android/java/strings/translations/android_ui_strings_et.xtb new file mode 100644 index 0000000..c8bb288f --- /dev/null +++ b/ui/android/java/strings/translations/android_ui_strings_et.xtb
@@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="et"> +<translation id="6315516427814392808">Unable to complete previous operation due to low memory</translation> +<translation id="6555463879959038093">Failed to copy to the clipboard</translation> +<translation id="793640675459356075">Failed to open selected file</translation> +</translationbundle> \ No newline at end of file
diff --git a/ui/android/java/strings/translations/android_ui_strings_gu.xtb b/ui/android/java/strings/translations/android_ui_strings_gu.xtb new file mode 100644 index 0000000..8293950 --- /dev/null +++ b/ui/android/java/strings/translations/android_ui_strings_gu.xtb
@@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="gu"> +<translation id="6315516427814392808">Unable to complete previous operation due to low memory</translation> +<translation id="6555463879959038093">Failed to copy to the clipboard</translation> +<translation id="793640675459356075">Failed to open selected file</translation> +</translationbundle> \ No newline at end of file
diff --git a/ui/android/java/strings/translations/android_ui_strings_kn.xtb b/ui/android/java/strings/translations/android_ui_strings_kn.xtb new file mode 100644 index 0000000..c346a1d --- /dev/null +++ b/ui/android/java/strings/translations/android_ui_strings_kn.xtb
@@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="kn"> +<translation id="6315516427814392808">Unable to complete previous operation due to low memory</translation> +<translation id="6555463879959038093">Failed to copy to the clipboard</translation> +<translation id="793640675459356075">Failed to open selected file</translation> +</translationbundle> \ No newline at end of file
diff --git a/ui/android/java/strings/translations/android_ui_strings_ml.xtb b/ui/android/java/strings/translations/android_ui_strings_ml.xtb new file mode 100644 index 0000000..c0a4d4a --- /dev/null +++ b/ui/android/java/strings/translations/android_ui_strings_ml.xtb
@@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ml"> +<translation id="6315516427814392808">Unable to complete previous operation due to low memory</translation> +<translation id="6555463879959038093">Failed to copy to the clipboard</translation> +<translation id="793640675459356075">Failed to open selected file</translation> +</translationbundle> \ No newline at end of file
diff --git a/ui/android/java/strings/translations/android_ui_strings_mr.xtb b/ui/android/java/strings/translations/android_ui_strings_mr.xtb new file mode 100644 index 0000000..93e050c --- /dev/null +++ b/ui/android/java/strings/translations/android_ui_strings_mr.xtb
@@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="mr"> +<translation id="6315516427814392808">Unable to complete previous operation due to low memory</translation> +<translation id="6555463879959038093">Failed to copy to the clipboard</translation> +<translation id="793640675459356075">Failed to open selected file</translation> +</translationbundle> \ No newline at end of file
diff --git a/ui/android/java/strings/translations/android_ui_strings_ms.xtb b/ui/android/java/strings/translations/android_ui_strings_ms.xtb new file mode 100644 index 0000000..dd201d3 --- /dev/null +++ b/ui/android/java/strings/translations/android_ui_strings_ms.xtb
@@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ms"> +<translation id="6315516427814392808">Unable to complete previous operation due to low memory</translation> +<translation id="6555463879959038093">Failed to copy to the clipboard</translation> +<translation id="793640675459356075">Failed to open selected file</translation> +</translationbundle> \ No newline at end of file
diff --git a/ui/android/java/strings/translations/android_ui_strings_ta.xtb b/ui/android/java/strings/translations/android_ui_strings_ta.xtb new file mode 100644 index 0000000..d6e31f2f --- /dev/null +++ b/ui/android/java/strings/translations/android_ui_strings_ta.xtb
@@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="ta"> +<translation id="6315516427814392808">Unable to complete previous operation due to low memory</translation> +<translation id="6555463879959038093">Failed to copy to the clipboard</translation> +<translation id="793640675459356075">Failed to open selected file</translation> +</translationbundle> \ No newline at end of file
diff --git a/ui/android/java/strings/translations/android_ui_strings_te.xtb b/ui/android/java/strings/translations/android_ui_strings_te.xtb new file mode 100644 index 0000000..e914101 --- /dev/null +++ b/ui/android/java/strings/translations/android_ui_strings_te.xtb
@@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<!DOCTYPE translationbundle> +<translationbundle lang="te"> +<translation id="6315516427814392808">Unable to complete previous operation due to low memory</translation> +<translation id="6555463879959038093">Failed to copy to the clipboard</translation> +<translation id="793640675459356075">Failed to open selected file</translation> +</translationbundle> \ No newline at end of file
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js index a1eae49b..c78e9c8f 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js +++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -500,17 +500,6 @@ }; /** - * Default sorting for DirectoryItem sub-dirrectories. - * @param {!Array<!Entry>} entries Entries to be sorted. - * @returns {!Array<!Entry>} - */ -DirectoryItem.prototype.sortEntries = function(entries) { - entries.sort(util.compareName); - const filter = this.fileFilter_.filter.bind(this.fileFilter_); - return entries.filter(filter); -}; - -/** * Retrieves the latest subdirectories and update them on the tree. * @param {boolean} recursive True if the update is recursively. * @param {function()=} opt_successCallback Callback called on success. @@ -518,34 +507,40 @@ */ DirectoryItem.prototype.updateSubDirectories = function( recursive, opt_successCallback, opt_errorCallback) { - if (!this.entry || this.entry.createReader === undefined) { - opt_errorCallback && opt_errorCallback(); + if (!this.entry || util.isFakeEntry(this.entry)) { + if (opt_errorCallback) + opt_errorCallback(); return; } - const onSuccess = (entries) => { + var sortEntries = function(fileFilter, entries) { + entries.sort(util.compareName); + return entries.filter(fileFilter.filter.bind(fileFilter)); + }; + + var onSuccess = function(entries) { this.entries_ = entries; this.updateSubElementsFromList(recursive); opt_successCallback && opt_successCallback(); - }; + }.bind(this); - const reader = this.entry.createReader(); - const entries = []; - const readEntry = () => { - reader.readEntries((results) => { + var reader = this.entry.createReader(); + var entries = []; + var readEntry = function() { + reader.readEntries(function(results) { if (!results.length) { - onSuccess(this.sortEntries(entries)); + onSuccess(sortEntries(this.fileFilter_, entries)); return; } - for (let i = 0; i < results.length; i++) { - const entry = results[i]; + for (var i = 0; i < results.length; i++) { + var entry = results[i]; if (entry.isDirectory) entries.push(entry); } readEntry(); - }); - }; + }.bind(this)); + }.bind(this); readEntry(); }; @@ -766,42 +761,26 @@ */ EntryListItem.prototype.updateSubDirectories = function( recursive, opt_successCallback, opt_errorCallback) { - if (!this.entry || this.entry.createReader === undefined) { + if (!this.entry) { opt_errorCallback && opt_errorCallback(); return; } this.entries_ = []; - - const onSuccess = (entries) => { - this.entries_ = entries; - this.updateSubElementsFromList(recursive); - opt_successCallback && opt_successCallback(); - }; - - const reader = this.entry.createReader(); - const entries = []; - const readEntry = () => { - reader.readEntries((results) => { - if (!results.length) { - onSuccess(this.sortEntries(entries)); - return; + if (this.entry && this.entry.children) { + for (let childEntry of this.entry.children) { + if (childEntry instanceof VolumeEntry) { + // For VolumeEntry we want to display its root. + this.entries_.push(childEntry.rootEntry); + } else { + this.entries_.push(childEntry); } - - for (let i = 0; i < results.length; i++) { - const entry = results[i]; - if (entry.isDirectory) { - // For VolumeEntry we want to display its root. - if (entry instanceof VolumeEntry) { - entries.push(entry.rootEntry); - } else { - entries.push(entry); - } - } - } - readEntry(); - }); - }; - readEntry(); + } + } + if (this.entries_.length > 0) { + this.expanded = true; + } + this.updateSubElementsFromList(recursive); + opt_successCallback && opt_successCallback(); }; ////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc index 49275ab..bca15e6 100644 --- a/ui/message_center/views/notification_view_md.cc +++ b/ui/message_center/views/notification_view_md.cc
@@ -36,7 +36,6 @@ #include "ui/strings/grit/ui_strings.h" #include "ui/views/animation/flood_fill_ink_drop_ripple.h" #include "ui/views/animation/ink_drop_highlight.h" -#include "ui/views/animation/ink_drop_mask.h" #include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/controls/button/image_button.h" @@ -1242,8 +1241,6 @@ action_buttons_row_->SetBackground(views::CreateBackgroundFromPainter( std::make_unique<NotificationBackgroundPainter>( 0, bottom_radius, kActionsRowBackgroundColor))); - top_radius_ = top_radius; - bottom_radius_ = bottom_radius; } NotificationControlButtonsView* NotificationViewMD::GetControlButtonsView() @@ -1345,16 +1342,6 @@ GetInkDropBaseColor(), ink_drop_visible_opacity()); } -std::unique_ptr<views::InkDropMask> NotificationViewMD::CreateInkDropMask() - const { - gfx::Path path; - SkScalar radii[8] = {top_radius_, top_radius_, top_radius_, - top_radius_, bottom_radius_, bottom_radius_, - bottom_radius_, bottom_radius_}; - path.addRoundRect(gfx::RectToSkRect(gfx::Rect(size())), radii); - return std::make_unique<views::PathInkDropMask>(size(), path); -} - SkColor NotificationViewMD::GetInkDropBaseColor() const { // Background of inline settings area. return SkColorSetRGB(0xEE, 0xEE, 0xEE);
diff --git a/ui/message_center/views/notification_view_md.h b/ui/message_center/views/notification_view_md.h index 709c28e..d897066 100644 --- a/ui/message_center/views/notification_view_md.h +++ b/ui/message_center/views/notification_view_md.h
@@ -184,7 +184,6 @@ void AddInkDropLayer(ui::Layer* ink_drop_layer) override; void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override; std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override; - std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; SkColor GetInkDropBaseColor() const override; // Overridden from MessageView: @@ -270,9 +269,6 @@ // Describes whether the view should display a hand pointer or not. bool clickable_; - int top_radius_ = 0; - int bottom_radius_ = 0; - // Container views directly attached to this view. NotificationHeaderView* header_row_ = nullptr; views::View* content_row_ = nullptr;
diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc index ad8f673..ea7fbcb 100644 --- a/ui/views/controls/menu/menu_controller_unittest.cc +++ b/ui/views/controls/menu/menu_controller_unittest.cc
@@ -45,6 +45,10 @@ #include "ui/gfx/x/x11.h" #endif +#if defined(OS_CHROMEOS) +#include "ui/base/ui_base_features.h" +#endif + namespace views { namespace test { @@ -1704,9 +1708,15 @@ EXPECT_EQ(MenuController::EXIT_ALL, controller->exit_type()); } -// Tests that if a menu is ran without a widget, that MenuPreTargetHandler does -// not cause a crash. +// Tests that menus without parent widgets do not crash in MenuPreTargetHandler. +// This is generally true, except on Chrome OS running with the window service. +// In that case, a DCHECK fires to ensure menus can consume parents' key events. TEST_F(MenuControllerTest, RunWithoutWidgetDoesntCrash) { +#if defined(OS_CHROMEOS) + if (features::IsUsingWindowService()) + return; +#endif // OS_CHROMEOS + ExitMenuRun(); MenuController* controller = menu_controller(); controller->Run(nullptr, nullptr, menu_item(), gfx::Rect(),
diff --git a/ui/views/controls/menu/menu_pre_target_handler_aura.cc b/ui/views/controls/menu/menu_pre_target_handler_aura.cc index 6378f755..459347b 100644 --- a/ui/views/controls/menu/menu_pre_target_handler_aura.cc +++ b/ui/views/controls/menu/menu_pre_target_handler_aura.cc
@@ -29,12 +29,12 @@ wm::GetActivationClient(root_)->AddObserver(this); root_->AddObserver(this); } else { - // TODO(mukai): check if this code path can run in ChromeOS and find the - // solution for SingleProcessMash. - if (features::IsUsingWindowService()) { - LOG(WARNING) << "MenuPreTargetHandlerAura is created without owner " - << "widget. This may not work well in SingleProcessMash."; - } + // This should only happen in cases like when context menus are shown for + // Windows OS system tray items and there is no parent window. This should + // not be hit on Chrome OS, where Window Service clients need to install a + // pre-target handler on the aura::Env associated with their app window. + DCHECK(!features::IsUsingWindowService()) + << "MenuPreTargetHandlerAura may not work correctly without an owner."; aura_env_ = aura::Env::GetInstance(); } aura_env_->AddPreTargetHandler(this, ui::EventTarget::Priority::kSystem);